智乐活

Kafka 可靠的数据传递

2018/07/24 Share

Kafka 在数据传递可靠性方面具有很大的灵活性,是高度可配置的,通过使用客户端 API 可以满足不同程度的可靠性需求。

Kafka 有一些基本的保证:1. Kafka 可以保证分区内消息的顺序;2. 消息被写入到分区的所有同步副本才算是已经提交的消息;3. 只要有一个副本活跃,已经提交的消息就不会丢失;4. 消费者只能读取已经提交的消息。

以上的基本保证用于构建可靠的系统,开发者在配置参数上作出权衡(可靠性、一致性的重要程度与可用性、高吞吐量、低延迟和硬件成本重要程度之间的权衡),从而获得想要达到的可靠性。

配置 broker

broker 有 3 个配置会影响消息存储的可靠性,应用在 broker 级别时控制所有主题的行为,应用在主题级别时控制个别主题的行为。

复制系数

复制系数即数据数据副本的个数,复制系数 N 需要至少 N 个 broker,在 N - 1 个 broker 失效的情况下仍然可用,默认为 3。主题级别的配置是 replication.factor,而 broker 级别通过 default.replication.factor 来配合自动创建主题的复制系数。

更高的复制系数会带来更高的可用性和更少的故障,不过会占用 N 倍的磁盘空间,一般要在可用性和存储硬件之间作出权衡。

如果重启等导致主题不可用是可以接受的,那么复制系数设为 1 就可以,不过在节省硬件成本的同时也降低了可用性。复制系数为 2 可以容忍 1 个 broker 失效,不过有时候 1 个broker 失效会导致集群不稳定(通常是旧版 Kafka)。建议在要求可用性的场景把复制系数设置为 3,在大多数情况下足够安全。

同时注意副本的分布也很重要,Kafka 会保证分区的每个副本在不同的 broker 上,如果把 broker 分布在不同机架上,并使用 broker.rack 配置机架信息,可以获得更高的可用性。

不完全首领选举

当分区首领不可用时,一个同步副本会被选为新首领。但如果首领不可用时其他副本都是不同步的,就要做出一个艰难的选择。

如果将不同步副本提升为新首领,则副本不同步后写入旧首领的消息丢失,导致数据不一致,否则分区在旧首领(最后一个同步副本)恢复之前不可用。

默认情况下 unclean.leader.election.enable 的值为 true,即允许【不完全的选举】。

最少同步副本

尽管可以将复制系数设为 3,可还是会出现只有一个同步副本的情况,如果唯一的同步副本不可用,就必须在可用性和一致性间做选择。如果要确保已提交的消息被写入到不止一个副本,就需要把最小同步副本的值设置大一点。

最小同步副本在主题和 broker 级别均为 min.insync.replicas,如果设置为 2,则至少存在两个同步副本才能向分区写入数据。如果可用副本不足,生产者会受到 NotEnoughReplicasException。此配置配合生产者的 acks(需要接收到多少个同步副本的响应才算写入成功)配置能使消息的可靠性更好。

配置生产者

即使我们尽可能地把 broker 配置的很可靠,但如果没有对生产者进行可靠性方面的配置,系统仍然可能出现突发的数据丢失。

比如 broker 配置为 3 个副本,禁用不完全选举,如果生产者 acks 为 1,首领副本接到消息后崩溃,虽然有两个同步副本,但还没有来得及同步消息,其中一个副本称为新首领,从生产者的角度就丢失了一个消息。

再比如 acks 设为 all,但发送消息时首领崩溃,生产者收到【首领不可用】的错误相应,如果没有处理错误,也会丢失消息。

所以,生产者首先需要将 acks 配置为合适的值,其次需要处理 broker 返回的错误。

broker 返回的错误如果是可以通过重试解决的,生产者会自动处理错误,比如 LEADER_NOT_AVAILABLE 错误,可以通过配置 retries 来指定最大重试次数。需要注意的是,重试会带来一些风险,比如生产者因为网络问题没有收到 broker 的确认。

如果需要【只保存一次】,可以在消息中假如唯一标识符,或者使消息【幂等】,即出现了重复消息也不会有负面影响。【这个账号里有 10 美元】是幂等的,【给这个账号加 10 美元】不是幂等的。

另一种不可通过重试解决的错误,比如消息过大、重试达上限等,需要开发者根据业务逻辑处理错误。

配置消费者

只有被写入到所有同步副本的消息才会被消费者读取,消息已经具备一致性,所以消费者要做的就是记住哪些消息已经被读取过,哪些还没有读取。

从分区读取数据时,消费者会获取一批事件,检查事件中最大的偏移量,然后从最大偏移量开始读取下一批事件。而如果消费者退出,其他消费者需要知道之前的消费者读取的进度,这也就是提交偏移量的作用。

消费者需要注意以下配置:1. group.id,具有相同 group.id 的消费者会共同读取订阅的主题。2. auto.offset.reset 指定在没有记录偏移量时从何处开始读取,earliest 表示从分区开始位置读取,latest 表示从末尾开始读取。3. enable.auto.commit 配置是否开启自动提交偏移量。4. auto.commit.interval.ms 自动提交偏移量的时间间隔。

手动提交偏移量会更准确,关于手动提交偏移量需要注意以下几点:

  1. 要在消息事件处理完后再提交偏移量
  2. 在提交频率和重复消息数量之前作权衡
  3. 注意再均衡,在失去控制前提交偏移量
  4. 注意消息事件处理失败的逻辑
  5. 数据处理要花费很长时间时注意保持心跳
  6. 需要【仅一次】传递时可以借助支持唯一键、事务的系统

验证系统可靠性

在确认了可靠性需求,并且配置 broker 和客户端后,最好还是先对系统可靠性做些验证。建议在 3 个层面做验证:配置验证、应用程序验证及生产环境的应用程序监控。

配置验证

Kafka 提供了两个用于验证配置的重要工具:org.apache.kafka.tools 包内的 VerifiableProducer 和 VerifiableConsumer 两个类,可以从命令行运行两个类或嵌入自动化测试框架。

使用和生产者、消费者相同的方式来配置 VerifiableProducer 和 VerifiableComsumer,VerifiableProducer 生成一系列消息,通过 VerifiableComsumer 检查每个消息。可以在首领选举、控制器选举、依次重启、不完全首领选举测试等场景测试系统的可靠性。

应用程序验证

确保 broker 和客户端配置满足需求后,可以再从应用程序方面检查,包括错误处理、提交偏移量、再均衡监听等,建议基于如下故障条件测试应用程序:客户端从服务器断开连接、首领选举、依次重启 broker、依次重启生产者和依次重启消费者。

生产环境监控

测试无法替代生产环境的持续监控,监控的目的是确保数据按期望的方式流动,可以按照业务需求对重要的数据指标进行持续地监控。

参考

Kafka 官方文档

Kafka 权威指南

CATALOG
  1. 1. 配置 broker
    1. 1.1. 复制系数
    2. 1.2. 不完全首领选举
    3. 1.3. 最少同步副本
  2. 2. 配置生产者
  3. 3. 配置消费者
  4. 4. 验证系统可靠性
    1. 4.1. 配置验证
    2. 4.2. 应用程序验证
    3. 4.3. 生产环境监控
  5. 5. 参考