Redis(五)Redis消息模式及事务及其它数据类型

262 阅读7分钟

Redis消息模式

队列模式

使用list类型的lpush和rpop实现消息队列

注意事项:

  • 消息接收方如果不知道队列中是否有消息,会一直发送rpop命令,如果这样的话,会每一次都建立一次连接,这样显然不好

  • 可以使用brpop命令,它如果从队列中取不出来数据,会一直阻塞,在一定范围内没有取出则返回null

发布订阅模式

Redis 发布订阅 (pub/sub) 是一种消息通信模式:发送者 (pub) 发送消息,订阅者 (sub) 接收消息。

Redis 客户端可以订阅任意数量的频道。

订阅消息(subscribe)

下图展示了频道 channel1 , 以及订阅这个频道的三个客户端 —— client2 、 client5 和 client1 之间的关系

Snipaste_2021-08-10_17-17-13.png

示例:

subscribe channel1

发布消息(publish)

当有新消息通过 PUBLISH 命令发送给频道 channel1 时, 这个消息就会被发送给订阅它的三个客户端

微信截图_20210811094759.png

示例:

publish channel1 "测试发布订阅"

Redis 发布订阅命令

订阅一个或多个符合给定模式的频道

PSUBSCRIBE pattern [pattern ...]

查看订阅与发布系统状态

PUBSUB subcommand [argument [argument ...]]

将信息发送到指定的频道

PUBLISH channel message

退订所有给定模式的频道

PUNSUBSCRIBE [pattern [pattern ...]]

订阅给定的一个或多个频道的信息

SUBSCRIBE channel [channel ...]

指退订给定的频道

UNSUBSCRIBE [channel [channel ...]]

Redis事务

Redis事务介绍

  • Redis 的事务是通过 MULTI 、 EXEC 、 DISCARD 和 WATCH 、UNWATCH这五个命令来完成的

  • Redis 的单个命令都是原子性的,所以这里需要确保事务性的对象是命令集合

  • Redis 将命令集合序列化并确保处于同一事务的命令集合连续且不被打断的执行

  • Redis 不支持回滚操作

事务命令

MULTI

  • 用于标记事务块的开始

  • Redis会将后续的命令逐个放入队列中,然后使用EXEC命令原子化地执行这个命令序列

  • 语法

    multi

EXEC

  • 在一个事务中执行所有先前放入队列的命令,然后恢复正常的连接状态

  • 语法

    exec

DISCARD

  • 清除所有先前在一个事务中放入队列的命令,然后恢复正常的连接状态

  • 语法

    discard

WATCH

  • 当某个[事务需要按条件执行]时,就要使用这个命令将给定的[键设置为受监控]的状态

  • 语法

    watch key [key…]

  • 注意

    使用该命令可以实现 Redis 的乐观锁

UNWATCH

  • 清除所有先前为一个事务监控的键

  • 语法

    unwatch

Redis不支持事务回滚原因

  • 大多数事务失败是因为语法错误或者类型错误,这两种错误,在开发阶段都是可以预见的

  • Redis 为了性能方面就忽略了事务回滚

Redis 的补充数据类型

BitMap

BitMap 就是通过一个 bit 位来表示某个元素对应的值或者状态, 其中的 key 就是对应元素本身,实际上底层也是通过对字符串的操作来实现。Redis 从 2.2 版本之后新增了setbit, getbit, bitcount 等几个bitmap 相关命令。虽然是新命令,但是本身都是对字符串的操作

  • 语法

    SETBIT key offset value

其中 offset 必须是数字,value 只能是 0 或者 1,offset参数要求大于或等于 0,并且小于 2^32(4,294,967,296)这将位图限制在 512MB

通过 bitcount可以很快速的统计,比传统的关系型数据库效率高很多

  • BITOP operation destkey key [key ...]

    对一个或多个保存二进制位的字符串 key 进行位元操作,并将结果保存到 destkey 上

    operation 可以是 AND 、 OR 、 NOT 、 XOR 这四种操作中的任意一种

    • BITOP AND destkey key [key ...] ,对一个或多个 key 求逻辑并,并将结果保存到destkey

    • BITOP OR destkey key [key ...] ,对一个或多个 key 求逻辑或,并将结果保存到 destkey

    • BITOP XOR destkey key [key ...] ,对一个或多个 key 求逻辑异或,并将结果保存到destkey

    • BITOP NOT destkey key ,对给定 key 求逻辑非,并将结果保存到 destkey

    除了 NOT 操作之外,其他操作都可以接受一个或多个 key 作为输入

