自动确认没收到,实现重复消费问题,可以用业务唯一标识来确定业务是否被消费。
TTL也就是超时时间,一般去dead letter的时间为min(消息的ttl,queue的ttl)。
acks=all设置是最安全的,但是效率太低了,实际的生产环境中至少要设置到ack=1的机制。
异步提交容易丢失数据,同步提交容易阻塞。
代码中实现的是异步+同步组合提交。
分区设置一致肯定能保证顺序执行,也可以设置业务key,key可以决定存储分区,同一个key的哈希值相同,存储分区也相同。
👆正常拷贝,需要复制的次数太多了。
零拷贝 为👆 ,零拷贝指的是cpu不参与拷贝,用dma硬件参与拷贝而非cpu。
可靠性和持久化
- 数据存储机制
Kafka 将消息存储在磁盘上,使用分区(Partition)来组织数据。每个主题(Topic)可以有多个分区,每个分区是一个有序的、不可变的消息队列。消息被追加到分区的末尾,并且每条消息都有一个唯一的偏移量(Offset)。 - 日志段(Log Segment)
每个分区被进一步拆分为多个日志段(Log Segment),每个日志段都是一个单独的文件。日志段的大小可以通过配置参数 log.segment.bytes 来控制,默认大小为 1GB。当一个日志段达到配置的大小限制时,Kafka 会创建一个新的日志段。 - 数据持久化配置
Kafka 提供了多个配置选项来控制数据的持久化行为:- a. 副本(Replication)
Kafka 通过复制(Replication)来确保数据的持久性和容错性。每个分区可以有多个副本(Replica),其中一个是领导者(Leader),其他是跟随者(Follower)。所有的写操作都首先写到领导者,然后由跟随者复制。
相关配置参数:
replication.factor: 每个分区的副本数量。
min.insync.replicas: 在生产者配置 acks=all 时,要求最少有多少个副本处于同步状态,才能认为写操作成功。 - b. 日志保留(Log Retention)
Kafka 提供了多种日志保留策略,可以根据时间或磁盘空间来控制日志的保留。
相关配置参数:
log.retention.hours: 日志保留的时间,默认是 168 小时(7 天)。
log.retention.bytes: 日志保留的最大字节数。
log.retention.ms: 日志保留的时间(以毫秒为单位)。
log.segment.bytes: 单个日志段的最大大小。 - c. 数据刷盘(Flush)
Kafka 使用页缓存来提高性能,数据首先写入页缓存,然后定期刷入磁盘。你可以配置刷盘的频率。
相关配置参数:
log.flush.interval.messages: 在多少条消息后触发一次刷盘。
log.flush.interval.ms: 在多长时间后触发一次刷盘。
- a. 副本(Replication)
- 数据恢复
Kafka 在启动时会重建内存中的索引,以便快速定位消息。它通过检查日志文件和索引文件来确保数据的一致性。
示例配置
下面是一个示例的 Kafka 配置文件(server.properties),展示了如何配置持久化参数:
# 每个分区的副本数量
default.replication.factor=3
# 日志保留时间
log.retention.hours=168
# 日志保留大小
log.retention.bytes=1073741824
# 单个日志段的大小
log.segment.bytes=1073741824
# 刷盘间隔(消息数)
log.flush.interval.messages=10000
# 刷盘间隔(时间)
log.flush.interval.ms=1000
# 最少同步副本数
min.insync.replicas=2
- 数据持久化的工作流程
消息生产:生产者将消息发送到 Kafka 代理(Broker),领导者副本接收消息并写入日志。
消息复制:跟随者副本从领导者副本拉取消息并写入自己的日志。
消息确认:当消息被写入到足够多的副本时,领导者副本向生产者发送确认。
消息消费:消费者从分区中读取消息,使用偏移量来跟踪消费进度。
通过以上机制,Kafka 确保了消息的可靠性和持久性,即使在代理崩溃或故障的情况下,消息也不会丢失。