可靠的数据传递
可靠性保证
- kafka可以保证分区消息的顺序
- 只有当消息被写入分区的所有同步副本时,才被认为是已提交的
- 只要还有一个副本是活跃的,那么已经提交的消息就不会丢失
- 消费者只能读取已经提交的消息
消息存储的可靠性和一致性的重要程度与可用性、高吞吐量、低延迟和硬件成本之间的权衡
复制
kafka复制机制和分区多副本架构是可靠性保证的核心
同步分区要满足的条件
- 与zookeeper间有一个活跃的会话,在过去6s内发送过心跳
- 过去10s内从首领获取过消息
- 过云10s内从首领获取过最新消息,即几乎是零延迟
一个滞后的同步副本会导致生产者和消费者变慢,因为消息被认为已提交前,需要得到同步副本的确诊
非同步副本不会影响性能,但更少的同步副本意味着更低的有效复制系统
broker配置
影响消息存储可靠性的参数,这些参数即可应用于全局,也可应用于特定的主题
1、复制系数
主题级别:replication.factor
broker级别:default.replication.factor
即分区副本个数,默认3副本
broker.rack 可以为每个broker配置所在机架的名字,此时kafka会保证分区的副本被分布在多个机架上
2、不完全的首领选举
broker级别:unclean.leader.election 默认true
在选举首领副本过程中没有丢失数据,即提交的数据同时存在于所有同步副本上,好么选举是完全的
如果在首领不可用时,其他副本都不同步,就是不完全
注意:允许不同步的跟随副本提升为首领副本,就要承担丢失数据和数据不一致的风险;若不允许它成为首领,则要接受较低可用性的风险(需要等待原首领恢复到可用状态)
3、最少同步副本
主题级别:min.insync.replicas
broker级别:min.insync.replicas
如果同步副本数量小于最小值,broker会停止接受生产者的请求,消费者仍然可正常读取已有数据 (只读)
在可靠的系统里使用生产者
可能存在的问题
- acks设置为1,首领收到消息后,崩溃,消息还没有同步到同步副本时
- acks设置为all,客户端发送后首领崩溃,但客户端没有正确处理"首领不可用"异常,并认为消息已正常投递
发送确认
acks=0 一定会丢失消息,但可得到惊人的吞吐量和带宽利用率
acks=1 风险点,客户端没有正确处理 LeaderNotAvailableException 异常;首领同步消息时崩溃
acks=all 配合min.insync.replicas参数,最保险,但会降低吞吐量
配置生产者的重试参数
broker返回的错误分为两种:可通过重试解决和不能通过重试解决
对于重试次数,需要根据实际情况进行设置 (MirrorMaker的重试策略是无限重试,决不丢失消息)
重试发送已经失败的消息会带来风险,如导致消息重复
重试和恰当的错误处理可保证每个消息"至少被保存一次",但无法保证"只被保存一次"
解决办法是为每条消息加入唯一标识符 和 应用程序做到"幂等"
额外的错误处理
不可重试的错误:消息大小错误、认证错误、序列化错误、重试次数上限或内存达到上限时的错误
在可靠的系统里使用消费者
跟踪哪些消息是已经读取过的,哪些是还没有读取过的
消费者提交了偏移量却未能处理完消息,就有可能造成消息丢失
消费者的可靠性配置
- group.id
- auto.offset.reset 在没有偏移量或偏移量无效时,客户端的行为 late