1、Broker配置

1.1、复制系数
主题级别的配置参数是replication.factor,而在b roker 级别则可以通过default. replication.factor来配置自动创建的主题。
如果复制系数为N,那么在N-1个broker 失效的情况下,仍然能够从主题读取数据或向主题写入数据。所以,更高的复制系数会带来更高的可用性、可靠性和更少的故障。另一方面,复制系数N 需要至少N 个broker ,而且会有N 个数据副本,也就是说它们会占用N倍的磁盘空间。我们一般会在可用性和存储硬件之间作出权衡。

#创建一个分区为3的 副本为3的主题
./kafka-topics.sh --create --zookeeper 192.168.92.39:2181 --replication-factor 3 --partitions 3 --topic test
#查看主题
./kafka-topics.sh --describe --zookeeper 192.168.43.38:2181 --topic test

分区0,在broker[1,2,0]上都有副本,首领副本是1。

kafka 复制和容灾 kafka复制系数_kafka可靠消息传递


kafka 复制和容灾 kafka复制系数_数据_02


1.2、不完全的首领选举

unclean.leader.election 只能在broker 级别(实际上是在集群范围内)进行配置, 它的默认值是true。

kafka 复制和容灾 kafka复制系数_偏移量_03


如果把unclean.leader.election设为true ,就是允许不同步的副本成为首领(也就是“ 不完全的选举”),那么我们将面临丢失消息的风险。

如果把这个参数设为false ,就要等待原先的首领重新上线,从而降低了可用性。

#摘自kafka权威指南

比如银行系统,大部分银行系统宁愿选择在几分钟甚至几个小时内不处理信用卡支付事务,也不会冒险处理错误的消息。不过在对可用性要求较高的系统里,比如实时点击流分析系统, 一般会启用不完全的首领选举。

1.3、最少同步副本
在主题级别和broker 级别上,这个参数都叫min.insync.replicas(ISR)
我们知道,尽管为一个主题配置了3 个副本,还是会出现只有一个同步副本的情况。如果这个同步副本变为不可用,我们必须在可用性和一致性之间作出选择—这又是一个两难的选择。(有3个副本,由于网络或者其它原因造成从副本不能fetch主副本的消息,虽然有3个分区副本,但是还是一个主副本进行服务)如果要确保已提交的数据被写入不止一个副本,就需要把最少同步副本数量设置为大一点的值。对于一个包含3 个副本的主题,如果min.insync.replicas被设为2 ,那么至少要存在两个同步副本才能向分区写入数据。

2、生产者配置

2.1、发送确认
生成者可以选择以下3种不同的确认模式

acks=0 意味着如果生产者能够通过网络把消息发送出去,那么就认为消息已成功写入Kafka 。在acks=0 模式下的运行速度是非常快的,你可以得到惊人的吞吐量和带宽利用率,不过如果选择了这种模式, 一定会丢失一些消息。(在这种情况下还是有可能发生错误,比如发送的对象无法被序列化或者网卡发生故障,但如果是分区离线或整个集群长时间不可用,那就不会收到任何错误。即使是在发生完全首领选举的情况下,这种模式仍然会丢失消息,因为在新首领选举过程中它并不知道首领已经不可用了。)

acks=1 意味若首领在收到消息并把它写入到分区数据文件(不一定同步到磁盘上)时会返回确认或错误响应(。不过在这个模式下仍然有可能丢失数据,比如消息已经成功写入首领,但在消息被复制到跟随者副本之前首领发生崩溃)。

acks=all 意味着首领在返回确认或错误响应之前,会等待所有同步副本都收到悄息。如果和min.insync.replicas参数结合起来,就可以决定在返回确认前至少有多少个副本能够收到消息。这是最保险的做法——生产者会一直重试直到消息被成功提交。不过这也是最慢的做法,生产者在继续发送其他消息之前需要等待所有副本都收到当前的消息。可以通过使用异步模式和更大的批次来加快速度,但这样做通常会降低吞吐量。

2.2、配置生产者的重试次数
retries(broker配置):设置大于0的值将使客户端重新发送任何数据,一旦这些数据发送失败。

如果broker 返回的错误可以通过重试来解决,那么生产者会自动处理这些错误。生产者向broker 发送消息时, broker 可以返回一个成功响应码或者一个错误响应码。错民响应码可以分为两种, 一种是在重试之后可以解决的,还有一种是无法通过重试解决的。例如,如果broker 返回的是LEADER_NOT_AVAILABLE 错误,生产者可以尝试重新发送消息。也许在这个时候一个新的首领被选举出来了,那么这次发送就会成功。也就是说, LEADER_NOT_AVAILABLE是一个可重试错误。另一方面,如果broker 返回的是INVALID_CONFIG 错误,即使通过重试也无能改变配置选项,所以这样的重试是没有意义的。这种错误是不可重试错误。
要注意,重试发送一个已经失败的消息会带来一些风险,如果两个消息都写入成功,会导致消息重复。(生产者因为网络问题没有收到broker的确认,但实际上消息已经写入成功,生产者会认为网络出现了临时故障,就重试发送该消息,那么该消息就会出现两次)。

3、消费者的可靠性

3.1、消费者配置
group.id:如果两个消费者具有相同的group.id , 并且订阅了同一个主题,那么每个消费者会分到主题分区的一个子集, 也就是说它们只能读到所有消息的一个子集(不过群组会读取主题所有的消息)。如果你希望消费者可以看到主题的所有消息,那么需要为它们设置唯一的group.id 。
auto.offset.reset:这个参数指定了在没有偏移量可提交时或者请求的偏移量在broker 上不存在时,消费者会做些什么。这个参数有两种配置。一种是earliest ,如果选择了这种配置,消费者会从分区的开始位置读取数据,不管偏移量是否有效,这样会导致消费者读取大量的重复数据,但可以保证最少的数据丢失。一种是latest,如果选择了这种配置, 消费者会从分区的末尾开始读取数据,这样可以减少重复处理消息,但很有可能会错过一些消息。
enable.auto.commit:这是一个非常重要的配置参数,你可以让消费者基于任务调度自动提交偏移量,也可以在代码里手动提交偏移量。自动提交的一个最大好处是,在实现消费者逻辑时可以少考虑一些问题。如果你在消费者轮询操作里处理所有的数据,那么自动提交可以保证只提交已经处理过的偏移量。自动提交的主要缺点是,无法控制重复处理消息(比如消费者在自动提交偏移量之前停止处理消息),而且如果把消息交给另外一个后台线程去处理,自动提交机制可能会在消息还没有处理完毕就提交偏移量。
auto.commit.interval.ms:如果选择了自动提交偏移盘,可以通过该参数配置提交的频度, 默认值是每5 秒钟提交一次。一般来说,频繁提交会增加额外的开销,但也会降低重复处理消息的概率。

3.2、显示提交偏移量
1)关闭自动提交offset, 消息消费成功后,手动提交offset.
2)在设计程序时要考虑好再均衡问题。