Kafka的可靠性

在使用kafka的时候,我们都知道kafka有很强的可靠性,或者说kafka可以保证消息不丢失。
那它是怎么来保证的呢?
或者返过来思考,在使用kafka的时候什么情况下会丢失消息呢?

从应用kafka的三个角度来理解kafka的可靠性保证

生产者的可靠性

在kafka的producer配置时,我们需要配置一些必要的参数来保证生产端的可靠性

确认机制(request.required.acks)

request.required.acks(下面简写ack),这个参数有三个值,分别是1, 0, -1

  • 1:producer在ISR(先不管是什么,下面有说明)中的leader已成功收到的数据并得到确认后发送下一条message。如果leader宕机了,且producer没有重试机制,则会丢失数据。
  • 0:producer无需等待来自broker的确认而继续发送下一批消息。这种情况下数据传输效率最高,但是数据可靠性确是最低的。
  • -1:producer需要等待ISR中的所有follower都确认接收到数据后才算一次发送完成,可靠性最高,但是传输速率有一定的影响。但是这样也不能保证数据不丢失,比如当ISR中只有leader时,这种场景就变成了acks=1的情况

发送模式 (producer.type)

producer.type 这个参数指定了在后台线程中消息的发送方式是同步的还是异步的,如果需要确保消息的可靠性,必须要将producer.type设置为sync。

  • producer.type=sync(默认)。默认是同步方式,所以一般不用配置
  • producer.type=async,设置异步模式,在producer的内存中数据缓存一定数量时以batch的形式push数据到kafka上,这样会极大的提高broker的性能,但是这样会增加丢失数据的风险。

所以生产端要根据实际的业务场景,斟酌可靠性和传输性能,配置合适的参数。

kafka broker的可靠性

kafka server的可靠性保证主要是其健壮的副本策略。调整和副本相关的参数,可以保证kafka的副本策略保证生产环境的数据可靠性要求。从最原始的物理层开始解析

文件存储机制

kafka中每一类型的消息,我们称之为topic,生产者通过topic向kafka broker发送消息,消费者通过topic从kafka broker中读取消息。

topic在物理层由partition组成,每一个topic可以分成若干个partition。再往下,一个partition在物理层由若干个segment组成。
我们一一介绍 topic、partition和segment。在物理层的存储,可以在kafka的部署节点中有一个data目录,可以看到每个topic对应的partition,进入partition之后可以看到具体的segment结构。也可以通过命令来查看分区信息:sh kafka-topics.sh --zookeeper localhost:2181/kafka --topic topicName --describe
无论是通过命令还是直接在目录下查看,可以看到每个partition的命名都是通过topic+有序序号命名的,最大的序号是partition数-1。partition是实际物理上的概念,而topic是逻辑上的概念。

partition再细分的segment就是数据的最小存储单位。每个partition相当于一个巨型文件被平均分配到多个大小相等的segment数据文件中(每个segment 文件中消息数量不一定相等)这种特性也方便old segment的删除,即方便已被消费的消息的清理,提高磁盘的利用率。每个partition只需要支持顺序读写就行,segment的文件生命周期由服务端配置参数决定(详细的参数配置参考官网)。

在kafka数据存储目录下,可以看到每个partition(/data/topic-01)下的数据存储细节,每一个segment文件都是由两部分组成的,.index文件和.log文件,分别对应segment的索引文件和数据文件,文件的命名规则是:partition全局的第一个segment从0开始,后续每个segment文件名为上一个segment文件最后一条消息的offset值,数值大小为64位,20位数字字符长度,没有数字用0填充,如下图所示:
我是图
partition中如何通过offset查找message,我们暂不详细说明,后面专门写文件介绍这块

参考: