慢查询
- 前面学习了redis的基本使用,还有一些典型场景可以用到redis,从慢查询开始
- redis命令的生命周期:
- 慢查询发生在第3阶段
- 客户端超时不一定是慢查询导致,但慢查询是一个因素!
两个配置
showlog-max-len
- 这是针对慢查询队列的一个限制
- 慢查询命令会被记录在一个队列中,有以下特点:
- 先进先出
- 固定长度
- 保存在内存(不持久化)
- 配合第二个配置使用
showlog-log-slower-than
- 这个配置决定了判定慢查询的阈值,单位:微秒
- 设置为0,让所有命令进入慢查询队列,可以查看命令的运行时间
- 设置为<0,所有命令都不记录进慢查询
- 常见配置方式
命令
- 专门的慢查询API
- 运维经验
- 上面的1和2参数说反了!总之是要能缓存更多的慢查询
pipeline
- 流水线,为了减少网络时间
- 一次client到server需要经过
发送命令——处理——返回结果
- Redis可处理的QPS很高,主要时间花费在命令的发送和返回结果
- pipeline将命令打包:
- 假设一种极端场景:
- 实际情况肯定要比这花费更长时间,可见微秒级别的处理会被毫秒级别的信息传递拖慢
- 实际情况肯定要比这花费更长时间,可见微秒级别的处理会被毫秒级别的信息传递拖慢
- 实际测试
- 没有pipeline时,使用Jedis实现一下:大概50s
- 使用pipeline,大概0.7秒
- 没有pipeline时,使用Jedis实现一下:大概50s
- 一次client到server需要经过
- 到达server后pipeline会被拆开执行,但是会按顺序返回执行结果
- 使用建议:
- 使用建议:
发布订阅
- 这是一种消息模型
- 角色
- 发布者
- 订阅者
- 频道
- 通信
- 类似生产者消费者模型,发布者将消息发送到指定频道
- 订阅了某频道就能收到某发布者的消息
- Redis无法消息堆积,新订阅者不能收到之前的消息
- API
- publish
- subscribe
- publish
- 其他API,匹配方式
- 明确发布订阅的使用场景,订阅了频道就能收到消息
- 而消息队列一般是只发送给一个用户,或者说是一个“抢”的过程
- 之前有说过,消息队列可以用
lpush + brpop
阻塞实现
- 之前有说过,消息队列可以用
bitmap
- 字符串
big
的二进制码:
- 也就是说,Redis可以直接位操作
- API
setbit key offset value
,直接设置位值;getbit
就不说了,索引从0开始
- 注:不要在很短的位图上做很大的
offset
,会默认执行补0操作!
- 其他API
bitcount key [start end]
,获取指定范围的1的个数
bitop
bitpos
用户统计
- 场景:每天1亿用户访问量,5千万独立(其实就五千万用户),我们需要做一个记录(用于统计);我们对比set和bitmap
- 假设我们使用id标识登录用户,如果使用set,可以去重,只需存储5000万,但每个id都是整型32位
- 我们使用1位标识一个用户,没有去重,但也只需12M左右的空间
- 对比而言:
- 如果用户量较小:
- 小结
- 其实主要就是节省内存空间,用户访问量的统计需求要视具体场景而定,用什么标识,访问量级别等等
- 对于非常大的访问量(比如多多),用位图也吃力,可以使用下面的结构
HyperLogLog
- 这是一个用来做基数统计的算法
- 优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定的、并且是很小的
- 一般用于做独立用户统计(用户访问量统计)
- API使用,很简单,常用的就3个
- 模拟百万独立用户的内存消耗
- 大概15KB,占用很小
- 使用经验
- 占用空间极小,代价就是有错误,不能取出某一条数据
- 可以
pfadd
uuid来标识用户,进行独立访问量统计!
- 占用空间极小,代价就是有错误,不能取出某一条数据
GEO
- 地理信息定位;存储经纬度,计算两地距离,范围计算等等
- 举例:
- 获取经纬度
- 计算距离
georadius
- 举例:
- 底层使用的是zset,没有提供专门的API,所以可以
zrem key member