Kafka——可靠的数据传递

本文深入探讨Kafka如何通过复制机制和分区多副本架构确保数据传递的可靠性,解析ACID规范在Kafka中的体现,以及如何配置broker参数以平衡可用性和存储资源。同时,介绍了producer和consumer如何在高可靠系统中工作,确保数据的准确性和一致性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Kafka——可靠的数据传递

kafka的复制机制和分区的多副本架构时kafka可靠性保证的核心。

可靠性保证

  • ACID规范:原子性、一致性、隔离性和持久性
  • kafka可以保证分区内消息的顺序
  • 只有当消息被写入分区的所有同步副本时(但不一定写入磁盘),才被称为“已提交”的消息
  • 只要还有一个副本时活跃的,那么已提交的消息就不会丢失
  • 消费者只能读取已提交的消息

复制

复制功能是kafka架构的核心。在个别节点失效时仍能保证kafka的可用性和持久性。kafka使用topic(逻辑概念)组织数据,每个topic被分为若干了partition(物理概念),每个partition有多个replication,replication保存在broker上,每个broker可以保存成百上千个replication。

副本类型:

  • leader:每个分区只有一个leader。为了保证一致性,所有的producer和consumer请求都会经过leader。生产者在发送数据的时候,是直接发送到leader partition里面,然后follower partition会去leader那里自行同步数据,消费者消费数据的时候,也是从leader那去消费数据的
  • follower:不处理请求,只负责从leader复制消息,与leader保持同步,及时复制最新的消息。当leader不可用时,其中一个同步副本将成为新leader。只有同步副本才能成为新leader。

同步副本:

  • 过去6秒(可配置)向ZK发送过心跳
  • 过去10秒(可配置)从leader获取过消息
  • 过去10秒从leader获取过最新的消息

Broker配置

broker有3个配置参数影响kafka消息存储的可靠性:

  • 复制系数:broker级别参数default.replication.factor,topic级别参数replication.factor。默认值3。如果复制系数为N,那么在N-1个broker失效的情况下,仍然能从topic读取或者写入数据。更高的复制系数会带来更高的可用性、可靠性和更少的故障,但复制系数N需要至少N个broker,而且会保存N份数据,占用N倍磁盘空间。故需要在可用性和存储资源之间做出权衡。副本的位置也很重要,kafka确保partition的副本被放在不同的broker上,并把broker分布在多个不同的机架上,从而获得更高的可用性。
  • 不完全首领选举unclean.leader.election只能在broker级别控制,默认值true。在选举新leader时,其他副本都是不同步的,该怎么办?两种选择:
    • 不同步的follower不能选为新的leader。那么,分区在旧的leader恢复前是不可用的,降低了可用性;
    • 不同步的follower可以选为新的leader。那么会造成丢失数据,导致数据不一致的风险。
  • 最少同步副本:broker级别和topic级别参数min.insync.replicas。尽管一个topic配置了3个副本,还是会出现只有一个同步副本的情况,如果这个同步副本变为不可用,就必须在可用性和一致性之间做出两难选择。如果要确保已提交的数据被写入不止一个副本,就需要把最少同步副本参数设置为大一点的值。对于一个包含3个副本的topic,如果min.insync.replicas被设置为2,那么至少要存在两个同步副本才能向partition写入数据。

在可靠的系统里使用producer

  • 发送确认:producer可选择以下3种确认模式:

    • acks=0:producer通过网络把消息发送出去,就认为成功写入kafka。
      • 优点:运行速度快,最高的吞吐率和带宽利用率
      • 缺点:丢失数据
    • acks=1:leader在收到消息并写入分区文件,就认为成功写入kafka。
      • 优点:速度较快,相对较高的吞吐率和带宽利用率
      • 缺点:丢失数据
    • acks=all或-1:leader在返回确认或错误响应之前,会等待所有同步副本都收到消息。
      • 优点:最可靠
      • 缺点:丢失数据;速度最慢,较低的吞吐率和带宽利用率
  • producer的重试发送:producer需要处理的错误包括:producer可以自动处理的错误和需要开发者手动处理的错误。一般情况下,如果目标是不丢失数据,那么最好让producer在遇到错误时保持重试,如leader选举和网络连接问题。但要注意,重试发送一个已经失败的消息会带来一些风险,如果两次重试都写入成功,会导致消息重复。

在可靠的系统里使用consumer

消费者为什么要提交offset?如果一个consumer退出,另一个consumer需要知道从什么地方开始继续处理,需要知道前一个consumer在退出前处理的最后一个offset时多少。如果consumer提交了offset却未处理完消息,就有可能造成消息丢失,这是消息丢失的主要原因。

  • consumer的可靠性配置
    • group.id:如果两个consumer具有相同的group.id,并且订阅了同一个offset,那么每个consumer会分到主题分区的一个子集,即它们只会读取到所有消息的一个子集(群组会读取topic所有消息)。如果希望consumer看到topic的所有消息,那么需要为它们设置唯一的group.id;
    • auto.offset.reset:该参数指定了在没有offset可提交时(如consumer第一次启动)或者请求的offset在broker上不存在时,consumer会从哪里消费数据。可选项:
      • earliest:consumer从分区的开始位置读取消息
      • latest:consumer从扥去的末尾位置去读取消息
    • enable.auto.commit:提交offset的方式有:
      • 基于任务调度自动提交
      • 在代码里手动提交
    • auto.commit.interval.ms:与第三个参数有直接联系。如果选择了自动提交offset,可通过该参数配置提交的频度,默认每5秒提交一次。频繁提交会增加额外开销,但也会降低重复处理消息的概率。
  • 显示提交offset
    • 总是在处理完事件后再提交偏移量:如果所有的处理都是在轮询里完成,并且不需要在轮询之间维护状态(如聚合操作),那么可以使用自动提交,或者在轮询结束时手动提交;
    • 提交频度是性能和重复消息数量之间的权衡
    • 确保对轮询的offset心里有数:要记住:在处理完消息后再提交offset是非常关键的;
    • 再均衡:在设计应用程序时,要注意处理consumer的再均衡问题;
    • 消费者可能需要重试
    • 消费者可能需要维护状态
    • 长时间处理
    • 仅一次传递:
      • 幂等性写入:最简单最常用的办法就是把结果写到一个支持唯一键的系统里,比如键值存储引擎、关系型数据库、ES或其他存储引擎。要么消息本身包含一个唯一键,要么使用topic+partition+offset的组合来创建唯一键——唯一标识一个Kafka记录;
      • 事务:把消息和offset放在同一个事务,这样它们就能保持同步。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值