6.Bitmaps
Redis提供了Bitmaps这个“数据类型”可以实现对位的操作:
(1)Bitmaps本身不是一种数据类型, 实际上它就是字符串(key-value) , 但是它可以对字符串的位进行操作。
(2)Bitmaps单独提供了一套命令, 所以在Redis中使用Bitmaps和使用字符串的方法不太相同。 可以把Bitmaps想象成一个以位为单位的数组, 数组的每个单元只能存储0和1, 数组的下标在Bitmaps中叫做偏移量
setbit
设置二进制位的值getbit
获取二进制位的值bitcount
统计被设置的二进制位数量(可以指定字节范围)bitpos
查找第一个指定的二进制位值bitop
执行二进制位运算
当BITOP命令在对两个长度不同的位图执行运算时,会将长度较短的那个位图中不存在的二进制位的值看作0。
bitfield
- 命令格式:
bitfield bitmap set type offset value
根据偏移量对区域进行设置
offset参数用于指定设置的起始偏移量。这个偏移量从0开始计算,偏移量为0表示设置从位图的第1个二进制位开始,偏移量为1则表示设置从位图的第2个二进制位开始,以此类推。如果被设置的值长度不止一位,那么设置将自动延伸至之后的二进制位。
type参数用于指定被设置值的类型,这个参数的值需要以i或者u为前缀,后跟被设置值的位长度,其中i表示被设置的值为有符号整数,而u则表示被设置的值为无符号整数。比如i8表示被设置的值为有符号8位整数,而u16则表示被设置的值为无符号16位整数,诸如此类。BITFIELD的各个子命令目前最大能够对64位长的有符号整数(i64)和63位长的无符号整数(u63)进行操作。
value参数用于指定被设置的整数值,这个值的类型应该和type参数指定的类型一致。如果给定值的长度超过了type参数指定的类型,那么SET命令将根据type参数指定的类型截断给定值。比如,如果用户尝试将整数123(二进制表示为01111011)存储到一个u4类型的区域中,那么命令会先将该值截断为4位长的二进制数字1011(即十进制数字11),然后再进行设置。命令格式:bitfield bitmap set type #index value
根据给定类型的位长度,对位图在指定索引上存储的整数值进行设置
bitfield bitmap set u8 #132 22
对位图的第133个8位无符号整数进行设置(索引是从0开始计算的)。
- 命令格式:
bitfield bitmap get type offset
、bitfield bitmap get type #index
获取区域存储的值 - 命令格式:
bitfield bitmap incrby type offset increment
、bitfield bitmap incrby type #index increment
执行加法操作或减法操作
命令格式:bitfield bitmap [...] overflow wrap|sat|fail [...]
处理溢出
- WRAP表示使用回绕(wrap around)方式处理溢出,这也是C语言默认的溢出处理方式。在这一模式下,向上溢出的整数值将从类型的最小值开始重新计算,而向下溢出的整数值则会从类型的最大值开始重新计算。
- SAT表示使用饱和运算(saturation arithmetic)方式处理溢出,在这一模式下,向上溢出的整数值将被设置为类型的最大值,而向下溢出的整数值则会被设置为类型的最小值。
- FAIL表示让INCRBY子命令在检测到计算会引发溢出时拒绝执行计算,并返回空值表示计算失败。
7.HyperLogLog
Redis HyperLogLog 是用来做基数统计的算法,算法的标准误差仅为0.81%。
HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定的、并且是很小的。
在 Redis 里面,每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基数。这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比。
但是,因为 HyperLogLog 只会根据输入元素来计算基数,而不会储存输入元素本身,所以 HyperLogLog 不能像集合那样,返回输入的各个元素。
pfadd
对集合元素进行计数pfcount
返回集合的近似基数pfmerge
计算多个HyperLogLog的并集
PFCOUNT命令在计算多个HyperLogLog的近似基数时会执行以下操作:
1)在内部调用PFMERGE命令,计算所有给定HyperLogLog的并集,并将这个并集存储到一个临时的HyperLogLog中。
2)对临时HyperLogLog执行PFCOUNT命令,得到它的近似基数(因为这是针对单个HyperLogLog的PFCOUNT,所以这个操作不会引起循环调用)。3)删除临时HyperLogLog。
4)向用户返回之前得到的近似基数
8.Geospatial
Redis 3.2 中增加了对GEO类型的支持。GEO,Geographic,地理信息的缩写。该类型,就是元素的2维坐标,在地图上就是经纬度。redis基于该类型,提供了经纬度设置,查询,范围查询,距离查询,经纬度Hash等常见操作。
geoadd
存储坐标geopos
获取指定位置的坐标geodist
计算两个位置之间的直线距离georadius
查找指定坐标半径范围内的其他位置
georadiusbymember
查找指定位置半径范围内的其他位置geohash
获取指定位置的Geohash值
9.流
流(stream)是Redis 5.0版本中新增加的数据结构。
流是一个包含零个或任意多个流元素的有序队列,队列中的每个元素都包含一个ID和任意多个键值对,这些元素会根据ID的大小在流中有序地进行排列。
xadd
追加新元素到流的末尾
流元素的ID由ID和顺序编号(sequcen number)两部分组成。如果输入只包含ID,不包含序号,redis会自动将序号部分设置成0.
同一个流中的不同元素是不允许使用相同ID的,且要求新元素的ID必须比流中所有已有元素的ID都要大。
- 流元素ID可以输入特殊值
*
,Redis将自动为新添加的元素生成一个可用的新ID(毫秒时间(millisecond)和顺序编号(sequcen number)两部分组成)。 xtrim
对流进行修剪xdel
移除指定元素xlen
获取流包含的元素数量xrange
、xrevrange
访问流中元素xread
以阻塞或非阻塞方式获取流元素xgroup
管理消费者组xreadgroup
读取消费者组中的消息
xpending
显示待处理消息的相关信息xack
将消息标记为“已处理”xclaim
转移消息的归属权xinfo
查看流和消费者组的相关信息
Redis的发布和订阅
1、客户端可以订阅频道如下图
2、当给这个频道发布消息后,消息就会发送给订阅的客户端
登录redis客户端,使用subscribe 频道
来订阅频道;使用publish 频道 "字符串"
将字符串发布到指定频道。
Redis的事务定义
Redis事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。
Redis事务的主要作用就是串联多个命令防止别的命令插队。
1.Multi、Exec、discard
从输入Multi命令开始,输入的命令都会依次进入命令队列中,但不会执行,直到输入Exec后,Redis会将之前的命令队列中的命令依次执行。
组队的过程中可以通过discard来放弃组队。
2.事务的错误处理
组队中某个命令出现了报告错误,执行时整个的所有队列都会被取消。
如果执行阶段某个命令报出了错误,则只有报错的命令不会被执行,而其他的命令都会执行,不会回滚。
乐观锁适用于多读的应用类型,这样可以提高吞吐量。Redis就是利用这种check-and-set机制实现事务的。
3.watch key [key …]
在执行multi之前,先执行watch key1 [key2],可以监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。
执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。
4.unwatch
取消 WATCH 命令对所有 key 的监视。
如果在执行 WATCH 命令之后,EXEC 命令或DISCARD 命令先被执行了的话,那么就不需要再执行UNWATCH 了。
Redis持久化之RDB.
Redis 提供了2个不同形式的持久化方式。
- RDB(Redis DataBase)
- AOF(Append Of File)
Redis会单独创建(fork)一个子进程来进行持久化,会先将数据写入到 一个临时文件中,待持久化过程都结束了,再用这个临时文件替换上次持久化好的文件。 整个过程中,主进程是不进行任何IO操作的,这就确保了极高的性能 如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效。RDB的缺点是最后一次持久化后的数据可能丢失。
1. RDB持久化流程
2.命令save VS bgsave
save
:save时只管保存,其它不管,全部阻塞。手动保存。不建议。bgsave
:Redis会在后台异步进行快照操作, 快照同时还可以响应客户端请求。
- 可以通过
lastsave
命令获取最后一次成功执行快照的时间
3.优势
- 适合大规模的数据恢复
- 对数据完整性和一致性要求不高更适合使用
- 节省磁盘空间
- 恢复速度快
4.劣势
Fork的时候,内存中的数据被克隆了一份,大致2倍的膨胀性需要考虑
虽然Redis在fork时使用了写时拷贝技术,但是如果数据庞大时还是比较消耗性能。
在备份周期在一定间隔时间做一次备份,所以如果Redis意外down掉的话,就会丢失最后一次快照后的所有修改。
5.总结