Java中高级核心知识全面解析(5),还在找TCP-IP的相关文章

使用示例:

# *号表示服务器自动生成ID,后面顺序跟着一堆key/value 
127.0.0.1:6379> xadd codehole * name laoqian age 30 # 名字叫laoqian,年龄301527849609889-0 # 生成的消息ID 
127.0.0.1:6379> xadd codehole * name xiaoyu age 29 
1527849629172-0 
127.0.0.1:6379> xadd codehole * name xiaoqian age 1 
1527849637634-0 
127.0.0.1:6379> xlen codehole 
(integer) 3
127.0.0.1:6379> xrange codehole - + # -表示最小值, +表示最大值 
1) 1) 1527849609889-0 
	2) 1) "name" 
	2) "laoqian" 
	3) "age" 
	4) "30" 
2) 1) 1527849629172-0 
	2) 1) "name" 
	2) "xiaoyu" 
	3) "age" 
	4) "29" 
3) 1) 1527849637634-0 
	2) 1) "name" 
	2) "xiaoqian" 
	3) "age" 
	4) "1" 
127.0.0.1:6379> xrange codehole 1527849629172-0 + # 指定最小消息ID的列表 
1) 1) 1527849629172-0 
	2) 1) "name" 
	2) "xiaoyu" 
	3) "age" 
	4) "29" 
2) 1) 1527849637634-0 
	2) 1) "name" 
	2) "xiaoqian" 
	3) "age" 
	4) "1" 
127.0.0.1:6379> xrange codehole - 1527849629172-0 # 指定最大消息ID的列表 
1) 1) 1527849609889-0 
	2) 1) "name" 
	2) "laoqian" 
	3) "age" 
	4) "30" 
2) 1) 1527849629172-0 
	2) 1) "name" 
	2) "xiaoyu" 
	3) "age" 
	4) "29" 
127.0.0.1:6379> xdel codehole 1527849609889-0 
(integer) 
1 127.0.0.1:6379> xlen codehole # 长度不受影响 
(integer) 3 
127.0.0.1:6379> xrange codehole - + # 被删除的消息没了 
1) 1) 1527849629172-0 
	2) 1) "name" 
	2) "xiaoyu" 
	3) "age" 
	4) "29" 
2) 1) 1527849637634-0 
	2) 1) "name" 
	2) "xiaoqian" 
	3) "age" 
	4) "1" 
127.0.0.1:6379> del codehole # 删除整个Stream 
(integer) 1

3)独立消费示例

我们可以在不定义消费组的情况下进行 Stream 消息的 独立消费,当 Stream 没有新消息时,甚至可以阻塞等待。Redis 设计了一个单独的消费指令 xread ,可以将 Stream 当成普通的消息队列(list)来使用。使用 xread 时,我们可以完全忽略 消费组(Consumer Group) 的存在,就好比 Stream 就是一个普通的列表(list):

# 从Stream头部读取两条消息 
127.0.0.1:6379> xread count 2 streams codehole 0-0 
1) 1) "codehole" 
	2) 1) 1) 1527851486781-0 
		2) 1) "name" 
		2) "laoqian" 
		3) "age" 
		4) "30" 
	2) 1) 1527851493405-0 
		2) 1) "name" 
		2) "yurui" 
		3) "age" 
		4) "29" 
# 从Stream尾部读取一条消息,毫无疑问,这里不会返回任何消息 
127.0.0.1:6379> xread count 1 streams codehole $ (nil) 
# 从尾部阻塞等待新消息到来,下面的指令会堵住,直到新消息到来 
127.0.0.1:6379> xread block 0 count 1 streams codehole $ 
# 我们从新打开一个窗口,在这个窗口往Stream里塞消息 
127.0.0.1:6379> xadd codehole * name youming age 60 
1527852774092-0 
# 再切换到前面的窗口,我们可以看到阻塞解除了,返回了新的消息内容 
# 而且还显示了一个等待时间,这里我们等待了93s 
127.0.0.1:6379> xread block 0 count 1 streams codehole $ 
1) 1) "codehole" 
	2) 1) 1) 1527852774092-0 
		2) 1) "name" 
		2) "youming" 
		3) "age" 
		4) "60" 
