Apache Kafka设计理念探究

动机

创造一个分布式的实时流处理平台,也正是因为这个原因,Kafka选择了将日志分区和消费者群组模型。

持久化

日志的持久化依赖于文件系统,而文件系统的处理速度,在往常的观念里,应该是相当慢的。但是依赖于pagecache-centric design,文件系统的持久化获得了极大的提升。并且Kafka的日志是顺序读写,对于磁盘的定位速度也远远大于随机读写的速度,同样也因为如此,对于传统的AMQP消息系统使用B树实现queue的持久化,也是因为忽略了磁盘的随机读写会很慢,通过日志的方式则不会block写和读,也可以做到O(1)的读写效率(从日志最后读)。

效率

影响消息系统处理效率的主要有两个因素:

太多小的IO操作

过多的字节级复制

对于太多小的IO操作,Kafka会把一定时间内的消息先聚合内存中(“message set”),再一起写入,而不是来一条消息写一次日志。

对于过多的字节级复制,Kafka选择消费者,生产者和broker共享同一套二进制消息格式,使得操作系统可以直接将文件丢入network而不需要buffer。(zero-copy optimization,在具体的实现则是Linux中的sendfile system call方法)

此外,Kafka也提供了GZIP, Snappy and LZ4等协议压缩数据。

生产者

Kafka的生产者模型选择了生产者将数据直接发送给Topic的Master,而不是像Rabbit MQ一样需要路由(为了实现这,Kafka借助了Zookeeper,并且将元数据存储在Zookeeper之上)。除了此,Kafka将负载均衡的任务交给了客户端,客户端可以选择将消息发送到Topic中具体的哪个partition上。对于一些轻一致性,追求效率的场景,Kafka提供了异步发送的机制。

基于pull的拉取数据

Kafka没有选择和AMQP消息系统一样,由消息系统将队列里的消息推送给消费者,而是让消费者自己将Kafka的数据根据offset拉下来。相对于push的方式,Kafka认为pull会给与消费者更大的自由权,这样消费者也可以从任意的offset开始消费(自然也方便失败重试),也无需担心数据会遗漏丢失(只要消息不过期)。Kafka会使用长连接池阻塞的方式,来解决消息未到时消费者连接问题。Kafka也会保存每个消费的消费过的offset元数据,以此来提高消费者的效率。

消息唯一性保证

Kafka提供了三种消息确认机制:

At most once—Messages may be lost but are never redelivered.

At least once—Messages are never lost but may be redelivered.

Exactly once—this is what people actually want, each message is delivered once and only once.

Kafka在0.11.0.0开始通过给生产者的每条消息赋予全局ID,来保证消息不会被重复发送。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180826G1C2XP00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券