本博客讲述如何对redis中的流进行遍历
接上篇博客redis 流 stream的使用总结 - 基础命令
简言
1. XRANGE,XREVRANGE,XREAD命令只适合单个消费者模式,因为这三个命令都可以获取流中的元素,也都可以删除,只能实现公有订阅(所有的消费者都能收到消息,也不是很安全),无法实现私有订阅(所有消费者中,只有一个可以收到消息)
2. 若只有单个消费者,那么无论如何获取,删除,都是安全的
3. 若有多个消费者,请使用消费者组,具体可见下片博客 如何使用redis中流stream的组
这篇主要讲述3个命令
5. XRANGE 顺序访问流中的元素,元素ID从小到大
6. XREVRANGE 逆序访问流中的元素,元素ID从大到小
7. XREAD 以阻塞或非阻塞方式获取流元素
具体用法及示例
5. XRANGE 顺序访问流中的元素,元素ID从小到大
格式:XRANGE stream start_id end_id [COUNT n]
注释:获取流stream中ID大于等于start_id ,小于等于end_id 的元素列表,限制个数为n;若没有符合条件的元素,会返回一个空列表
例1:XRANGE s1 2000000000000 2000000000000
注释:这样可以获取指定的单个元素
1) 1) 2000000000000-0 // 流元素的ID
2) 1) "k1" // 流元素包含的键
2) "v1" // 流元素包含的值
例2:XRANGE s1 3000000000000 4000000000000
注释:获取指定ID范围内的多个元素
1) 1) 3000000000000-0 // 符合ID范围的第1个元素
2) 1) "k1"
2) "v1"
2) 1) 4000000000000-0 // 符合ID范围的最后一个元素
2) 1) "k1"
2) "v1"
例3:XRANGE s1 - +
注释:获取所有元素,- 表流中最小元素ID,+ 表流中最大元素ID
1) 1) 1000000000000-0 // 流中最小元素ID
2) 1) "k1"
2) "v1"
.....省略中间元素.....
4) 1) 4000000000000-0 // 流中最大元素ID
2) 1) "k1"
2) "v1"
例4:对流进行迭代,具体步骤如下
步骤1:使用 - 作为起始ID,+ 作为结束ID,调用带有COUNT选项的XRANGE 命令,获取流的前N个元素
步骤2:对于步骤1返回的最后一个元素,将该元素ID的顺序部分加1,得到一个新ID
步骤3:使用新ID作为起始ID,+ 作为结束ID,继续调用带有COUNT选项的XRANGE命令,直到返回的列表为空或少于我们限定的COUNT值,说明已经遍历完毕
示例步骤1:redis> XRANGE s1 - + COUNT 2
1) 1) 1000000000000-0 // 第一个元素ID
2) 1) "k1"
2) "v1"
2) 1) 1000000000000-1 // 第二个元素ID
2) 1) "k1"
2) "v1"
由于正常返回了2个元素,我们假设后面还有元素,把元素ID 1000000000000-1的顺序部分加1得到1000000000000-2,进行第2步
示例步骤2:redis> XRANGE s1 1000000000000-2 + COUNT 1
1) 1) 2000000000000-0 // 第一个元素ID
2) 1) "k1"
2) "v1"
由于只返回了1个元素,所以后面已经没有元素了,结束遍历;当然如果步骤2返回的列表为空,也说明遍历完毕了
6. XREVRANGE 逆序访问流中的元素,元素ID从大到小
格式:XREVRANGE stream end_id start_id [COUNT n]
注意:该命令格式前面是结束ID,后面是起始ID,与XRANGE命令正好相反
例如:XREVRANGE s1 + - COUNT 2
1) 1) 4000000000000-0 // 最大元素ID
2) 1) "k1"
2) "v1"
2) 1) 3000000000000-0 // 第二大元素ID
2) 1) "k1"
2) "v1"
7. XREAD 以阻塞或非阻塞方式获取流元素,ID从小往大进行遍历,可以同时对多个流进行遍历,能够以阻塞和非阻塞方式进行
注意:XRANGE命令 是大于等于元素ID,而XREAD 命令是大于元素ID,没有等于
格式:XREAD [COUNT n] STREAMS stream1 stream2 stream3 ... id1 id2 id3 ...
例如:redis> XREAD COUNT 1 STREAMS s1 s2 s3 1000000000000 1000000000000 1000000000000
注释:从流 s1 s2 s3 中各取出一个ID大于 1000000000000的元素,我们
1) 1) "s1" // 下面的元素来自流 s1
2) 1) 1) 1100000000000-0 // 第一个元素的ID
2) 1) "k1" // 第一个元素的ID键值对
2) "v1"
2) 1) "s2" // 下面的元素来自流 s2
2) 1) 1) 1531743117644-0 // 第一个元素的ID
2) 1) "k1" // 第一个元素的ID键值对
2) "v1"
3) 1) "s3" // 下面的元素来自流 s3
2) 1) 1) 1531748220373-0 // 第一个元素的ID
2) 1) "k1" // 第一个元素的ID键值对
2) "v1"
迭代流
步骤1:将表示流起点的特殊ID 0-0 (或者简写0都可以)作为ID传入,调用XREAD命令
步骤2:使用命令返回的最后一个元素ID作为ID参数,再次调用XREAD命令,直到返回的空列表或者个数少于我们限定的COUNT值
示例步骤1:redis> XREAD COUNT 2 s1 0-0
1) 1) "s1" // 下面的元素来自流 s1
2) 1) 1) 1100000000000-0 // 第一个元素
2) 1) "k1"
2) "v1"
2) 1) 1200000000000-0 // 第二个元素
2) 1) "k1"
2) "v1"
这个命令会从流s1中取出最开始的两个元素,它们的ID分别为1100000000000-0和1200000000000-0,我们直接用 1200000000000-0作为新ID,调用步骤2,不需加1,因为 XREAD会取出ID大于该值的元素,而XRANGE是大于等于
示例步骤2:redis> XREAD COUNT 2 s1 1200000000000-0
1) 1) "s1" // 下面的元素来自流 s1
2) 1) 1) 1500000000000-0 // 第一个元素
2) 1) "k1"
2) "v1"
由于这次只返回了一个元素,说明遍历完毕;再次调用XREAD命令,会返回空列表的
XRANGE 和 XREAD的区别
1. XRANGE的ID是一个范围,范围是闭区间,即【】,而XREAD的ID是一个值,且是开区间,即 (
2. XRANGE遍历时需计算ID值,即拿上一次遍历的最后一个元素的ID的顺序部分加1;而XREAD不需要,直接用即可
3. 遍历方向: XRANGE是从头到尾,XREVRANGE是从尾到头;而XREAD只能从头到尾
4. XRANGE 和 XREVRANGE 一次只能遍历一个流;XREAD一次可以遍历多个流
5. XRANGE 和 XREVRANGE 只能获取已有的元素,不等待;而 XREAD可以阻塞等待一段时间
XREAD 阻塞调用
格式:XREAD [BLOCK ms] [COUNT n] STREAMS stream1 stream2 stream3 ... id1 id2 id3 ...
注意:BLOCK可以是大于等于0的任何值,0表一直阻塞直到出现了可返回的元素为止。若一直没有元素,超时则返回空列表
只获取新出现的元素(即只从当前时刻开始获取流中新出现的元素,换句话说我们要“监听”新元素,不要历史的)
格式:XREAD BLOCK ms STREAMS stream1 stream2 stream3 ... $ $ $ ...
注意:就是把ID换成了特殊符号 $,这样XREAD命令就会只获取给定流在命令执行之后新出现的元素
例如:redis> XREAD BLOCK 10000000 STREAMS bs1 $
注释:执行命令后,本客户端将进入阻塞状态,直到10000000ms内有新元素
1) 1) "bs1" // 下面的元素来自流 bs1
2) 1) 1) 1300000000000-0 // 第一个元素的ID
2) 1) "k1"
2) "v1"
下篇我们讲解 消费者组的概念 redis 流 stream的使用总结 - 消费者组