Redis附加功能

慢查询分析

系统在命令执行前后计算每条命令的执行时间,当超过预设阈值时,就将这条命令的相关信息(发生时间、耗时、命令的详细信息等)记录下来

慢查询只统计执行时间,不代表客户端有没有超时问题

参数配置

可以通过以下参数对预设阈值,满查询记录进行配置
设置阈值,单位为微妙,默认是10000

slowlog-log-slower-than

  • 如果其值等于0,会记录所有的命令,小于0则对于任何命令都不做记录

设置最多存储多少条记录

slowlog-max-len

  • Redis使用一个列表来存储慢查询日志,该值即为列表的最大长度,当日志数量达到设置的最大值时,插入新的将移除最早的那一条

配置方式:

  1. 使用config set命令做动态修改,之后可以通过执行config rewrite将配置持久化到本地配置文件
  2. 直接修改配置文件

日志获取

慢查询日志存放在Redis列表中,但Redis并没有将这个键暴露出来,而是通过命令进行查看
获取慢查询日志

slowlog get [n]

  • 慢查询日志有四个属性值组成,分别是:id,发生时间戳,命令耗时,执行命令和参数

获取慢查询日志列表当前的长度

slowlog len

慢查询日志重置

slowlog reset

Redis Shell

Redis-cli

参数:

  • -h:ip地址
  • -p:端口号
  • -r:repeat,代表命令执行多次

    redis-cli -r 3 ping

  • -i:代表每隔几秒执行一次命令,必须与-r一起使用
  • -x:从标准输入读取数据作为redis-cli的最后一个参数,下面输入相当于进入客户端执行了set hello world

    echo “world” | redis-cli -x set hello

  • -c:连接redis Cluster节点使用
  • -a:如果Redis配置了密码,可以用-a(auth),就不需要手动输入auth命令
  • –scan和–pattern:用于扫描指定模式的键,相当于scan命令
  • –slave:把当前客户端模拟成当前redis节点的从节点,可以用来获取当前Redis节点的更新操作
  • –rdb:请求redis实例生成RDB持久化文件,保存在本地
  • –pipe:将命令封装成redis通信协议定义的数据格式,批量发送给Redis执行
  • –bigkeys:对redis的键进行采样,从中找到内存占用比较大的键值
  • –eval:执行指定的Lua脚本
  • –latency:用于网络检测,有三个选项:
    (1) –latency:测试客户端到目标Redis的网络延迟
    (2) –latency-history:以分时段的形式了解延迟信息
    (3) –latency-dist:以统计图表的形式从控制台输出延迟统计信息
  • –state:实时获取Redis中的重要信息
  • –raw和–no-raw:返回格式化的结果或者原始结果(针对中文,–raw显示中文,-no-raw会显示成字符编码

redis-server

参数:

  • –test-memory:测试当前操作系统是否能够稳定的分配指定内存给redis
    测试是否能够提供1G内存:

    redis-server –test-memory 1024

redis-benchmark

用于对Redis做基准性能测试

参数:

  • -c:clients,代表客户端并发数量,默认50
  • -n:代表客户端请求总量,默认100000
  • -q:仅仅显示redis-benchmark的requests per second信息
  • -r:向redis中插入更多的键。-r选项会在键名上加一个12位的后缀,-r 10000表示只对后四位做随机处理
  • -P:代表每个请求pipeline的数据量
  • -k<boolean>:代表客户端是否使用keepalive,1为使用,0为不使用,默认为1
  • -t:对指定命令做基准测试
  • –csv:将结果按照csv格式输出,便于后续处理

Pipeline

Redis客户端发送一条命令分为一下四个过程:
1)发送命令
2)命令排队
3)命令执行
4)返回结果

其中1+4称为RTT(Round Trip Time),即往返时间

Pipeline(流水线)将一组Redis命令进行组装,通过一次RTT传输Redis,再将这组执行结果按顺序返回给客户端,从而减少了命令整体的执行时间

redis-cli --pipe可以用于启动Pipeline机制,实际应用中更倾向于在客户端使用Pipeline(如Java的Redis客户端Jedis)

原生批量命令与Pipeline对比

  1. 原生批量命令是原子的,Pipeline是非原子的
  2. 原生批量命令是一个命令对应多个key,Pipeline支持多命令
  3. 原生批量命令是Redis服务端支持实现的,而Pipeline需要服务端和客户端的共同实现

事务

Redis提供了简单的事务功能,将一组需要执行的命令放到multiexec之间,multi代表事务开始,exec代表事务结束,只有执行了exec后中间的命令才会被执行
如果要停止事务的执行,可以使用discard命令代替exec

