消息中间件总结

Kafka

结构与存储

kafka使用topic来标识消息队列,生产者往指定的topic中写消息,消费者从指定的topic中读取消息。kafka集群由多个server组成,每个server也称为broker, 为了使得topic在broker中更好的扩展,我们将topic分为多个partition, partition可以分布在不同的broker上,每个partion(目录)相当于一个巨型文件被平均分配到多个大小相等segment(段)数据文件中。segment file包含两个文件:index file 和 data file,此2个文件一一对应,成对出现,后缀”.index”和“.log”分别表示为segment索引文件、数据文件。

其中.index索引文件存储大量元数据,.log数据文件存储大量消息,索引文件中元数据指向对应数据文件中message的物理偏移地址offset。当有新的消息产生时,即在文件后append,当消息消费后并不是立刻删除,而是kafka另起一个线程,定期检查,删除掉已消费的的消息(consumer端会记录每个partition当前消费的offset)。他们两个是一一对应的,对应关系如下 :

image_1c448a5mqdom1rnk1ejcakj1c3k1g.png-106.1kB

并且每个partition会有一个leader和多个follower(也可能没有),leader负责对消息的读写,而follower只负责与leader的同步,当leader挂掉之后再从follower中选举一个成为leader。

partition的分配

  1. 将所有Broker(假设共n个Broker)和待分配的Partition排序
  2. 将第i个Partition分配到第(i mod n)个Broker上 (这个就是leader)
  3. 将第i个Partition的第j个Replica分配到第((i + j) mode n)个Broker上

leader容灾

controller会在Zookeeper的/brokers/ids节点上注册Watch,一旦有broker宕机,它就能知道。当broker宕机后,controller就会给受到影响的partition选出新leader。controller从zk的/brokers/topics/[topic]/partitions/[partition]/state中,读取对应partition的ISR(in-sync replica已同步的副本)列表,选一个出来做leader。
选出leader后,更新zk,然后发送LeaderAndISRRequest给受影响的broker,让它们改变知道这事。为什么这里不是使用zk通知,而是直接给broker发送rpc请求,我的理解可能是这样做zk有性能问题吧。

如果ISR列表是空,那么会根据配置,随便选一个replica做leader,或者干脆这个partition就是歇菜。如果ISR列表的有机器,但是也歇菜了,那么还可以等ISR的机器活过来。

注册

kafka的注册中心是由zookeeper来实现的

生产

创建一条记录,记录中一个要指定对应的topic和value,key和partition可选。 先序列化,然后按照topic和partition,放进对应的发送队列中。kafka produce都是批量请求,产生消息后并不会马上传输到消息队列,而是先储存在buffer中,当buffer中的消息数到达一定的量的时候,再一起发送。因此如果宕机,buffer中的数据会丢失,因此存在丢消息的情况。
如果partition没填,那么情况会是这样的:

  1. key有填
    按照key进行哈希,相同key去一个partition。(如果扩展了partition的数量那么就不能保证了)
  2. key没填
    round-robin来选partition

消费

kafka中的消费模式是拉pull魔石,由消费者主导,消费者根据自身的消费情况,去消息队列中拉去消息。订阅topic是以一个消费组来订阅的,一个消费组里面可以有多个消费者。同一个消费组中的两个消费者,不会同时消费一个partition。换句话来说,就是一个partition,只能被消费组里的一个消费者消费,但是可以同时被多个消费组消费。因此,如果消费组内的消费者如果比partition多的话,那么就会有个别消费者一直空闲。

消息投递语义

At most once  

可能会消息丢失,但不会消息重复

先获取数据,再commit offset,最后进行业务处理。
1、生产者生产消息异常,不管,生产下一个消息,消息就丢了
2、消费者处理消息,先更新offset,再做业务处理,做业务处理失败,消费者重启,消息就丢了

At least once

可能会消息重复,但不会消息丢失,是实际中经常选择的一种语义

先获取数据,再进行业务处理,业务处理成功后commit offset。
1、生产者生产消息异常,消息是否成功写入不确定,重做,可能写入重复的消息
2、消费者处理消息,业务处理成功后,更新offset失败,消费者重启的话,会重复消费

Exactly once

既不丢失也不重复消费

在at least once的基础上保证生产者和消费者消息的幂等性

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值