这是我参与「第五届青训营 」伴学笔记创作活动的第 16 天
消息队列
今日学习
- 消息队列的前世今生
- 消息队列-Kafka
- 消息队列-BMQ
- 消息队列-RocketMQ
- 最佳实践
案例一
首先,请求会先到搜索商品这个服务上,并记录下你的搜索行为,然后点击商品的时候,又记录了我们的点击商品,这些数据最终都会通过计算分析,目的是为了下一次给你更准确的信息,这个时候问题来了,如果这个时候,负责记录存储的数据库被一个小哥删库跑路了。我们的所有操作都动不了了,这个时候我们应该怎么办,带着这个问题,我们继续往下看
解决方案
案例二
可以看到,一堆人都发起了订单请求,可是公司给的预算不够,服务器的配置太弱,订单服务只能同事处理10个订单请求。这个时候我们又该怎么办呢。继续往下看
案例三
一通分析,发现,库存服务和订单服务都挺快的,但是最后通知商家这一步咋这么慢,是不是还可以进行优化呀?
案例四
在大家都抢到了自己心仪商品准备睡去的时候,在字节跳动的会议室里传出了悲伤的声音,因为刚刚有服务器坏掉了,我们的本地日志都丢掉了,没有了日志,我们还怎么去修复那些刚刚出现的那些问题,周围一片寂静,突然小张站出来缓缓的说了一句话,众人才露出了微笑准备下班离开,大家能猜到小张到底说的什么吗
消息队列
MQ,指保存信息的一个容器,本质是一个队列。这个队列需要支持高吞吐,高并发,高可用
Kafka
如何使用
第一步:首先需要创建一个Kafka集群,但如果你是在字节工作,恭喜你这一步消息团队的小伙伴已经帮你完成了
第二步:需要在这个集群中创建一个Topic,并且设置好分片数量
第三步:引入对应语言的SDK,配置好集群和Topic等参数,初始化一个生产者,调用Send方法,将你的Hello World发送出去
第四步:引入对应语言的SDK,配置好集群和Topic等参数,初始化一个消费者,调用Poll方法,你将收到你刚刚发送的Hello World
概念
Topic:Kakfa中的逻辑队列,可以理解成每一个不同的业务场景就是一个不同的topic,对于这个业务来说,所有的数据都存储在这个topic中 Cluster:Kafka的物理集群,每个集群中可以新建多个不同的topic Producer:顾名思义,也就是消息的生产端,负责将业务消息发送到Topic当中 Consumer:消息的消费端,负责消费已经发送到topic中的消息 Partition:通常topic会有多个分片,不同分片直接消息是可以并发来处理的,这样提高单个Topic的吞吐
Offset:消息再partition内的相对位置,可以理解为唯一的Id,在partition内严格递增
Replica:分片的副本,分布在不同的机器上,可用来容灾,Leader对外服务,Follower异步去拉取leader的数据进行一个同步,如果leader挂掉了,可以将Follower提升成leader再堆外进行服务 ISR:意思是同步中的副本,对于Follower来说,始终和leader是有一定差距的,但当这个差距比较小的时候,我们就可以将这个follower副本加入到ISR中,不在ISR中的副本是不允许提升成Leader的
帮助提高吞吐量的或者稳定的功能
- Producer 批量发送
- Broker 顺序写
- Consumer Rebalance
重启
如果我们对一个机器进行重启 首先,我们会关闭一个Broker,此时如果该Broker上存在副本的Leader,那么该副本将发生leader切换,切换到其他节点上面并且在ISR中的Follower副本,可以看到图中是切换到了第二个Broker上面 而此时,因为数据在不断的写入,对于刚刚关闭重启的Broker来说,和新Leader之间一定会存在数据的滞后,此时这个Broker会追赶数据,重新加入到ISR当中 当数据追赶完成之后,我们需要回切leader,这一步叫做prefer leader,这一步的目的是为了避免,在一个集群长期运行后,所有的leader都分布在少数节点上,导致数据的不均衡 通过上面的一个流程分析,我们可以发现对于一个Broker的重启来说,需要进行数据复制,所以时间成本会比较大,比如一个节点重启需要10分钟,一个集群有1000个节点,如果该集群需要重启升级,则需要10000分钟,那差不多就是一个星期,这样的时间成本是非常大的。
BMQ
BMQ兼容Kafka协议,存算分离,云原生消息队列,初期定位是承接高吞吐的离线业务场景,逐步替换掉对应的Kafka集群,我们来了解一下BMQ的架构特点
HDFS写文件
先客户端写入前会选择一定数量的DataNode,这个数量是副本数,然后将一个文件写入到这三个节点上,切换到下一个segment之后,又会重新选择三个节点进行写入。这样一来,对于单个副本的所有segment来讲,会随机的分配到分布式文件系统的整个集群中
Broker-写文件流程
数据校验:CRC , 参数是否合法 校验完成后,会把数据放入Buffer中 通过一个异步的Write Thread线程将数据最终写入到底层的存储系统当中 这里有一个地方需要注意一下,就是对于业务的写入来说,可以配置返回方式,可以在写完缓存之后直接返回,另外我也可以数据真正写入存储系统后再返回,对于这两个来说前者损失了数据的可靠性,带来了吞吐性能的优势,因为只写入内存是比较快的,但如果在下一次flush前发生宕机了,这个时候数据就有可能丢失了,后者的话,因为数据已经写入了存储系统,这个时候也不需要担心数据丢失,相应的来说吞吐就会小一些 我们再来看看Thread的具体逻辑,首先会将Buffer中的数据取出来,调用底层写入逻辑,在一定的时间周期上去flush,flush完成后开始建立Index,也就是offset和timestamp对于消息具体位置的映射关系 Index建立好以后,会save一次checkpoint,也就表示,checkpoint后的数据是可以被消费的辣,我们想一下,如果没有checkpoint的情况下会发生什么问题,如果flush完成之后宕机,index还没有建立,这个数据是不应该被消费的 最后当文件到达一定大小之后,需要建立一个新的segment文件来写入
RocketMQ
事务场景
课程个人总结
这几节课程太难了,实践的太少,概念过多,也非常难懂。没有实操非常难理解,同时课程也不容易听到最后
引用