在学习之前先来看以下场景:
案例一:系统崩溃
假如此时负责记录数据的数据库宕机了,搜索行为的记录就迟迟不能写入数据,所有的操作都不会动了
案例二: 服务能力有限
当大量请求来了之后会使服务器压力变大,有可能宕机
案例三: 链路耗时长尾
用户需要苦苦等待30s去等待通知商家,但实际上并不需要
案例四:日志存储
假如有服务坏掉了,本地日志都没了,更别说去看问题出在哪里了!
因此,我们可以使用消息队列来解决上面的问题
消息队列:本质上是一个队列,但是这个队列需要支持高吞吐、高并发、高可用
消息队列对比
kafka
使用kafka
kafka中的基本概念
Offset:消息在partition内的相对位置信息,可以理解为唯一ID,在partition内部严格递增。
replica:分片的副本,分布在不同的机器上,可用来容灾,Leader对外服务,Follower异步去拉取leader的数据进行一个同步,如果leader挂掉了,可以将Follower提升leader再对外进行服务
ISR:意思是同步中的副本,对于Folower来说,始终和leader是有一定差距的,但当这个差距比以较小的时候,我们就可以将这个follower副本加入到isr中,不在iSR中的副本是不允许提升成leader的
数据复制
每一个broker代表一个kafka的节点,最终组成一个集群,topic1有两个分片,每个分片都是三副本,中间有一个broker扮演了controller角色,负责对副本和broker进行分配。
提高kafka吞吐能力和稳定性的几个手段
producer
批量发送+数据压缩
broker
可以采用顺序写的方式来加快速度
把消息写入broker之后,如果要找到一条消息的话,细节?
broker零拷贝
传统数据的读取
零拷贝的思想
消息的接收
采用这种方法每个consumer都已经对应好了具体的分区,所以他的速度就会很快,但是当一个consumer宕机之后就会引起对应的partition无法正常消费
所以就提出了高级的消费方式: 加入一个协调器
举个例子来说。如果我们对一个机器重启,我们会关团一个brokr,此时如果该broker 存在副本,将发生leader切换,切换到其他节点上面并在ISR对中的Follower副本 而此时,因为数据在不断的写入,对于刚刚关闭重启的Broker来说,和新Leader之间一定会存在数据的滞后,此时这个Broker会追赶数据,重新加入到SR当中 当数据追赶完成之后,我们需要回切leader,,这一步叫做prefer leader,,这一步的目的是为了避免,在一个集群长期运行后,所有的leader都分布在少数节点上,导致数据的不均衡 通过上面的一个过程分折,我们可以发现对于一个broker的重启来说,需要进行数据复制,所和以划间成本会比较大、,比加一个节点重启需要10分钟,一个集期有100个节点,如果升级,要1000分钟,这样的时间成本是非常大的。
负载不均衡
数据的复制会引起broker1的IO升高,本来就已经很高了。
kafka问题总结
rocketMQ
使用场景
例如,针对电商业务线,其业务涉及广泛,如注册、订单、库存、物流等;同时,也会涉及许多业务峰值时刻,如秒杀活动、周年庆、定期特惠等
基本概念
架构
broker节点有master和slave的概念,
nameserver为鸡群提供轻量级服务发现和路由
存储模型
对于一个broker来说所有的消息会append到一个commitlog上面上面,然后按照不同的queue,重新dispatch上面,这样consumer就可以按照Queue进行拉取消费。但需要注意的是,这里的ConsumerOueue所存储的并不是真实的数据,真实的数据其实只存在Comitlog中,这里存的仅仅是这个queue所有消息在Ccomitilog 上面的位置,相当于是这个queue的一个密集索引
高级特性
事务
指Producer端消息发送事件和本地事务事件,同时成功或同时失败