事务中出现错误的情况:

  1. 命令错误:例如语法错误,会导致整个事务无法执行
  2. 运行时错误:例如错将sadd写成zadd,这时候执行exec时正确的命令会被执行,Redis不支持回滚功能

在事务之前如果需要确保事务中的key没有被其他客户端修改才能执行,否则不执行,可以通过在multi之前先执行watch命令来实现

Bitmaps

计算机使用二进制位(位)作为信息的基础单位,1个字节等于8位,Redis提供Bitmaps可以实现对位的操作。Bitmaps本身不是一种数据结构,实际上它是字符串,但可以对字符串的位进行操作
可以把Bitmaps看成一个以位为单位的数组,数组的每个单元只能存储0和1,数组的下标在Bitmaps中叫做偏移量

命令

  1. 设置值

    setbit key offset value 设置键的第offset个位的值

  2. 获取值

    getbit key offset

  3. 获取Bitmaps指定范围值为1的个数,其中start和end代表起始和结束字节数(一个字节占8位,例如start=2表示从下标16开始算)

    bitcount [start][end]

  4. Bitmaps间的运算

    bitop op destkey key[key …]

op可以是and(交集),or(并集),not(非),xor(异或)操作, 操作结果保存在deskey中

  1. 计算Bitmaps中第一个值为targetBit的偏移量

    bitpos key targetBit [start][end]

应用场景

当用户量很大时,用来记录当天访问人数,可以大幅度减少内存

HyperLogLog

HyperLogLog实际类型为字符串类型,它是一种基数算法,可以利用极小的内存空间独立完成总数的统计

添加

pfadd key element [element …]

计算独立用户数

pfcount key [key …]

合并:求出多个HyperLogLog的并集并赋值给deskey

pfmerge destkey sourcekey [sourcekey …]

HyperLogLog内存占用量非常小,但是存在错误率

发布订阅

Redis提供基于“发布/订阅”模式的消息机制,此种模式下,发布者通过客户端向指定的频道(channel)发布消息,订阅该频道的客户端都可以接收到该消息

命令

发布订阅

publish channel message

订阅消息

subscribe channel [channel …]

取消订阅

unsubscribe [channel …]

按照模式订阅和取消订阅

psubscribe pattern [pattern]
punsubscribe pattern [pattern]

  • 客户端在执行订阅命令之后进入了订阅状态,只能接收subscribe、psubscribe、unsubscribe、punsubscribe四个命令
  • 新开启的客户端,无法接受该频道之前的消息,因为Redis不会对发布的消息进行持久化

查询订阅

  1. 查看活跃的频道(当前频道至少有一个订阅者)

    pubsub channels [pattern]

  2. 查看频道订阅数

    pubsub numsub [channel …]

  3. 查看模式订阅数

    pubsub numpat

GEO

GEO是Redis提供的地理信息定位功能

增加地理位置信息

geoadd key longitude latitude member [longitude latitude member]

longitude,latitude,member分别表示地理位置的经度,纬度,成员名

获取地理位置信息

geopos key member [member]

获取两个地理位置的距离

geodist key member1,member2 [unit]

unit代表返回的结果的单位,包括一下四种:

  • m :meters 米
  • km
  • mi:miles 代表英里
  • ft:feet 代表尺

获取指定位置范围内的地理信息位置集合

georadius key longitude latitude rediusm m|km|ft|mi [withcoord] [withdist] [withhash] [COUNT count] [asc|desc] [store key] [storedist key]
georadiusbymember key member radiusm m|km|ft|im [withcoord] [withdist] [withhash] [COUNT count] [asc|desc] [store key] [storedist key]

georadius,georadiusbymember两个命令都是以一个地理位置为中心算出指定半径内的其他地理信息位置,但后者只需要给出成员,前者给出经纬度
参数说明:

  • rediusm:半径,指定单位
  • withcoord:返回结果中包含经纬度
  • withdist:返回结果中包含离中心节点位置的距离
  • withhash:返回结果中包含withhash
  • Count count:指定返回结果的数量
  • asc|desc:返回结果按照离中心节点的距离做升序或者降序
  • store key:将返回结果的地理位置信息保存到指定键
  • storedist key:将返回结果离中心节点的距离保存到指定键

获取geohash

geohash key member [member…]

Redis使用geohash将二维经纬度转化为一维字符串
geohash具有一下特点:

  • GEO的数据类型为zset,Redis将所有地理位置的geohash存放在zset中
  • 字符串越长,表示位置更精确
  • 两个字符串越相似,它们之间的距离就越接近
  • geohash编码和经纬度是可以相互转换的

删除地理位置

GEO没有提供删除成员的命令,但是可以通过GEO底层实现是zset,使用zrem命令进行删除

zrem key member