00:00
各位同学大家好,接下来为大家介绍一种新的数据类型ready new stream好。老规矩。老思路,还是同样的味道,还是熟悉的配方学习方法。怎么来的?解决一些什么问题?我们为什么现在随着业务和企业需求的发展要学习它,之前有没有来吧,同学们,第一点咱们先说好,这个是red stream。我们大家在学JAVA8,宋永康老师给大家介绍过JAVA8的新特性,也介绍一个东西,JAVA8的新特性。留这个stream Java的那个JAVA8的那个stream和我们这个STREAM2回事,几乎没有一毛钱关系。OK,那杨哥痛快点,能不能一句话给我讲明白,这货是什么东东,说人话。在我们在这儿啊,这个stream就是版本的MQ,俗称消息中间键。
01:04
版的消息中间键OK,好,那么同学们听我说一下这些爱恨情仇。来龙去脉,首先熟悉杨格风格的都强调过一句话,天上飞的理念必然会有落地的实现,对吧?那在于我们Java中间键里面的话,那么对于我们的。MQ的落地时间,卡夫卡大名鼎鼎,那么OK,那么还有什么?等等等等,不一而足。对于我们现在的Java意义中间建系统而言,谁都是想既要保证自己的特色和存在,还要去抢别人的地盘,一句话中间键是不是也比较卷呢,对吧?那这个时候呢,我们大家都清楚,第一个对于KV建支队。分布式内存red江山稳固,那么他这个时候呢,他就动了一点歪心思,我能不能把手呢,伸的更长一点,哎,比如说。
02:09
对吧,梦想是要有的,万一实现了呢,我能不能把MQ给干掉,那这个时候我们的ready从一出娘胎啊,1.0版的时候,它基本上支持MQ对应的处理模型。那你说没有啊,杨哥,我从来没用过啊,之前大家用的是我们最经典的有个数据类型,是不是有一个东东叫list。OK,那么大家清楚,对于我们的消息中间键而言,每一条记录。每一个数据。每一个阶算戳二就是一个消息,那假设我们能实现啊,比如说往这一头进,往这一头戳,先进先戳,那假设啊,同学们,这是消息一,这是消息二,这是消息三,这是消息N啊,那假设啊,这是一,这是二,这是三,这是N,请告诉我,如果可以往一头进一头戳,先到先得,来一个我处理一个,来一个我处理一个,放在同样的一个数据容器模型里面,从Java的角度而言,我们在学多线程,是不是学过一个生产者消费者模式,生产一个消费一个,生产一个消费一个,那么在也动点小心思啊,我能不能有一种抽象的模型。
03:38
也能够完成这样强大的功能,然后给他搞定呢,那么这样的话呢,诶,我如果red能够把消息中心建的市场份额也给他抢过来,那我是不是更加稳固,哎,所以说现在干嘛卷的是无边无际,中间界的框架也在卷,那么好,那杨哥你现在说这个模型red它支持吗?100%支持,下面请在讲介绍stream之前,咱们先来看一个。
04:03
对于这个模型,我们可以用什么我们的消息队列list这个数据结构来实现,何以见得?那么同学们,前面我们学过list l push list112345,兄弟们,没有问题吧?L,然后LIST1,零到负一,那么弟兄们,那么这个时候是不是最顶头的是一,相当于这个,那假设你进来的顺序是12345,我现在想出去的顺序处理消费的顺序也是12345,你用队列怎么给模拟?那么是不是用l push给我进,用R破破这个命令例四一每次出一条12345,弟兄们请告诉我是不是你进来的顺序是12345,出去的顺序也是12345,那么这样,如果我们用list。假设你的消息队列极其简单,那么我们是不是可以不用上什么卡夫卡,Rocket MQ和MQ,我们用就能够摆平?OK,那么他本着这么一种思路就往这个方向发展,那么慢慢的呢?
05:16
达成了一个新的数据结构stream,那杨哥我就不明白了,难道自己要跟自己卷?照你这个说法,List已经满足了,怎么进?怎么消费他负二神经病啊,为什么要自己要搞个stream呢?那么下面来吧。介绍完这些知识以后,我们来看看red5.0之前的痛点。首先red消息队列一般有两个方案啊,在red,注意我说的很清楚啊,是red消队列啊,对于这种数据,第一种用list实现消息队列,说白了是不是就是点对点一进一出,一进一出,那么大家请看它的模型啊,按照我们刚才所讲的,是不是用l push直接进来,R破弹出去,那是不是就是一进一出,12345ABCDE。
06:11
左边的生产者,右边的消费者,那么对于这样一种情况,是不是可以用作异步队列来进行处理,刚才敲过了,不再敲好,这不挺好好的吗?但是不好意思再来后面啊,我们在这儿。会学一张叫register,发布和订阅,俗称PU布和萨布,因为对于这个消息队列而言,它需要有很多东西。最经典的两个模型,点对点。第二个一对多是不是叫广播,那么对于我们的list而言,它支持的是点对点,但是对于一对多种情况,它就有点力不从心,所以我们又来了,我们的什么PU和sub来,同学们是不是就是一个消息过来,多个消费者可以处理,有点像上硅谷的。
07:03
微信公众号上,硅谷有且仅有一个发布了一个微信朋友圈最新的微信公众号,那么请问订阅的消费者是不是都可以获得,但是这是red层面可以实现的。对于我们的消息,它有一个缺点,叫一无法持久化,第二个red网络断开淡季以后,这些消息是不是就会被丢弃?因为他们没有持久化,甚至也没有A签收机制来保证。所以如果一个消费者都没有,那么消息就会被丢弃了,所以说呢,他从理论上的数据模型上它是支撑的,但是对于落地的实现是个半成品,所以。我们简单的可以用red list结构来实现,稍微复杂点的用pop sub。但是它还是不好,那么基于此,Red呢,野心很大,就想着那么我们结合上面的痛点,我自己改正,从list到发布订阅,再到我的red的新的数据结构,Red版的消息中间建stream,希望能够抢夺进一步的市场份额,那么切记。
08:16
Stream这个数据结构是从5.0以后就有了,并不是七的新特性,只不过现在大家也觉得,如果我能用能干的事,能不能少上一个中间见,OK,这个呢?仁者见仁,智者见智,两种,第一种,一个系统我尽量少引入一些中间见,我能用red同时支撑。内存和那么Q我就不要再引入下面这三个重量级的,那么对于小产中产也是可以,但是对于大厂呢,有第二种思路,对不起,专业的人做专业的事,你red给我好端端的去做,内存,数据库,消息中间键,还有他们来转。不管你如何升级,我们用所以两种方法,我们供大家参考,那么一句话,所有的red的stream流就是red版的,那么Q消息中间键加阻塞队列,它把它们两个整合了以后,又加上一些新的特性,持久化签收等等,好,那么它能干些什么呢?
09:20
对于我们的red stream流,它可以实现消息的队列含我们的阻塞队列,对吧,功能很强大,支持消息的持久化,自动生成全局ID,就是message消息ID,支持A的确认消息,那你看几乎是就把消息中间键的内容全拿回来了,哎,所以呢,现在框架也比较绝好,那么接下来我们来说一下它的底层结构和原理,那么stream的结构请同学们漏眼,就上面这个先给大家五秒钟自行查看一下,同学们,我们先不说别的啊。它的架构图官方的就长这样,那它什么意思呢?首先write the stream是一个消息列表,它会将所有加入消息都干嘛串起来啊,不管你往哪边进都一样啊,每一个消息都有个唯一的ID和对应内容,那么相当于请看第一个叫message content,俗称消息内容,每一个消息就像在一个管道里面,在一个队列里面,那么这假设这从一到16是不是有16条消息,每一条消息?
10:27
这写着hello北京,这写着hello上海,这写着hello上硅谷,每一个消息就是一个message content,这第一步,第二步请看,叫consumer group,那么既然产生消息了,说明有消息的生产者,必然会有什么是不是消息的消费者,那么挨个挨个的一个一个的消息消费者的话呢,我们可以把它。打个包,传个组,建个群,所以说建立一个消费者group消费组,那么他通过后面这个命令我们会说,啊,现在你先不要管,那么同一个消费组可以有多个消费者,相当于就是什么广播上硅谷新发布了一套视频,那么订阅的人只要是同一个消费组,比如说上硅谷粉丝群零一,放上规谷粉丝群零二,那么所有的在这个群里面的消费者,在这一个消费组里面的消费者都可以获得,都可以读好,下面再来看last delivered。
11:24
Deliver ID,这个叫什么分发,意思就是邮标,相当于说啊,我们呢,来进行消费读取的时候,每一个消费组都会有一个,只要新发出来,新生产出来的消息被这个消费组截获读取了,那么最新的指针就会往后1亿个,哎,说难听点就是读完一个走一个,读完一个走一步,指针会往前移,就是我们的什么有必要表示哪一些是最新的消息,哪一些是未读的消息,好第四一个概念,消费者,那么消费者自然而然是包含在消费组当中,这个没问题吧,好,那么同学们。
12:02
这些message content,说白了就是消息的生产者生产的消息,那么下面二、三、四这个概念就是消费组里面的消费者要来消费,读取这些信息,每读一条就会用游标往前走一步,标识我读过这条消息了,好,那么下面第五个概念叫pending ids,这什么意思呢?他这个意思是一个消费组里面有一、二、三三个消费者,那么每一个消费者读了以后。如果你是读完以后签收。已读已确认,这是叫A,但是另外一种情况就是你读了,但是你并没有给我确认,没有发布A,这个就叫pending ideas,就是消费者一他读过这条消息了,但是没有发过确认,Pending单词意思什么呀,是不是叫悬而未决待定的,所以呢,他这个意思就是JD,消费者呢,他都会有一个状态变量啊。
13:00
他记录当前被消费,注意当前消费读过了但是没有签收的消息ID。我去到这个。菜鸟驿站,我看到我的快递了啊,已经放在你这儿,但是我没有签收,拿回家听懂了吧,就是只读,但是没确认。如果客户端没有这个A,那么这个变量里面的ID就会越来越多,就是你读的越来越多,但是你没确认的也越来越多,一旦某个消息被A了,那么这个判定ID,那么它呢就会减少,OK那么所以说记录了当前已经被客户端读取的消息还是没有被ACK的,我们用它来保证我们的消息不会丢,到底哪些是已读与确认,哪些是已读未确认,OK,那么它呢,用来确保客户端至少要消费的消息一次,而不会在网络中莫名其妙的丢了啊,我们最终会来拿这个单词来说话,所以这个就是red stream,它的消息流底层的原理和结构。列表存储全部的消息,消费者里面的消费者来消费,那么每消费了一条指针,往后走一步。
14:08
然后如果是已读已确认发了AC的,没有这个事儿,如果已读没有发A未确认的,会有一个待定的一个处理消息,OK,好,那么同学们,这个就是它的底层原理和。底层结构,那么它的基础命令有哪一些呢?来,首先队列相关指令,就是说你可以把它理解为就是怎么产生ID 123456~16,相当于消息和消息内容的生产者,那么它一生产以后就放在队列里面,来,同学们请看。这待会我们会一个个的过啊叫xad,那么X叫stream啊有这些,那么在这儿给大家呢,老规矩整理好,有生产B呢,会有消费N多个消费者,我们把它汇到一个消费组里面,那么消费组那么当然是不是来读取这些消息,好这是我们第二组,第三一个有一些特殊符号,比如说小。
15:06
井号。小于加号,大于最小和最大可能出现的消息ID,那么你可以把它理解为MYSQL里面的between and,好,那么下面还有什么?Dollar大于新,那么分别是些什么呢?那么假设这个呢,就是指消费最新的消息,那么就是要比当前系统里面消息ID所产生的消息时间更大的,而这个相当于说往前走一步,OK,相当于说会更新消费者最后的消息ID。新是用于。Xad命令代表这个消息全部让系统上传我们这儿过一遍。懵逼的同学,没关系,接下来理论完成是不是代码实操?兄弟们,下半场马上开始,不要走开,下面这些案例和操作挨个挨个给大家过。
我来说两句