消息队列学习笔记

kafka

设计目标

  • 以时间复杂度为O(1)的方式提供消息持久化能力以及读取能力,即使对TB级以上数据也能保证常数时间复杂度的访问性能。
  • 高吞吐率。即使在非常廉价的商用机器上也能做到单机支持每秒100K条以上消息的传输。
  • 支持Kafka Server间的消息分区,及分布式消费,同时保证每个Partition内的消息顺序传输。
  • 同时支持离线数据处理和实时数据处理(通过消费组实现)。
  • Scale out:支持在线水平扩展。

相关知识点

  • Kafka以集群的方式运行,可以由一个或多个服务组成,每个服务叫做一个broker.

  • 一个topic是对一组消息的归纳。对每个topic,Kafka 对它的日志进行了分区,分为多个partition。

  • 每个分区在Kafka集群的若干服务中都有副本,这样这些持有副本的服务可以共同处理数据和请求,副本数量是可以配置的。副本使Kafka具备了容错能力。

  • 每个分区都由一个服务器作为“leader”,零或若干服务器作为“followers”,leader负责处理消息的读和写,followers则去复制leader.如果leader down了,followers中的一台则会自动成为leader(通过zk实现)。

  • Producer将消息发布到它指定的topic中,并负责决定发布到哪个分区。通常简单的由负载均衡机制随机选择分区。

  • 发布消息通常有两种模式:队列模式(queuing)和发布-订阅模式(publish-subscribe)。
    队列模式一堆消费者消费队列中消息,只要有一个消费者消费了消息,该消息就算被消费完毕。
    发布订阅模式,一个消息会被所有消费者订阅,被所有消费者消费一遍,不过实际应用中,一般都是订阅组,一个消息发给多个订阅组,每个订阅组中的一个消费者去处理一条消息。

  • Kafka只能保证一个分区之内消息的有序性,在不同的分区之间是不可以的,这已经可以满足大部分应用的需求。如果需要topic中所有消息的有序性,那就只能让这个topic只有一个分区,当然也就只有一个consumer组消费它。

  • Kafka集群包含一个或多个服务器,这种服务器被称为broker。

  • 对于传统的message queue而言,一般会删除已经被消费的消息,而Kafka集群会保留所有的消息,无论其被消费与否。但是在为了防止磁盘被耗尽,Kafka提供两种策略删除旧数据,一是基于时间,二是基于Partition文件大小。

高吞吐率保证

  • 这里写图片描述
    对于一条消息会被append到某一Partition中,顺序写磁盘,效率非常高(经验证,顺序写磁盘效率比随机写内存还要高,这是Kafka高吞吐率的一个很重要的保证)。Kafka在底层摒弃了Java堆缓存机制,采用了操作系统级别的页缓存,同时将随机写操作改为顺序写,再结合Zero-Copy的特性极大地改善了IO性能。

  • 当前消费消息的offset由Consumer控制。正常情况下Consumer会在消费完一条消息后递增该offset。当然,Consumer也可将offset设成一个较小的值,重新消费一些消息。因为offet由Consumer控制,所以Kafka broker是无状态的,它不需要标记哪些消息被哪些消费过,也不需要通过broker去保证同一个Consumer Group只有一个Consumer能消费某一条消息,因此也就不需要锁机制,这也为Kafka的高吞吐率提供了有力保障。

  • 如果Partition机制设置合理,所有消息可以均匀分布到不同的Partition里,这样就实现了负载均衡。

消息重复相关

写消息

  • 默认情况一条消息从Producer到broker是确保了At least once,可通过设置Producer异步发送实现At most once)

读消息

  • 读完消息先commit再处理消息。这种模式下,如果Consumer在commit后还没来得及处理消息就crash了,下次重新开始工作后就无法读到刚刚已提交而未处理的消息,这就对应于At most once。
  • 读完消息先处理再commit。这种模式下,如果在处理完消息之后commit之前Consumer crash了,下次重新开始工作时还会处理刚刚未commit的消息,实际上该消息已经被处理过了。这就对应于At least once。
  • Kafka默认保证At least once,并且允许通过设置Producer异步提交来实现At most once。

高可用性

  • Producer在发布消息到某个Partition时,先通过ZooKeeper找到该Partition的Leader,Leader会将该消息写入其本地Log。每个Follower都从Leader pull数据,为了提高性能,每个Follower在接收到数据后就立马向Leader发送ACK,而非等到数据写入Log中。因此,对于已经commit的消息,Kafka只能保证它被存于多个Replica的内存中,而不能保证它们被持久化到磁盘中,也就不能完全保证异常发生后该条消息一定能被Consumer消费。但考虑到这种场景非常少见,可以认为这种方式在性能和数据持久化上做了一个比较好的平衡。在将来的版本中,Kafka会考虑提供更高的持久性。
  • Leader会跟踪与其保持同步的Replica列表,该列表称为ISR(即in-sync Replica)。如果一个Follower宕机,或者落后太多,Leader将把它从ISR中移除。
  • Kafka只解决fail/recover,不处理“Byzantine”(“拜占庭”)问题。一条消息只有被ISR里的所有Follower都从Leader复制过去才会被认为已提交。

使用原因

  • 解耦
  • 冗余
    许多消息队列所采用的”插入-获取-删除”范式中,在把一个消息从队列中删除之前,需要你的处理系统明确的指出该消息已经被处理完毕,从而确保你的数据被安全的保存直到你使用完毕。
  • 扩展性
    增大消息入队和处理的频率是很容易的
  • 灵活性 & 峰值处理能力
  • 可恢复性
    即消费者挂了,恢复后继续消费。
  • 顺序保证
    kafka保证partition内有序。
  • 异步通信
  • 高吞吐率

其它

  • push模式很难适应消费速率不同的消费者, push模式的目标是尽可能以最快速度传递消息。对于Kafka而言,pull模式更合适。pull模式可简化broker的设计,Consumer可自主控制消费消息的速率,同时Consumer可以自己控制消费方式——即可批量消费也可逐条消费。

RabbitMQ

ZeroMQ

ActiveMQ

Redis

参考

http://www.infoq.com/cn/articles/kafka-analysis-part-1/
http://www.infoq.com/cn/articles/kafka-analysis-part-2/

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值