一、慢查询分析
慢查询两个参数
- slowlog-log-slower-than 阀值,单位是微秒(1秒=1000毫秒=1000000微秒),默认值是10000
slowlog-log-slower-than=0会记录所有的命令
slowlog-log-slowerthan<0对于任何命令都不会进行记录 - 实际上Redis使用了一个列表来存储慢查询日志,slowlog-max-len就是列表的最大长度
- 每个慢查询日志有4个属性组成, 分别是慢查询日志的标识id、 发生时间戳、 命令耗时、 执行命令和参数
# 获取慢查询日志,
slowlog get [n] # n可以指定条数
# 获取慢查询日志当前的列表长度
slowlog len
# 慢查询日志列表清空
slowlog reset
最佳实践
-
slowlog-max-len配置建议: 线上建议调大慢查询列表, 记录慢查询时Redis会对长命令做截断操作, 并不会占用大量内存。 增大慢查询列表可以减缓慢查询被剔除的可能, 例如线上可设置为1000以上。
-
slowlog-log-slower-than配置建议: 默认值超过10毫秒判定为慢查询,需要根据Redis并发量调整该值。 由于Redis采用单线程响应命令, 对于高流量的场景, 如果命令执行时间在1毫秒以上, 那么Redis最多可支撑OPS不到1000。 因此对于高OPS场景的Redis建议设置为1毫秒。
-
慢查询只记录命令执行时间, 并不包括命令排队和网络传输时间。 因此客户端执行命令的时间会大于命令实际执行时间。
-
定期执行slow get命令将慢查询日志持久化到其他存储中(例如MySQL) , 然后可以制作可视化界面进行查询
二、Bitmaps位图
- 概述:Bitmaps本身的数据结构就是字符串,支持对字符串的位进行操作。
- 场景:每个独立用户是否访问过网站存放在Bitmaps中,将访问的用户记做1,没有访问的用户记做0,用偏移量作为用户的id
setbit key offset value # 设置值
getbit key offset # 获取值
bitcount [start][end] # 获取Bitmaps指定范围值为1的个数,start和end代表起始和结束字节数
bitop是一个复合操作,做多个Bitmaps的and(交集)、or(并集) 、 not(非)、xor(异或)操作并将结果保存在destkey中
bitop op destkey key [key ... ]
Bitmaps分析
假设网站有1亿用户, 每天独立访问的用户有5千万, 如果每天用集合类型和Bitmaps分别存储活跃用户。
集合类型内存量:64位50000000=400M。
Bitmaps内存量:1位50000000=12.5M。
但如果该网站每天的独立访问用户很少,例如只有10万(大量的僵尸用户),就不适合。
三、HyperLogLog
- HyperLogLog并不是一种新的数据结构(实际是字符串类型),而是一种基数算法,通过HyperLogLog可以利用极小的内存空间完成独立总数的统计。
# 添加操作:如果添加成功返回1
pfadd key element [element …]
# 求一个或多个key的基数,计算独立用户数
pfcount key [key …]
# 合并:pfmerge可以求出多个HyperLogLog的并集并赋值给destkey
pfmerge destkey sourcekey [sourcekey ...]
-
HyperLogLog内存占用量小得惊人, 但是用如此小空间来估算如此巨大的数据, 必然不是100%的正确, 其中一定存在误差率。 Redis官方给出的数字是0.81%的失误率
-
选型时需要注意:
只为了计算独立总数,不需要获取单条数据
可以容忍一定误差率
四、发布publish / 订阅subscribe
# 发布消息
publish channel message
# 订阅消息:多个客户端订阅同一个频道,都会受到消息推送,类似于广播
subscribe channel [channel ...]
# 取消订阅
unsubscribe [channel [channel ...]]
# 按照模式订阅和取消订阅
psubscribe pattern [pattern...]
punsubscribe [pattern [pattern ...]]
# 订阅查询
pubsub channels [pattern] # 查看活跃的频道
pubsub numsub [channel ...] # 查看频道订阅数
pubsub numpat # 查看模式订阅数
五、GEO地理信息定位
# 增加地理位置信息,添加和更新都是用此命令
geoadd key longitude latitude member [longitude latitude member ...]
# longitude、 latitude、 member分别是该地理位置的经度、 纬度、 成员
# 获取地理位置信息
geopos key member [member ...]
# 获取两个地址位置的距离
geodist key member1 member2 [unit]
# unit代表返回结果的单位,m(meters) 代表米、km(kilometers) 代表公里、mi(miles) 代表英里、ft(feet) 代表尺
# 获取指定位置范围内的地理信息位置集合
georadius key longitude latitude radiusm|km|ft|mi [withcoord] [withdist][withhash] [COUNT count] [asc|desc] [store key] [storedist key]
georadiusbymember key member radiusm|km|ft|mi [withcoord] [withdist][withhash] [COUNT count] [asc|desc] [store key] [storedist key]
# 两个命令作用一样,都是以一个地理位置为中心算出指定半径内的其他地理信息位置,georadius 是给出中心位置的经纬度,georadiusbymember是给出中心位置的成员
# 获取geohash:Redis使用geohash将二维经纬度转换为一维字符串。
geohash key member [member ...]
# GEO的数据类型为zset, Redis将所有地理位置信息的geohash存放在zset中。
# 字符串越长, 表示的位置更精确, 例如geohash长度为9时, 精度在2米左右
# 两个字符串越相似, 它们之间的距离越近, Redis利用字符串前缀匹配算法实现相关的命令
# geohash编码和经纬度是可以相互转换的
# 删除地理位置信息
zrem key member
# GEO没有提供删除成员的命令, 但是因为GEO的底层实现是zset, 所以可以借用zrem命令实现对地理位置信息的删除。