Reids的一些简单操作以及API演示
Reids瑞士军刀
一、慢查询
keys * 、hmgetall 这些时间复杂度大的操作可能会导致慢查询。
生命周期
客户端超时不一定是慢查询,也可能是阻塞,或者是网络的通讯问题(生命周期中4个阶段都可能导致)
两个配置
slowlog-max-len
- 先进先出的队列
- 固定长度
- 保存在内存内
当队列满了,再有慢查询指令进入队列,第一个操作就会被去除。
保存在内存中,如果重启,指令就会消失。
慢查询队列实际是使用Redis的list数据结构实现的。
slow-log-slower-than
- 慢查询阈值(单位:微秒)
- slow-log-slower-than=0,记录所有指令
- slow-log-slower-than<0,不记录任何指令
配置方法
- 默认值
- config get slowlog-max-len 128
- config get slowlog-log-slower-than 10000
- 修改配置文件重启
- 动态配置
- config set slowlog-max-len 1000
- config set slowlog-log-slower-than 1000
慢查询命令
运维经验
为了保证万级别的QPS(每秒查询率),slowlog-log-slower-than 不能设置过大。
队列长度不能过小,可以方便寻找问题
定期持久化到数据库(MySql)
二、pipeline 流水线
redis的读写速度十分快,所以系统的瓶颈往往是在网络通信中的延迟。
redis可能会在很多时候处于空闲状态而等待命令的到达。
为了解决这个问题,可以使用redis的流水线,流水线是一种通讯协议,类似一个队列批量执行一组命令。(减少时间开销)
流水线的作用
命令 | N个操作命令 | 1次pipeline(n个命令) |
---|---|---|
时间 | n次网络+n次命令 | 1次网络+n次命令 |
数据量 | 1条命令 | n条命令 |
解决了n次操作的网络时间
注意两点
- Redis的命令时间都是微秒级别的
- pipeline每次条数要控制(网络)
与原生m操作的区别
原生m操作是原子的。
流水线是非原子的,一个流水线操作会被拆分成若干个子操作
使用建议
- 注意每次pipeline携带的数据量
- pipeline每次只能作用在一个Redis节点
三、发布订阅
角色
- 发布者(publisher)
- 订阅者(subscriber)
- 频道 (channels)
可以想象为生产者-消费者模型
发布者一个客户端,订阅者也是一个客户端(redis-cli)
API
命令 | 描述 |
---|---|
PSUBSCRIBE pattern [pattern …] | 订阅一个或多个符合给定模式的频道。 |
PUBSUB subcommand [argument [argument …]] | 查看订阅与发布系统状态。 |
PUBLISH channel message | 将信息发送到指定的频道。 |
PUNSUBSCRIBE [pattern [pattern …]] | 退订所有给定模式的频道。 |
SUBSCRIBE channel [channel …] | 订阅给定的一个或多个频道的信息。 |
UNSUBSCRIBE [channel [channel …]] | 指退订给定的频道。 |
详细api查询文档redis发布订阅
与消息队列的区别
发布订阅:发布者发布后,所有的订阅者都可以接受到消息。
消息队列:消息发布后,消息队列是一个抢的操作,只有一个客户端拿到消息。
发布订阅不适合这种业务。不过可以通过linked list,通过blpop key timeout
阻塞弹出来实现这种效果。
四、位图(BitMap)
什么是位图
就是通过一个bit位来表示某个元素对应的值或者状态,其中的key就是对应元素本身。我们知道8个bit可以组成一个Byte,所以bitmap本身会极大的节省储存空间。
Redis的位图
Redis从2.2.0版本开始新增了setbit,getbit,bitcount等几个bitmap相关命令。虽然是新命令,但是并没有新增新的数据类型,因为setbit等命令只不过是在set上的扩展
API
命令 | 含义 |
---|---|
getbit key offset | 对key所存储的字符串值,获取指定偏移量上的位(bit) |
setbit key offset value | 对key所存储的字符串值,设置或清除指定偏移量上的位(bit)1. 返回值为该位在setbit之前的值2. value只能取0或13. offset从0开始,即使原位图只能10位,offset可以取1000 |
bitcount key [start end] | 获取位图指定范围中位值为1的个数如果不指定start与end,则取所有 |
bitop op destKey key1 [key2…] | 做多个BitMap的and(交集)、or(并集)、not(非)、xor(异或)操作并将结果保存在destKey中 |
bitpos key tartgetBit [start end] | 计算位图指定范围第一个偏移量对应的的值等于targetBit的位置1. 找不到返回-12. start与end没有设置,则取全部3. targetBit只能取0或者1 |
使用场景
- 用户签到
很多网站都提供了签到功能(这里不考虑数据落地事宜),并且需要展示最近一个月的签到情况,如果使用bitmap我们怎么做?一言不合亮代码!
根据日期 offset =hash % 365 ; key = 年份#用户id
- 统计活跃用户
使用时间作为cacheKey,然后用户ID为offset,如果当日活跃过就设置为1
那么我该如果计算某几天/月/年的活跃用户呢(暂且约定,统计时间内只有有一天在线就称为活跃),有请下一个redis的命令
命令 BITOP operation destkey key [key …]
说明:对一个或多个保存二进制位的字符串 key 进行位元操作,并将结果保存到 destkey 上。
说明:BITOP 命令支持 AND 、 OR 、 NOT 、 XOR 这四种操作中的任意一种参数
20190216 活跃用户 【1,2】
20190217 活跃用户 【1】
统计20190216~20190217 总活跃用户数: 1
- 用户在线状态
使用bitmap是一个节约空间效率又高的一种方法,只需要一个key,然后用户ID为offset,如果在线就设置为1,
不在线就设置为0,和上面的场景一样,5000W用户只需要6MB的空间。
HyperLogLog
- Redis 在 2.8.9 版本添加了 HyperLogLog 结构。
- Redis HyperLogLog 是用来做基数统计的算法,HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定 的、并且是很小的。
- 在 Redis 里面,每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基 数。这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比。
- 但是,因为 HyperLogLog 只会根据输入元素来计算基数,而不会储存输入元素本身,所以 HyperLogLog 不能像集合那样,返回输入的各个元素。
API
命令 | 描述 |
---|---|
PFADD key element [element …] | 将除了第一个参数以外的参数存储到以第一个参数为变量名的HyperLogLog结构中.这个命令的一个副作用是它可能会更改这个HyperLogLog的内部来反映在每添加一个唯一的对象时估计的基数(集合的基数). |
PFCOUNT key [key …] | 当参数为一个key时,返回存储在HyperLogLog结构体的该变量的近似基数,如果该变量不存在,则返回0.当参数为多个key时,返回这些HyperLogLog并集的近似基数,这个值是将所给定的所有key的HyperLoglog结构合并到一个临时的HyperLogLog结构中计算而得到的. |
PFMERGE destkey sourcekey [sourcekey …] | 将多个 HyperLogLog 合并(merge)为一个 HyperLogLog , 合并后的 HyperLogLog 的基数接近于所有输入 HyperLogLog 的可见集合(observed set)的并集. |
使用场景
- 统计注册 IP 数
- 统计每日访问 IP 数
- 统计页面实时 UV 数
- 统计在线用户数
- 统计用户每天搜索不同词条的个数
GEO(地理位置信息)
作用
- 储存经纬度
- 计算两地距离
- 范围计算
API
命令 | 描述 |
---|---|
GEOADD key longitude latitude member [longitude latitude member …] | 添加一个或多个地理位置到Sorted Set |
GEOHASH key member [member …] | 返回一个标准的地理空间的Geohash |
GEOPOS key member [member …] | 返回地理空间的经纬度 |
GEODIST key member1 member2 [unit] | 返回两个给定位置之间的距离。 m 表示单位为米。km 表示单位为千米。mi 表示单位为英里。ft 表示单位为英尺。 |
GEORADIUS key longitude latitude radius m km ft mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] | GEORADIUS key longitude latitude radius m |
GEORADIUSBYMEMBER key member radius m km ft mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] | 这个命令和 GEORADIUS 命令一样, 都可以找出位于指定范围内的元素, 但是 GEORADIUSBYMEMBER 的中心点是由给定的位置元素决定的 |
[Unit]
- m 表示单位为米。
- km 表示单位为千米。
- mi 表示单位为英里。
- ft 表示单位为英尺。
- WITHDIST: 在返回位置元素的同时, 将位置元素与中心之间的距离也一并返回。 距离的单位和用户给定的范围单位保持一致。
- WITHCOORD: 将位置元素的经度和维度也一并返回。
- WITHHASH: 以 52 位有符号整数的形式, 返回位置元素经过原始 geohash 编码的有序集合分值。 这个选项主要用于底层应用或者调试, 实际中的作用并不大。
由于GEO的基本数据类型时Sorted Set 所有删除命令为zrem