(93.11s)

客户端如果想要使用 xread 进行 顺序消费,一定要 记住当前消费 到哪里了,也就是返回的消息 ID。下次继续调用 xread 时,将上次返回的最后一个消息 ID 作为参数传递进去,就可以继续消费后续的消息。

block 0 表示永远阻塞,直到消息到来, block 1000 表示阻塞 1s ,如果 1s 内没有任何消息到来,就返回 nil

127.0.0.1:6379> xread block 1000 count 1 streams codehole $ 
(nil) 
(1.07s)

4)创建消费者示例

Stream 通过 xgroup create 指令创建消费组(Consumer Group),需要传递起始消息 ID 参数用来初始化 last_delivered_id 变量:

127.0.0.1:6379> xgroup create codehole cg1 0-0 # 表示从头开始消费 
OK
# $表示从尾部开始消费,只接受新消息,当前Stream消息会全部忽略 
127.0.0.1:6379> xgroup create codehole cg2 $ 
OK
127.0.0.1:6379> xinfo codehole # 获取Stream信息 
1) length 
2) (integer) 3 # 共3个消息 
3) radix-tree-keys 
4) (integer) 1 
5) radix-tree-nodes 
6) (integer) 2 
7) groups 
8) (integer) 2 # 两个消费组 
9) first-entry # 第一个消息 
10) 1) 1527851486781-0 
	2) 1) "name" 
	2) "laoqian" 
	3) "age" 
	4) "30" 
11) last-entry # 最后一个消息 
12) 1) 1527851498956-0 
	2) 1) "name" 
	2) "xiaoqian" 
	3) "age" 
	4) "1" 
127.0.0.1:6379> xinfo groups codehole # 获取Stream的消费组信息 
1) 1) name 
	2) "cg1" 
	3) consumers 
	4) (integer) 0 # 该消费组还没有消费者 
	5) pending 
	6) (integer) 0 # 该消费组没有正在处理的消息 
2) 1) name 
	2) "cg2" 
	3) consumers # 该消费组还没有消费者 
	4) (integer) 0 
	5) pending 
	6) (integer) 0 # 该消费组没有正在处理的消息

5)组内消费示例

Stream 提供了xreadgroup 指令可以进行消费组的组内消费,需要提供 消费组名称、消费者名称和起始消息 ID。它同 xread 一样,也可以阻塞等待新消息。读到新消息后,对应的消息 ID 就会进入消费者的 PEL (正在处理的消息) 结构里,客户端处理完毕后使用 xack 指令 通知服务器,本条消息已经处理完毕,该消息 ID 就会从 PEL 中移除,下面是示例:

# >号表示从当前消费组的last_delivered_id后面开始读 
# 每当消费者读取一条消息,last_delivered_id变量就会前进 
127.0.0.1:6379> xreadgroup GROUP cg1 c1 count 1 streams codehole > 
1) 1) "codehole" 
	2) 1) 1) 1527851486781-0 
		2) 1) "name" 
		2) "laoqian" 
		3) "age" 
		4) "30" 
127.0.0.1:6379> xreadgroup GROUP cg1 c1 count 1 streams codehole > 
1) 1) "codehole" 
	2) 1) 1) 1527851493405-0
		2) 1) "name" 
		2) "yurui" 
		3) "age" 
		4) "29" 
127.0.0.1:6379> xreadgroup GROUP cg1 c1 count 2 streams codehole > 
1) 1) "codehole" 
	2) 1) 1) 1527851498956-0 
		2) 1) "name" 
		2) "xiaoqian" 
		3) "age" 
		4) "1" 
	2) 1) 1527852774092-0 
		2) 1) "name" 
		2) "youming" 
		3) "age" 
		4) "60" 
		# 再继续读取,就没有新消息了 
