文章目录
- Kafka版本
- Producer参数配置
- bootstrap.servers
- key.serializer
- value.serializer
- acks
- buffer.memory
- max.block.ms
- compression.type
- retries
- retry.backoff.ms
- batch.size与linger.ms
- max.request.size
- request.timeout.ms
- client.id
- enable.idempotence
- max.in.flight.requests.per.connection
- transaction.timeout.ms
- transactional.id
- connections.max.idle.ms
- 其他参数
- Consumer重要参数配置
- group.id
- session.timeout.ms
- max.poll.interval.ms
- fetch.min.bytes
- fetch.max.bytes
- fetch.max.wait.ms
- max.partition.fetch.bytes
- auto.offset.reset
- enable.auto.commit
- auto.commit.interval.ms
- max.poll.records
- heartbeat.interval.ms
- connections.max.idle.ms
- request.timeout.ms
- exclude.internal.topics
- 其他配置
- Broker重要参数
- zookeeper.connect
- listeners
- advertised.listeners
- broker.id
- log.dir与log.dirs
- unclean.leader.election.enable
- message.max.bytes
- delete.topic.enable
- 消息删除策略
- min.insync.replicas
- num.network.threads
- num.io.threads
- Broker-Topic参数
- delete.retention.ms
- max.message.bytes
- retention.bytes
- auto.create.topics .enable
- 无消息丢失配置
Kafka版本
- kafka版本1.1.1,可能绝大部分也适用于kafka 0.10.x及以上版本。
Producer参数配置
- 官方文档https://kafka.apache.org/documentation/#producerconfigs
bootstrap.servers
- 指定一组Broker地址(格式host1:port1,host2:port2,…),比如
kafka-master:9092,kafka-slave1:9093,kafka-slave2:9094
.如果集群中的实例很多,只需要指定部分broker即可,不需要列出所有的实例地址,kafka会根据提供的地址发现其他的地址
key.serializer
- key的序列化类(实现序列化接口),即使 Producer在发送消息时不指定 key,这个参数也是必须要设置的。
-
key.serializer
指定的是实现了org.apache.kafka.common.serialization.Serializer接口的类的全限定名称。
value.serializer
- value的序列化类(实现序列化接口),这个参数也是必须要设置的
-
value.serializer
指定的是实现了org.apache.kafka.common.serialization.Serializer接口的类的全限定名称。
acks
- acks 参数用于控制 producer 生产消息的持久性。acks 指定了在给 producer 发送响应前, leader broker 必须要确保己成功写入该消息的副本数。
acks = 0
: producer发送消息后立即开启下一条消息的发送,根本不等待 leader broker端返回结果。由于不接收发送结果,因此在这种情况下 producer.send 的回调也就完全失去了作用, 即用户无法通过回调机制感知任何发送过程中的失败,所以 acks=0 时 producer 并不保证消息会被成功发送。但是通常这种设置下producer吞吐量最高,对于可以容忍丢失消息,而且需要高吞吐量的场景可以使用此设置。acks = -1或者acks = all
: 发送消息时, leader broker不仅会将消息写入本地日志,同时还会等待 ISR 中所有其他副本都成功写入它们各自的本地日志后,才发送响应结果给producer。只要 ISR中至少有一个副本是处于"存活"状态的,那么这条消息就肯定不会丢失。通常这种设置下produer吞吐量最低,但是可以保证消息不会丢失(并不是绝对,因为ISR中可能只有leader副本,这样就相当于acks=1的情况,如果需要获得最高的可靠性,需要配合broker的配置min.insync.replicas)acks = 1
: 这是默认配置,producer发送消息后 leader broker 仅将该消息写入本地日志,然后便发送响应结果给 producer,而无须等待 ISR中其他副本写入该消息。 那么此时只要该 leader broker一直存活, Kafka就能够保证这条消息不丢失,但是如果响应消息之后但follower还未复制之前leader立即故障,那么消息将会丢失。这实际上是一种折中方案,既可以达到适当的消息持久性,同时也保证了producer端的吞吐量。
buffer.memory
- buffer.memory:producer 端用于缓存消息的缓冲区大小,单位字节,默认值是 33554432(即32MB)。Java 版本 producer 启动时会首先创建一块内存缓冲区用于保存待发送的消息,然后由另一个专属线程负责从缓冲区中读取消息执行真正的发送
- 如果 producer 向缓冲区写消息的速度超过了专属I/O线程发送消息的速度,那么必然造成该缓冲区空间的不断增大,生产者将阻塞
max.block.ms
之后,抛出异常。 - 如果 producer程序要给很多分区发送消息,那么就需要仔细地设置这个参数以防止过小的内存缓冲区降低了 producer程序整体的吞吐量。
max.block.ms
- 该配置控制 KafkaProducer.send() 和 KafkaProducer.partitionsFor() 将阻塞多长时间,单位毫秒,默认60000ms。此外这些方法被阻止,也可能是因为缓冲区已满或元数据不可用。在用户提供的序列化程序或分区器中的锁定不会计入此超时。
compression.type
- 数据压缩的类型,对应
org.apache.kafka.common.record.CompressionType
- none,这是默认值,表示不压缩
- gzip
- snappy
- lz4:推荐使用此算法
- Kafka 对 LZ4 压缩算法的支持是最好的。启用 LZ4 进行消息压缩的producer 的吞吐量是最高的。压缩的性能与producer端的batch大小相关,通常batch越大需要压缩的时间就越长。
LZ4>>Snappy>GZIP
- 虽然producer 端引入压缩后可以显著地降低网络 I/O传输开销从而提升整体吞吐量,但也会增加 producer端机器的 CPU开销。如果 broker端的压缩参数设置得与 producer 不同, broker 端在写入消息时也会额外使用 CPU 资源对消息进行对应的解压缩-重压缩操作。
retries
- Kafka broker 在处理写入请求时可能因为瞬时的故障 (比如瞬时的leader 选举或者网络抖动)导致消息发送失败。这种故障通常都是可以自行恢复的,如果把这些错误封装进回调函数的异常中返还给 producer, producer 程序也并没有太多可以做的,只能简单地在回调函数中重新尝试发送消息。与其这样,还不如 producer 内部自动实现重试
- retries表示进行重试的次数,默认值是 0,表示不进行重试
- 如果max.in.flight.requests.per.connection没有设置为1,有可能改变消息发送的顺序,因为如果2个批次发送到一个分区中,第一个失败了并重试,但是第二个成功了,那么第二个批次将超过第一个。
- 重试需要注意的问题
- 重试可能造成消息的重复发送:如果broker恰好在消息已经成功写入Kafka topic后,发送ack前,出了故障,生产者的重试机制就会导致这条消息被写入Kafka两次或者多次。一般需要在consumer端执行去重处理。不过kafka在0.11.0.0版本开始支持"精确一次"处理语义
- 重试可能造成消息的乱序: producer 会将多个消息发送请求(默认是 5 个) 缓存在内存中,如果由于某种原因发生了消息发送的重试,就可能造成消息流的乱序 。为了避免乱序发生,producer 提供了
max.in.flight.requets.per.connection
参数 。一旦将此参数设置成 1, producer将确保某一时刻只能发送一个请求。 - 重试间隔:Producer重试之间会停顿一段时间(retry.backoff.ms,默认100ms ),为了避免频繁的重试对系统带来冲击。常见的瞬时错误就是leader的换届选举(一般建议通过测试来计算平均 leader选举时间并根据该时间来设定
retries
和retry.backoff.ms
的值 )
retry.backoff.ms
- 尝试重试指定topic分区的失败请求之前等待的时间。这样可以避免在某些故障情况下高频次的重复发送请求,默认值100ms
batch.size与linger.ms
- producer 会将发往同一分区的多条消息封装进一个 batch中,以减少网络交互。当 batch满了的时候, producer会发送 batch 中的所有消息。
batch.size
默认值16384(16KB),对于吞吐量优先的应用,调大此值会提高性能。 -
linger.ms
就是控制发送延时行为的,默认值时0,表示消息需要立即发送,不需要关系batch是否被填满,对于低延迟的应用来说,这样是合理的。但是对于吞吐量优先的应用,应该调大此值。
max.request.size
- producer 端能够发送的最大消息大小,字节为单位,默认1048576(1MB),此参数最好与broker端的message.max .bytes保持一致。
request.timeout.ms
- 客户端等待请求响应的最长时间。如果在超时之前未收到响应,客户端将在必要时重新发送请求,如果重试耗尽,则该请求将失败。 这应该大于
replica.lag.time.max.ms
,以减少由于不必要的生产者重试引起的消息重复的可能性。 -
request.timeout.ms
默认30s,如果broker在30s内都没有给producer发送响应,那么produer就会任务该请求超时了,并在回调函数中显示抛出TimeoutException异常
client.id
- 默认空字符串,当发出请求时传递给服务器的id字符串。这样做的目的是允许服务器请求记录这个【逻辑应用名】,这样能够追踪请求的源,而不仅仅只是ip/prot。
enable.idempotence
- 当设置为true,生产者将确保一次性语义。请注意,需要将
max.in.flight.requests.per.connection
设置为1,重试次数不能为零。另外acks必须设置为"all"。如果这些值保持默认值,我们将覆盖默认值。 如果这些值设置为与幂等生成器不兼容的值,则将抛出一个ConfigException异常。
max.in.flight.requests.per.connection
- 阻塞之前,客户端单个连接上发送的未应答请求的最大数量,默认时5。注意,如果此设置设置大于1且发送失败,则会由于重试(如果启用了重试)会导致消息重新排序的风险
- 一般而言,在需要保持顺序消息的场景下需要把此参数设置为1,避免消息重排序的风险
transaction.timeout.ms
- 生产者在主动中止正在进行的交易之前,交易协调器等待事务状态更新的最大时间(以ms为单位,默认60000ms)。如果此值大于broker中的
max.transaction.timeout.ms
设置,则请求将失败,并报"InvalidTransactionTimeout"错误。
transactional.id
- 用于事务传递的Transactional Id。这样可以跨多个生产者会话的可靠性语义,因为它允许客户端保证在开始任何新事务之前使用相同的Transactional Id的事务已经完成。如果没有提供Transactional Id,则生产者被限制为幂等传递。请注意,如果配置了Transactional Id,则必须启用
enable.idempotence
。 默认值为空,这意味着无法使用事务。
connections.max.idle.ms
- 指定在多少毫秒之后关闭闲置的连接,默认540000ms。此值如果设置的太小,Kafka会定期地关闭与Broker的空闲 Socket连接,导致下次 consumer处理请求时需要重新创建Socket连接。
- 推荐设置为-1,即永远不要关闭空闲连接。
其他参数
-
receive.buffer.bytes
:读取数据时使用的TCP接收缓冲区(SO_RCVBUF)的大小。默认值32768字节,如果值为-1,则将使用OS默认值。 -
send.buffer.bytes
:发送数据时,用于TCP发送缓存(SO_SNDBUF)的大小。默认值131072字节,如果值为 -1,将使用OS默认值。
Consumer重要参数配置
- 官方文档https://kafka.apache.org/documentation/#newconsumerconfigs
group.id
- 此Consumer所属消费者组的唯一标识。如果消费者用于订阅或offset管理策略的组管理功能,则此属性是必须的。默认是空字符串
session.timeout.ms
-
session.timeout.ms
是 consumer group 检测组内成员发送崩溃的时间 。如果设置1min,当某个group成员突然奔溃了,Kafka消费者组协调者(group coordinator)可能需要1min才能感知到。 - 在0.10.1.0版本(不包含)之前
session.timeout.ms
还有另外一个含义,就是consumer 消息处理逻辑的最大时间。倘若 consumer 两次 poll 之间的间隔超过了该参数所设置的阈值,那么 coordinator 就会认为这个 consumer已经追不上组内其他成员的消费进度了, 因此会将该 consumer踢出组,该 consumer负责的分区也会被分配给其他 consumer。好的情况下会导致不必要的rebalance,坏的情况下那些被踢出 group 后处理的消息, consumer 都无法提交位移,即会导致重复消费 - 在0.10.1.0版本(包含)之后,
session.timeout.ms
参数被明确为coordinator检测失败的时间
,默认10000ms
max.poll.interval.ms
- 使用消费者组管理时poll()调用之间的最大延迟(即用于设置消息处理逻辑的最大时间的)。消费者在获取更多记录之前可以空闲的时间量的上限。如果此超时时间期满之前poll()没有调用,则消费者被视为失败,并且分组将重新平衡,以便将分区重新分配给别的成员。默认300000ms
- 比如业务逻辑平均处理时长为20s,则此参数应该设置大于20000ms
- 在0.10.1.0版本(不包含)之前使用的是
session.timeout.ms
,在0.10.1.0版本(包含)之后,session.timeout.ms
被拆分成session.timeout.ms
和max.poll.interval.ms
fetch.min.bytes
- 拉取请求返回的最小数据量,默认值是1字节。此值设置的越大服务器等待数据积累的时间越长,可能以一些额外的延迟为代价提高服务器吞吐量,对于延迟敏感的应用调整为可能发送的最小消息字节为好(提前预估大概平均消息字节数)
fetch.max.bytes
- 服务器为拉取请求返回的最大数据值,默认52428800字节(50MB)。这不是绝对的最大值,如果在第一次非空分区拉取的第一条消息大于该值,该消息将仍然返回,以确保消费者继续工作。接收的最大消息大小通过message.max.bytes (broker config) 或 max.message.bytes (topic config)定义。注意,消费者是并行执行多个提取的。
fetch.max.wait.ms
- 此参数与
fetch.min.bytes
有些关联,因为如果kafka仅仅参考fetch.min.bytes
的值,如果发送方一直不发送消息,那么consumer可能会一直阻塞等待。fetch.max.wait.ms
用于指定kafka最大的等待时间,默认值500ms,如果业务应用对延迟比较敏感,可以调小参数。
max.partition.fetch.bytes
- 从每个分区里返回给 Consumer的最大数据量 ,默认值为 1048576字节(1MB)。
-
max.partition.fetch.bytes
用来限制一次从每个分区拉取的最大消息大小,fetch.max.bytes
限制一次拉取中整体消息大小。
auto.offset.reset
- 当Kafka中没有初始offset或如果当前的offset不存在时(例如,该数据被删除了或者位移越界了)的策略
- earliest:指定从最早的位移开始消费(最早的位移不一定就是0)
- latest:指定从最新处位移开始消费 ,这是默认值
- none:指定如果未发现位移信息或位移越界,则抛出异常。
- 对于第一次运行consumer Group并且指定earliest开始消费,因为此时group没有任何位移信息,所以该group会从头开始消费所有数据。一旦group成功提交位移后,重启了group(还是配置earliest),此时并不会重头开始消费,因为kafka已经保存了该group的位移信息,因此会无视
auto.offset.reset
的设置。
enable.auto.commit
-
enable.auto.commit
指定consumer是否自动提交。如果为true,consumer在后台周期性自动提交offset,默认为true。如果为false,需要手动提交offset。 - 对于需要"精确处理一次"语义的需求,最好将参数设置为false,手动提交位移。
auto.commit.interval.ms
- 如果
enable.auto.commit
设置为true,则消费者偏移量自动提交给Kafka的频率(以毫秒为单位),默认5000ms
max.poll.records
- 在单次调用
poll()
中返回的最大记录数,默认500。消息比较小,可以适当提高此值
heartbeat.interval.ms
- 当 coordinator 决定开启新一轮 rebalance 时,它会将这个决定以
REBALANCE_IN_PROGRESS
异常的形式"塞进" consumer 心跳请求的 response 中,这样其他成员拿到 response 后才能知道它需要重新加入 group。这个过程显然是越快越好,heartbeat.interval.ms
就是设置这个时间的 - 推荐设置一个比较低的值,让group下的其他consumer成员能尽快感知新一轮rebalance开启了。但是该值必须小于
session.timeout.ms
,通常不高于1/3,默认3000ms
connections.max.idle.ms
- 指定在多少毫秒之后关闭闲置的连接,默认540000ms(9分钟)。此值如果设置的太小,Kafka会定期地关闭与Broker的空闲 Socket连接,导致下次 consumer处理请求时需要重新创建Socket连接。
- 推荐设置为-1,即永远不要关闭空闲连接。
request.timeout.ms
- 客户端等待请求响应的最长时间。如果在超时之前未收到响应,客户端将在必要时重新发送请求,如果重试耗尽,则该请求将失败。 这应该大于
replica.lag.time.max.ms
,以减少由于不必要的生产者重试引起的消息重复的可能性。 -
request.timeout.ms
默认3000ms,如果broker在30s内都没有给consumer发送响应,那么consumer就会任务该请求超时了
exclude.internal.topics
- Kafka 中有两个内部的主题:
_consumer_offsets
和_transaction_state
。exclude.internal.topics 用来指定 Kafka 中的内部主题是否可以向消费者公开,默认值为 true。如果设置为 true,那么只能使用subscribe(Collection)
的方式而不能使用subscribe(Pattern)
的方式来订阅内部主题,设置为 false 则没有这个限制。
其他配置
-
bootstrap.servers
含义与Producer相同、key.deserializer
、value.deserializer
,与Producer序列化类似,这里是反序列化
Broker重要参数
zookeeper.connect
- broker要连接的zookeeper地址加端口号,多个地址使用都好分隔,比如
zookeeper.connect=zk-master:2181,zk-slave1:2181,zk-slave2:2181
- 最佳实践是再加一个chroot路径(不指定默认使用zookeeper根路径),可以实现多个kafka集群服用一套zookeeper集群,可以节省机器资源。
zookeeper.connect=zk-master:2181,zk-slave1:2181,zk-slave2:2181/kafka
listeners
- broker监听客户端连接的地址列表,配置格式为协议://hostname:port,多个使用逗号分隔。kafka支持的协议类型有
PLAINTEXT
,SSL
,SASL_SSL
.如果未开启安全认证,则直接使用PLAINTEXT即可
listeners=PLAINTEXT://kafka-master:9092
- 如果不指定主机名,则表示绑定默认网卡,如果默认绑定到127.0.0.1,则无法对外提供服务。如果主机名是 0.0.0.0,则表示绑定所有的网卡
advertised.listeners
- 与 listeners类似,该参数也是用于发布给 clients 的监听器,不过该参数主要用于 IaaS 环境,比如云上的机器通常都配有多块网卡(私网网卡和公网网 卡)。对于这种机器,用户可以设置该参数绑定公网 IP供外部clients使用,然后配置上面的 listeners来绑定私网IP供 broker间通信使用。当然不设置该参数也是可以的, 只是云上的机器很容易出现 clients 无法获取数据的问题,原因就是 listeners 绑定的是默认网卡,而默认网卡通常都是绑定私网 IP 。在实际使用场景中,对于配有多块网卡的机器而言,这个参数通常都是需要配置的。
broker.id
- 指定 Kafka 集群中 broker 的唯一标识,默认值为-1.如果没有设置kafka会自动生成一个唯一值。
log.dir与log.dirs
-
log.dir
用来配置单个根目录,而log.dirs
用来配置多个根目录,多个使用逗号分隔。 -
log.dirs
保存日志数据的目录,多个目录使用逗号分隔,生产环境一般情况下需要指定多个目录,这样kakfa可以把负载均匀地分配到多个目录下,如果使用多块磁盘,每个目录挂载一个磁盘,则多块磁盘可以同时写,极大提升吞吐量。如果未设置,则使用log.dir
中的值,即log.dirs
的优先级高。默认情况下只配置log.dir
,默认值为/tmp/kafka-logs。
unclean.leader.election.enable
- 是否开启 unclean leader选举,在kafka 0.11.0 版本开始默认为false,之前版本是true。
- ISR 中的所有副本都有资格随时成为新的 leader,但若 ISR变空而此时 leader又宕机了, Kafka应该如何选举新的 leader呢?为false表示不允许从剩下存活的非ISR副本中选择一个当 leader,因为这可能会导致消息丢失。
message.max.bytes
- 服务器可以接收的消息的最大大小,默认值为1000012字节(977KB,约等于1MB)
delete.topic.enable
- 是否允许kafka删除topic,kafka1.0.0版本默认为true,kafka1.0.0版本之前默认为false。如果为false,并不会真正的删除topic
消息删除策略
-
log.retention.{hours|minutes|ms}
:消息数据的留存时间,默认配置是log.retention.hours=168,即7天 -
log.retention.bytes
:消息日志的总大小,默认-1表示不会通过消息总大小判断是否需要删除
min.insync.replicas
- 配合producer的ack参数使用。只有ack=-1,配置min.insync.replicas才有意义,表示broker端必须成功响应 clients 消息发送的最少副本数。
- 在实际使用中,假设每个分区有3个副本,如果min.insync.replicas=2,则表示能容忍一台broker宕机而不影响服务。如果设置为min.insync.replicas=3,则只要任何一台broker宕机,整个kafka集群将不可用。
num.network.threads
- num.network.threads控制broker在后台用于处理网络请求(转发请求)的线程数,默认为3.
num.io.threads
- broker用于执行网络请求的io线程数,默认为8
Broker-Topic参数
- 每个topic可以设置自己的参数,即可以覆盖全局broker配置。
- 可以在创建主题时通过提供一个或多个–config选项来设置替代值。
bin/kafka-topics.sh --zookeeper localhost:2181 --create --topic my-topic --partitions 1 --replication-factor 1 --config max.message.bytes=64000 --config flush.messages=1
- 创建topic后修改
bin/kafka-configs.sh --zookeeper localhost:2181 --entity-type topics --entity-name my-topic --alter --add-config max.message.bytes=128000
- 检查是否生效
bin/kafka-configs.sh --zookeeper localhost:2181 --entity-type topics --entity-name my-topic --describe
- 删除
bin/kafka-configs.sh --zookeeper localhost:2181 --entity-type topics --entity-name my-topic --alter --delete-config max.message.bytes
delete.retention.ms
- 每个 topic可以设置自己的日志留存时间以覆盖全局默认值
max.message.bytes
- 覆盖全局的 message.max.bytes,为每个 topic 指定不同的最大 消息尺寸
retention.bytes
- 覆盖全局的 log.retention.bytes,每个 topic 设置不同的日志留存尺寸
auto.create.topics .enable
- 默认true,当Producer向一个尚未创建的主题发送消息时,会自动创建一个分区数为 num.partitions (默认值为 1)、副本因子为 default.replication.factor (默认值为 1)的Topic
- 当一个Consumer开始从未知主题中读取消息时,或者当任意一个客户端向未知主题发送元数据请求时,都会按照配置参数 num.partitions 和 default.replication.factor 的值来创建一个相应的主题
- 不建议将 auto .create.topics. enable 参数设置为 true,这个参数会增加topic的管理与维护的难度。
无消息丢失配置
- Producer无消息丢失配置
-
max.block.ms
:内存缓冲区被填满时 producer 处于阻塞状态并停止接收新的消息而不是抛出异常 acks =all
-
retries= Integer.MAX_VALUE
:无限重试,producer只会重试那些可恢复的异常情况 -
max.in.flight.requests.per.connection = 1
:防止 topic 同分区下的消息乱序问题,即限制了 producer在单个 broker连接上能够发送的未响应请求的数量 - 使用带Callback的机制发送消息,在 Callback 的失败处理逻辑中显式调用 KafkaProducer.close(0)。 这样做的目的是为了处理消息的乱序问题 。 若不使用 close(0),默认情况下 producer 会被允许将未完成的消息发送出去, 这样就有可能造成消息乱序
- broker端配置
-
unclean.leader.election.enable =false
:关闭 unclean leader选举,即不允许非 ISR 中的副本被选举为 leader,从而避免 broker端因日志水位截断而造成的消息丢失 。 -
replication.factor>= 3
:使用多个副本来保存分区的消息。 -
min.insync.replicas > 1
:用于控制某条消息至少被写入到 ISR 中的多少个副本才算成功,只有在 producer端 acks被设置成 all或-1 时,这个参数才有意义 -
确保replication.factor > min.insync.replicas
:若两者相等,那么只要有一个副本挂掉,分区就无法正常工作,虽然有很高的持久性但可用性被极大地降低了。 推荐配置成replication.factor= min.insyn.replicas + 1