慢查询

  • Redis的慢查询日志功能用于记录执行时间超过给定时长的命令请求,用户可以通过这个功能产生的日志来监视和优化查询速度
  • slowlog-max-len

    • 指定服务器最多保存多少条慢查询日志
    • 先进先出队列(理解生命周期)
    • 固定长度
    • 保存在内存中(定期持久化慢查询)
  • slowlog-log-slower-than

    • 指定执行时间超过多少微秒(1秒等于1000 000微秒)的命令请求会被记录到日志上
    • 慢查询阈值(单位:微秒)
    • slowlog-log-slower-than=0,记录所以命令
    • slowlog-log-slower-than<0,不记录任何命令
  • 默认值

    • config get slowlog-max-len = 128,不要设置过小,通常设置1000左右
    • config get slowlog-log-slower-than = 10000,不要设置过大,默认10ms,通常设置1ms
  • 配置方法

    • 修改配置文件重启
    • 动态配置

      • config set slowlog-max-len = 128
      • config set slowlog-log-slower-than = 10000
  • 慢查询命令

    • slowlog get [n] : 获取慢查询队列
    • slowlog len : 获取慢查询队列长度
    • slowlog reset : 清空慢查询队列队列

pipeline

  • 什么是流水线?

     | 命令               | 时间          | 数据量       |
     | -------------------- | --------------- | --------------- |
     | N个命令操作     | n次网络+n命令次 | 1次网络+n命令次 |
     | 1次pipeline(n个命令) | 1条命令      | n条命令      |  
     - redis的命令时间是微秒级别
     - 注意每次pipeline携带数据量,即每次条数要控制(网络)       
     - pipeline每次只能作用在一个redis节点上
    
  • php实现pipeline
<?php
    $redis = new \Redis();
    $redis->connect('127.0.0.1', 6379);
    $pipe = $redis->multi($redis::PIPELINE);
    for ($i = 0; $i < 10000; $i++) {
        $pipe->set("key::$i", str_pad($i, 4, '0', 0));
    }
    $replies = $pipe->exec();

发布订阅

  • 角色

    • 发布者(publisher) redis-cli
    • 订阅者(subscriber) redis-cli
    • 频道(channel)
  • 模型

1.png

  • API

    • publish 发布

      • publish channel message
    • subscribe 订阅

      • subscribe [channel] #一个或者多个
    • unsubscribe 取消订阅

      • unsubscribe [channel] #一个或者多个
    • 其他

      • psubscribe [pattern ...] #订阅模式
  • 发布订阅与消息队列

    • LPUSH + RPOP
    • 模型

2.png

Bitmap

  • 位图模型

3.png

  • 注意事项

    • 类型string,最大为512MB
    • setbit的偏移量有可能消耗大
  • 相关命令

    • setbit key offset value #给位图指定索引设置值

      • setbit key 1 1
      • setbit key 5 1
      • setbit key 11 1
      • setbit key 15 1
      • setbit key 19 1
      • setbit key 50 1

4.png

 
- setbit key offset #获取位图指定索引值
- bitcount key [start end] #获取位图指定范围(start到end ,单位为字节,如果不指定就是获取全部)位值为1的个数
- bitop op destkey key [key...] 做多个Bitmap的and(交集)、 or(并集)、 not(非)、xor(异或)操作并将结果保存在destkey中
- bitpos key targetBit [start] [end] 计算位图指定范围(start到end ,单位为字节,如果不指定就是获取全部)第一个偏移量对应的值等 于targetBit的位置
  • 独立用户系统

    • 使用set和bitmap
    • 1亿用户,5千万独立访问 占用内存量 && 10万独立访问 占用内存量(由以对比得知,应该根据场景不同使用不一样的模式去存储数据,以便于达到更优)