127.0.0.1:6379> xreadgroup GROUP cg1 c1 count 1 streams codehole > (nil) 
# 那就阻塞等待吧 
127.0.0.1:6379> xreadgroup GROUP cg1 c1 block 0 count 1 streams codehole > 
# 开启另一个窗口,往里塞消息 
127.0.0.1:6379> xadd codehole * name lanying age 61 
1527854062442-0 
# 回到前一个窗口,发现阻塞解除,收到新消息了 
127.0.0.1:6379> xreadgroup GROUP cg1 c1 block 0 count 1 streams codehole > 
1) 1) "codehole" 
	2) 1) 1) 1527854062442-0 
		2) 1) "name" 
		2) "lanying" 
		3) "age" 
		4) "61" 
(36.54s) 
127.0.0.1:6379> xinfo groups codehole # 观察消费组信息 
1) 1) name 
	2) "cg1" 
	3) consumers 
	4) (integer) 1 # 一个消费者 
	5) pending 
	6) (integer) 5 # 共5条正在处理的信息还有没有ack 
2) 1) name 
	2) "cg2" 
	3) consumers 
	4) (integer) 0 # 消费组cg2没有任何变化,因为前面我们一直在操纵cg1 
	5) pending 
	6) (integer) 0 # 如果同一个消费组有多个消费者,我们可以通过xinfo consumers指令观察每个消费者的状态 
127.0.0.1:6379> xinfo consumers codehole cg1 # 目前还有1个消费者 
1) 1) name 
	2) "c1" 
	3) pending 
	4) (integer) 5 # 共5条待处理消息 
	5) idle 
	6) (integer) 418715 # 空闲了多长时间ms没有读取消息了 
# 接下来我们ack一条消息 
127.0.0.1:6379> xack codehole cg1 1527851486781-0 
(integer) 1 
127.0.0.1:6379> xinfo consumers codehole cg1
1) 1) name 
	2) "c1" 
	3) pending 
	4) (integer) 4 # 变成了55) idle 
	6) (integer) 668504 
# 下面ack所有消息 
127.0.0.1:6379> xack codehole cg1 1527851493405-0 1527851498956-0 1527852774092- 0 1527854062442-0 
(integer) 4 
127.0.0.1:6379> xinfo consumers codehole cg1 
1) 1) name 
	2) "c1" 
	3) pending 
	4) (integer) 0 # pel空了 
	5) idle 
	6) (integer) 745505

6)QA 1:Stream 消息太多怎么办? | Stream 的上限

很容易想到,要是消息积累太多,Stream 的链表岂不是很长,内容会不会爆掉就是个问题了。 xdel指令又不会删除消息,它只是给消息做了个标志位。

Redis 自然考虑到了这一点,所以它提供了一个定长 Stream 功能。在 xadd 的指令提供一个定长长度 maxlen ,就可以将老的消息干掉,确保最多不超过指定长度,使用起来也很简单:

> XADD mystream MAXLEN 2 * value 1 
1526654998691-0 
> XADD mystream MAXLEN 2 * value 2 
1526654999635-0 
> XADD mystream MAXLEN 2 * value 3 
1526655000369-0 
> XLEN mystream 


### 最后

> 由于细节内容实在太多了,为了不影响文章的观赏性,只截出了一部分知识点大致的介绍一下,每个小节点里面都有更细化的内容!

![](https://img-blog.csdnimg.cn/img_convert/536670449d83818b4dd6a3499f338731.png)

**需要这份文档的朋友可以帮忙点个赞还有小编准备的一份Java进阶学习路线图(Xmind)以及来年金三银四必备的一份《Java面试必备指南》**

##### **[CodeChina开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频】](https://codechina.csdn.net/m0_60958482/java-p7)**

只截出了一部分知识点大致的介绍一下,每个小节点里面都有更细化的内容!

[外链图片转存中...(img-L4iA6it0-1630821044033)]

**需要这份文档的朋友可以帮忙点个赞还有小编准备的一份Java进阶学习路线图(Xmind)以及来年金三银四必备的一份《Java面试必备指南》**

##### **[CodeChina开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频】](https://codechina.csdn.net/m0_60958482/java-p7)**

![](https://img-blog.csdnimg.cn/img_convert/2bc22a0a1dd125e183f8a9ca0a141829.png)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值