Redis(慢查询, pipeline, 发布订阅, Bitmap, HyperLogLog, GEO) 学习笔记
Redis(慢查询, pipeline, 发布订阅, Bitmap, HyperLogLog, GEO)
1. 慢查询
客户端请求的生命周期
两个配置
配置
-
slowlog-max-len
慢查询队列最大长度- 先进先出队列
- 固定长度(队列满了后会以先进先出的方式,保证队列的固定长度)
- 保存在内存中(不会持久化,重启消失)
-
slowlog-log-slower-than
慢查询阈值- 慢查询阈值(单位:微妙)
slowlog-log-slower-than=0
记录所有命令 (排查问题时,查看执行查询命令时会使用)slowlog-log-slower-than<0
不记录任何命令
配置方法
- 默认值
config get slowlog-max-len
= 128config get slowlog-log-slower-than
= 10000
- 修改配置文件重启
- 动态配置
config set slowlog-max-len 1000
config set slowlog-log-slower-than 1000
3个命令
slowlog get [n]
: 获取慢查询队列slowlog len
: 获取慢查询队列长度slowlog reset
: 清空慢查询队列
运维经验
slowlog-log-slower-then
不要设置过大,默认10ms, 通常设置1ms(1000)slowlog-max-len
不要设置过小,通常设置1000左右- 理解命令生命周期(综合考虑 网络 慢查询 QPS 等因素)
- 定期持久化慢查询(通过
slowlog get [n]
命令获取慢查询记录,然后保存到其他的数据中)
2. pipeline 流水线
什么是流水线?
流水线作用
对比 pipeline 的使用
-
不使用 pipeline
-
使用 pipeline
pipeline 使用建议
- 注意每次 pipeline 携带数据量
- pipeline 每次只能作用在一个 Redis 节点上
- M操作(mget, mset)命令和 pipeline 的区别
- M操作(mget, mset)命令的执行是原子的,本身就是一条原生的命令
- pipeline 是执行多条命令,不具备原子性
3. 发布订阅
角色
- 发布者(publisher)
- 订阅者(subscriber)
- 频道(channel)
模型
API
publish (发布)
publish channel message
# 示例 127.0.0.1:6382> publish sohu:tv "hello world" (integer) 0 # 表示订阅个数, 0 表示没有订阅者 127.0.0.1:6382> publish sohu:tv "hello" (integer) 3 # 表示订阅个数, 3 表示有3个订阅者
subscribe (订阅)
subscribe [channel]
: 订阅1个或多个频道127.0.0.1:6382> subscribe sohu:tv cctv1 Reading messages... (press Ctrl-C to quit) 1) "subscribe" 2) "sohu:tv" 3) (integer) 1 1) "subscribe" 2) "cctv1" 3) (integer) 2 1) "message" 2) "sohu:tv" 3) "hello" 1) "message" 2) "cctv1" 3) "hello"
unsubscribe (取消订阅)
unsubscribe [channel]
: 取消订阅1个或者多个频道127.0.0.1:6382> unsubscribe sohu:tv 1) "unsubscribe" 2) "sohu:tv" 3) (integer) 0
疑问:为什么在 redis-cli 中使用了 subscribe 命令之后无法再执行 unsubscribe 等的命令
https://nicechiblog.com/article/21/article_1598666045913.html
其他
psubscribe [pattern]
: 订阅模式(匹配频道)punsubscribe [pattern]
: 退出指定的模式(指定匹配模式)pubsub channels
: 列出至少有一个订阅者的频道pubsub numsub [channel...]
: 列出给定频道的订阅者数量pubsub numpat
: 列出被订阅模式的数量
对比发布订阅与消息队列
-
消息队列模式
总结
- 明白发布订阅模式中的角色
- 明白重要的API
- 明白发布订阅和消息队列的使用场景
4. Bitmap (位图)
位图介绍
127.0.0.1:6382> set hello big
OK
127.0.0.1:6382> get hello
"big"
127.0.0.1:6382> getbit hello 0
(integer) 0
127.0.0.1:6382> getbit hello 1
(integer) 1
127.0.0.1:6382> getbit hello 2
(integer) 1
127.0.0.1:6382> getbit hello 3
(integer) 0
127.0.0.1:6382> getbit hello 6
(integer) 1
127.0.0.1:6382> getbit hello 7
(integer) 0
相关命令
-
setbit key offset value
: 给位图指定索引设置值# big '01100010 01101001 01100111' 127.0.0.1:6382> set hello big OK 127.0.0.1:6382> get hello "big" 127.0.0.1:6382> getbit hello 0 (integer) 0 127.0.0.1:6382> setbit hello 0 1 # 将 hello 的第0个bit设置为1 (integer) 0 # 返回值0: 表示修改之前对应位的值是0 127.0.0.1:6382> getbit hello 0 (integer) 1 127.0.0.1:6382> get hello "\xe2ig" 127.0.0.1:6382> set hello big OK 127.0.0.1:6382> get hello "big" 127.0.0.1:6382> setbit hello 7 1 (integer) 0 127.0.0.1:6382> get hello "cig"
-
getbit key offset
: 获取位图指定索引的值 -
bitcount key [start end]
: 获取位图指定范围位值为1的个数(start 到 end,单位为字节,如果不指定就是获取全部)注意:start 和 end,单位为字节
# big '01100010 01101001 01100111' 127.0.0.1:6382> set hello big OK 127.0.0.1:6382> bitcount hello (integer) 12 127.0.0.1:6382> bitcount hello 0 1 (integer) 7 127.0.0.1:6382> 127.0.0.1:6382> 127.0.0.1:6382> bitcount hello 1 1 (integer) 4 127.0.0.1:6382> bitcount hello 0 0 (integer) 3 127.0.0.1:6382>
-
bitop op destkey key [key...]
: 做多个 Bitmap 的 and(交集),or(并集),not(非),xor(异或) 操作,并将结果保存到destkey中127.0.0.1:6382> set test1 abc OK 127.0.0.1:6382> set test2 bbc OK 127.0.0.1:6382> set test3 abbd OK 127.0.0.1:6382> bitop and test test1 test2 (integer) 3 127.0.0.1:6382> get test "`bc" 127.0.0.1:6382> bitop or test test1 test2 (integer) 3 127.0.0.1:6382> get test "cbc" 127.0.0.1:6382> bitop not test test1 (integer) 3 127.0.0.1:6382> get test "\x9e\x9d\x9c" 127.0.0.1:6382> bitop and test test2 test3 (integer) 4 # 结果destkey的字节数 127.0.0.1:6382> get test "`bb\x00"
-
bitpos key targetBit [start] [end]
: 计算位图指定范围(start到end,单位为字节,如果不指定就是获取全部)第一个偏移量对应的值等于targetBit的位置# big '01100010 01101001 01100111' 127.0.0.1:6382> get hello "big" 127.0.0.1:6382> bitpos hello 1 (integer) 1 127.0.0.1:6382> bitpos hello 1 1 2 (integer) 9
独立用户统计 (位图的简单使用)
-
使用 set 和 Bitmap 对比
-
1亿用户,5千万独立访问
Bitmap 使用经验
- type=string, 最大512MB
- 注意setbit时的偏移量,可能有较大耗时
- 位图不是绝对好
5. HyperLogLog
新的数据结构?
- 基于 HyperLogLog 算法:极小空间完成独立数量统计
- 本质还是字符串
127.0.0.1:6382> pfadd web "u1" (integer) 1 127.0.0.1:6382> type web string
三个命令
-
pfadd key element [element...]
: 向 hyperloglog 添加元素 -
pfcount key [key...]
: 计算 hyperloglog 的独立总数 -
pfmerge destkey sourcekey [sourcekey...]
: 合并多个 hyperloglog127.0.0.1:6382> pfadd 20200601:unique:ids "uuid-1" "uuid-2" "uuid-3" "uuid-4" (integer) 1 127.0.0.1:6382> pfadd 20200602:unique:ids "uuid-4" "uuid-5" "uuid-6" "uuid-7" (integer) 1 127.0.0.1:6382> pfcount 20200602:unique:ids (integer) 4 127.0.0.1:6382> pfcount 20200601:unique:ids 20200602:unique:ids (integer) 7 127.0.0.1:6382> pfmerge 202006_01_02:unique:ids 20200601:unique:ids 20200602:unique:ids OK 127.0.0.1:6382> pfcount 202006_01_02:unique:ids (integer) 7
内存消耗(百万独立用户)
使用经验
-
是否能容忍错误率?(错误率:0.81%)
百万独立用户统计结果:
-
是否需要单条数据?
6. GEO
GEO 是什么
应用场景
5个城市的经纬度
相关命令
-
geoadd key longitude latitude member [longtitude latitude member ...]
: 添加地理位置信息127.0.0.1:6382> geoadd cities:locations 116.28 39.55 beijing (integer) 1 # 添加1个member 127.0.0.1:6382> geoadd cities:locations 116.28 39.55 beijing (integer) 0 # 添加0个member (重复不会添加) 127.0.0.1:6382> geoadd cities:locations 117.12 39.08 tianjing 114.29 38.02 shijiazhuang 118.01 39.38 tangshan 115.29 38.51 baoding (integer) 4 # 添加4个member
-
geopos key member [membet ...]
: 获取地理位置127.0.0.1:6382> geopos cities:locations beijing 1) 1) "116.28000229597091675" 2) "39.5500007245470826" 127.0.0.1:6382> geopos cities:locations beijing baoding 1) 1) "116.28000229597091675" 2) "39.5500007245470826" 2) 1) "115.28999894857406616" 2) "38.50999956342798924" 127.0.0.1:6382>
-
geodist key member1 member2 [unit]
: 获取两个地理位置的距离127.0.0.1:6382> geodist cities:locations beiji ng tianjin km "89.2061"
-
georadius
georadiusbymember
获取指定范围内的地理位置信息集合:georadius key longitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count [ANY]] [ASC|DESC] [STORE key] [STOREDIST key]
georadiusbymember key member radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count [ANY]] [ASC|DESC] [STORE key] [STOREDIST key]
- wihcoord: 返回结果包含经纬度
- withdist: 返回结果包含距离中心节点位置
- withhash: 返回结果中包含geohash
- Count count: 指定返回结果的数量
- asc|desc: 返回结果按照距离中心节点的距离做升序、降序
- store key: 将返回结果的地理位置信息保存到指定key
- storedist key: 将返回结果距离中心节点的距离保存到指定key
127.0.0.1:6382> georadiusbymember cities:locations beijing 150 km 1) "beijing" 2) "tianjin" 3) "tianjing" 4) "tangshan" 5) "baoding"
相关说明
- redis 3.2+ 提供功能
- type geoKey = zset
127.0.0.1:6382> type cities:locations zset
- 没有删除API(使用有序集合的删除命令):
zrem key member
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)