数据类型每个userid占用空间需要存储的用户量全部内存量
set32位(假设userid用的是整型,实际很多网站用的是长整型)50,000,00032位* 50,000,000= 200MB
Bitmap1位100,000,0001位*100,000,000= 12.5ME
一天一个月一年
set200M6G72G
Bitmap12.5M375M4.5G
数据类型每个userid占用空间需要存储的用户量全部内存量
set32位(假设userid用的是整型,实际很多网站用的是长整型)1,000,00032位* 1,000,000= 4MB
Bitmap1位10000,0001位* 100.000,000 = 12.5MB
一天一个月一年
set4M120M1.5G
Bitmap12.5M375M4.5G

HyperLoglog

  • 注意事项

    • 不是新的数据结构
    • 基于HyperLogLog算法:极小空间完成独立数量统计
    • 本质还是字符串
  • 相关命令

    • pfadd key element [element ...] :向hyperloglog添加元素
    • pfadd 2021_12_14:ids "uid-1" "uid-2" "uid-3" "uid-4"
    • pfcount 2021_12_14:ids
    • pfadd 2021_12_14:ids "uid-1" "uid-2" "uid-3" "uid-90"
    • pfcount key [key ...]:计算hyperloglog的独立总数
    • pfmerge destkey sourcekey [sourcekey ...] :合并多个hyperloglog
  • 内存消耗(模拟插入100万数据)
<?php

    set_time_limit(0);
    $redis = new \Redis();
    $redis->connect('127.0.0.1', 6379);
    $pipe = $redis->multi($redis::PIPELINE);
    $key = '2021_12_14:unique:ids';
    $values = [];
    for ($i = 1; $i <= 1000000; $i++) {
        $values[]= "uuid-$i";
        if ($i % 1000 == 0) {
            $pipe->pfAdd($key, $values);
            $replies = $pipe->exec();
            $values = [];
        }
    }
    echo '<pre>';
    print_r($redis->pfCount($key));//999978
    die;
    • 插入100万不重复的数据,最后得到999978个数据,有一定的错误率
    • 是否能容忍错误率:0.81%
    • 是否需要单条数据
时间1天1个月1年
内存消耗15KB450KB5MB

GEO(redis3.2+)

  • GEO是什么?

    • GEO(地理信息定位) :存储经纬度,计算两地距离,范围计算等
    • 注意事项

      • geokey是zset类型
  • 相关命令(以5个城市经纬度为例来介绍)

    • geo key longitude latitude member [longitude latitude member...] #增加地理位置信息

      • geoadd cities:locations 116.28 39.55 beijing
      • geoadd cities:locations 117.12 39.08 tianjin
      • geoadd cities:locations 114.29 38.02 shijiazhuang
      • geoadd cities:locations 118.01 39.38 tangshan
      • geoadd cities:locations 115.29 38.51 baoding
    • geopos key member [member ...]#获取地理位置信息

      • geopos cities:locations tianjin
    • geodist key member1 member2 [unit] #获取两个地理位置的距离 #unit: m(米)、km(千米)、mi(英里)、 ft(尺)

      • geodist cities:locations tianjin beijing km //天津到北京的距离为89.2061km
    • 其他命令(georadius)
       georadius key longitude latitude radiusm|kmftlmi [withcoord]   [withdist] [withhash] [COUNT count] [asc|desc]   [store key][storedist key]
  
       georadiusbymember key member  radiusm|km|ftlmi [withcoord]   [withdist] [withhash] COUNT count] [asc|desc]   [store key][storedist key] #获取指定位置范围内的地理位置信息集合
       
       withcoord :返回结果中包含经纬度。
       withdist :返回结果中包含距离中心节点位置。
       withhash :返回结果中包含geohash
       COUNT count :指定返回结果的数量。
       asc|desc :返回结果按照距离中心节点的距离做升序或者降序。
       store key :将返回结果的地理位置信息保存到指定键。
       storedist key :将返回结果距离中心节点的距离保存到指定键
城市经度纬度简称
北京116.2839.55beijing
天津117.1239.08tianjin
石家庄114.2938.02shijiazhuang
唐山118.0139.38tangshan
保定115.2938.51baoding




Last modification:September 21, 2022
如果觉得我的文章对你有用,请随意赞赏