HyperLogLog

Redis 在 2.8.9 版本添加了 HyperLogLog 结构。Redis HyperLogLog 是用来做基数统计的算法,HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定 的、并且是很小的

在 Redis 里面,每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基数。这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比。

但是,因为 HyperLogLog 只会根据输入元素来计算基数,而不会储存输入元素本身,所以 HyperLogLog 不能像集合那样,返回输入的各个元素

这个数据结构的命令有三个:PFADD、PFCOUNT、PFMERGE

Geospatial

底层数据结构 Zset

命令:GEOADD、GEODIST、GEOHASH、GEOPOP、GEOPADUIS、GEORADIUSBYMEMBER

可以用来保存地理位置,并作位置距离计算或者根据半径计算位置等

Redis GEO 操作方法有

  • geoadd:添加地理位置的坐标

  • geopos:获取地理位置的坐标

  • geodist:计算两个位置之间的距离

  • georadius:根据用户给定的经纬度坐标来获取指定范围内的地理位置集合

  • georadiusbymember:根据储存在位置集合里面的某个地点获取指定范围内的地理位置集合

  • geohash:返回一个或多个位置对象的 geohash 值

精确到小数点后6位可以达到约1米精度,所以一般经纬度精确到小数点后6位即可

Redis Stream

Redis 5.0 全新的数据类型:streams,官方把它定义为:以更抽象的方式建模日志的数据结构。Redis 的streams主要是一个append only(AOF)的数据结构,至少在概念上它是一种在内存中表示的抽象 数据类型,只不过它们实现了更强大的操作,以克服日志文件本身的限制

如果你了解MQ,那么可以把streams当做基于内存的MQ。如果你还了解kafka,那么甚至可以把streams当做基于内存的kafka。listpack存储信息,Rax组织listpack 消息链表

listpack是对ziplist的改进,它比ziplist少了一个定位最后一个元素的属性

另外,这个功能有点类似于redis以前的Pub/Sub,但是也有基本的不同

  • streams支持多个客户端(消费者)等待数据(Linux环境开多个窗口执行XREAD即可模拟),并且每个客户端得到的是完全相同的数据

  • Pub/Sub是发送忘记的方式,并且不存储任何数据;而streams模式下,所有消息被无限期追加在streams中,除非用于显式执行删除(XDEL)。 XDEL 只做一个标记位 其实信息和长度还在

  • streams的Consumer Groups也是Pub/Sub无法实现的控制方式

streams数据结构本身非常简单,但是streams依然是Redis到目前为止最复杂的类型,其原因是实现的一些额外的功能:一系列的阻塞操作允许消费者等待生产者加入到streams的新数据。另外还有一个称为Consumer Groups的概念,Consumer Group概念最先由kafka提出,Redis有一个类似实现,和kafka的Consumer Groups的目的是一样的:允许一组客户端协调消费相同的信息流

消息队列相关命令

  • XADD 添加消息到末尾

  • XTRIM 对流进行修剪,限制长度

  • XDEL 删除消息

  • XLEN 获取流包含的元素数量,即消息长度

  • XRANGE 获取消息列表,会自动过滤已经删除的消息

  • XREVRANGE 反向获取消息列表,ID 从大到小

  • XREAD 以阻塞或非阻塞方式获取消息列表

消费者组相关命令

  • XGROUP CREATE 创建消费者组

  • XREADGROUP GROUP 读取消费者组中的消息

  • XACK 将消息标记为"已处理"

  • XGROUP SETID 为消费者组设置新的最后递送消息ID

  • XGROUP DELCONSUMER 删除消费者

  • XGROUP DESTROY 删除消费者组

  • XPENDING 显示待处理消息的相关信息

  • XCLAIM 转移消息的归属权

  • XINFO 查看流和消费者组的相关信息

  • XINFO GROUPS 打印消费者组的信息

  • XINFO STREAM 打印流信息