Kafka之参数配置

文章目录

  • 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版本

  1. kafka版本1.1.1,可能绝大部分也适用于kafka 0.10.x及以上版本。

Producer参数配置

  1. 官方文档https://kafka.apache.org/documentation/#producerconfigs

bootstrap.servers

  1. 指定一组Broker地址(格式host1:port1,host2:port2,…),比如kafka-master:9092,kafka-slave1:9093,kafka-slave2:9094.如果集群中的实例很多,只需要指定部分broker即可,不需要列出所有的实例地址,kafka会根据提供的地址发现其他的地址

key.serializer

  1. key的序列化类(实现序列化接口),即使 Producer在发送消息时不指定 key,这个参数也是必须要设置的。
  2. key.serializer指定的是实现了org.apache.kafka.common.serialization.Serializer接口的类的全限定名称。

value.serializer

  1. value的序列化类(实现序列化接口),这个参数也是必须要设置的
  2. value.serializer指定的是实现了org.apache.kafka.common.serialization.Serializer接口的类的全限定名称。

acks

  1. 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

  1. buffer.memory:producer 端用于缓存消息的缓冲区大小,单位字节,默认值是 33554432(即32MB)。Java 版本 producer 启动时会首先创建一块内存缓冲区用于保存待发送的消息,然后由另一个专属线程负责从缓冲区中读取消息执行真正的发送
  2. 如果 producer 向缓冲区写消息的速度超过了专属I/O线程发送消息的速度,那么必然造成该缓冲区空间的不断增大,生产者将阻塞max.block.ms之后,抛出异常。
  3. 如果 producer程序要给很多分区发送消息,那么就需要仔细地设置这个参数以防止过小的内存缓冲区降低了 producer程序整体的吞吐量。

max.block.ms

  1. 该配置控制 KafkaProducer.send() 和 KafkaProducer.partitionsFor() 将阻塞多长时间,单位毫秒,默认60000ms。此外这些方法被阻止,也可能是因为缓冲区已满或元数据不可用。在用户提供的序列化程序或分区器中的锁定不会计入此超时。

compression.type

  1. 数据压缩的类型,对应org.apache.kafka.common.record.CompressionType

    • none,这是默认值,表示不压缩
    • gzip
    • snappy
    • lz4:推荐使用此算法
  2. Kafka 对 LZ4 压缩算法的支持是最好的。启用 LZ4 进行消息压缩的producer 的吞吐量是最高的。压缩的性能与producer端的batch大小相关,通常batch越大需要压缩的时间就越长。

    LZ4>>Snappy>GZIP
    
  3. 虽然producer 端引入压缩后可以显著地降低网络 I/O传输开销从而提升整体吞吐量,但也会增加 producer端机器的 CPU开销。如果 broker端的压缩参数设置得与 producer 不同, broker 端在写入消息时也会额外使用 CPU 资源对消息进行对应的解压缩-重压缩操作。

retries

  1. Kafka broker 在处理写入请求时可能因为瞬时的故障 (比如瞬时的leader 选举或者网络抖动)导致消息发送失败。这种故障通常都是可以自行恢复的,如果把这些错误封装进回调函数的异常中返还给 producer, producer 程序也并没有太多可以做的,只能简单地在回调函数中重新尝试发送消息。与其这样,还不如 producer 内部自动实现重试
  2. retries表示进行重试的次数,默认值是 0,表示不进行重试
  3. 如果max.in.flight.requests.per.connection没有设置为1,有可能改变消息发送的顺序,因为如果2个批次发送到一个分区中,第一个失败了并重试,但是第二个成功了,那么第二个批次将超过第一个。
  4. 重试需要注意的问题
    • 重试可能造成消息的重复发送:如果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选举时间并根据该时间来设定retriesretry.backoff.ms的值 )

retry.backoff.ms

  1. 尝试重试指定topic分区的失败请求之前等待的时间。这样可以避免在某些故障情况下高频次的重复发送请求,默认值100ms

batch.size与linger.ms

  1. producer 会将发往同一分区的多条消息封装进一个 batch中,以减少网络交互。当 batch满了的时候, producer会发送 batch 中的所有消息。batch.size默认值16384(16KB),对于吞吐量优先的应用,调大此值会提高性能。
  2. linger.ms就是控制发送延时行为的,默认值时0,表示消息需要立即发送,不需要关系batch是否被填满,对于低延迟的应用来说,这样是合理的。但是对于吞吐量优先的应用,应该调大此值。

max.request.size

  1. producer 端能够发送的最大消息大小,字节为单位,默认1048576(1MB),此参数最好与broker端的message.max .bytes保持一致。

request.timeout.ms

  1. 客户端等待请求响应的最长时间。如果在超时之前未收到响应,客户端将在必要时重新发送请求,如果重试耗尽,则该请求将失败。 这应该大于replica.lag.time.max.ms,以减少由于不必要的生产者重试引起的消息重复的可能性。
  2. request.timeout.ms默认30s,如果broker在30s内都没有给producer发送响应,那么produer就会任务该请求超时了,并在回调函数中显示抛出TimeoutException异常

client.id

  1. 默认空字符串,当发出请求时传递给服务器的id字符串。这样做的目的是允许服务器请求记录这个【逻辑应用名】,这样能够追踪请求的源,而不仅仅只是ip/prot。

enable.idempotence

  1. 当设置为true,生产者将确保一次性语义。请注意,需要将max.in.flight.requests.per.connection设置为1,重试次数不能为零。另外acks必须设置为"all"。如果这些值保持默认值,我们将覆盖默认值。 如果这些值设置为与幂等生成器不兼容的值,则将抛出一个ConfigException异常。

max.in.flight.requests.per.connection

  1. 阻塞之前,客户端单个连接上发送的未应答请求的最大数量,默认时5。注意,如果此设置设置大于1且发送失败,则会由于重试(如果启用了重试)会导致消息重新排序的风险
  2. 一般而言,在需要保持顺序消息的场景下需要把此参数设置为1,避免消息重排序的风险

transaction.timeout.ms

  1. 生产者在主动中止正在进行的交易之前,交易协调器等待事务状态更新的最大时间(以ms为单位,默认60000ms)。如果此值大于broker中的max.transaction.timeout.ms设置,则请求将失败,并报"InvalidTransactionTimeout"错误。

transactional.id

  1. 用于事务传递的Transactional Id。这样可以跨多个生产者会话的可靠性语义,因为它允许客户端保证在开始任何新事务之前使用相同的Transactional Id的事务已经完成。如果没有提供Transactional Id,则生产者被限制为幂等传递。请注意,如果配置了Transactional Id,则必须启用enable.idempotence。 默认值为空,这意味着无法使用事务。

connections.max.idle.ms

  1. 指定在多少毫秒之后关闭闲置的连接,默认540000ms。此值如果设置的太小,Kafka会定期地关闭与Broker的空闲 Socket连接,导致下次 consumer处理请求时需要重新创建Socket连接。
  2. 推荐设置为-1,即永远不要关闭空闲连接。

其他参数

  1. receive.buffer.bytes:读取数据时使用的TCP接收缓冲区(SO_RCVBUF)的大小。默认值32768字节,如果值为-1,则将使用OS默认值。
  2. send.buffer.bytes:发送数据时,用于TCP发送缓存(SO_SNDBUF)的大小。默认值131072字节,如果值为 -1,将使用OS默认值。

Consumer重要参数配置

  1. 官方文档https://kafka.apache.org/documentation/#newconsumerconfigs

group.id

  1. 此Consumer所属消费者组的唯一标识。如果消费者用于订阅或offset管理策略的组管理功能,则此属性是必须的。默认是空字符串

session.timeout.ms

  1. session.timeout.ms 是 consumer group 检测组内成员发送崩溃的时间 。如果设置1min,当某个group成员突然奔溃了,Kafka消费者组协调者(group coordinator)可能需要1min才能感知到。
  2. 在0.10.1.0版本(不包含)之前session.timeout.ms还有另外一个含义,就是consumer 消息处理逻辑的最大时间。倘若 consumer 两次 poll 之间的间隔超过了该参数所设置的阈值,那么 coordinator 就会认为这个 consumer已经追不上组内其他成员的消费进度了, 因此会将该 consumer踢出组,该 consumer负责的分区也会被分配给其他 consumer。好的情况下会导致不必要的rebalance,坏的情况下那些被踢出 group 后处理的消息, consumer 都无法提交位移,即会导致重复消费
  3. 在0.10.1.0版本(包含)之后,session.timeout.ms参数被明确为coordinator检测失败的时间,默认10000ms

max.poll.interval.ms

  1. 使用消费者组管理时poll()调用之间的最大延迟(即用于设置消息处理逻辑的最大时间的)。消费者在获取更多记录之前可以空闲的时间量的上限。如果此超时时间期满之前poll()没有调用,则消费者被视为失败,并且分组将重新平衡,以便将分区重新分配给别的成员。默认300000ms
  2. 比如业务逻辑平均处理时长为20s,则此参数应该设置大于20000ms
  3. 在0.10.1.0版本(不包含)之前使用的是session.timeout.ms,在0.10.1.0版本(包含)之后,session.timeout.ms被拆分成session.timeout.msmax.poll.interval.ms

fetch.min.bytes

  1. 拉取请求返回的最小数据量,默认值是1字节。此值设置的越大服务器等待数据积累的时间越长,可能以一些额外的延迟为代价提高服务器吞吐量,对于延迟敏感的应用调整为可能发送的最小消息字节为好(提前预估大概平均消息字节数)

fetch.max.bytes

  1. 服务器为拉取请求返回的最大数据值,默认52428800字节(50MB)。这不是绝对的最大值,如果在第一次非空分区拉取的第一条消息大于该值,该消息将仍然返回,以确保消费者继续工作。接收的最大消息大小通过message.max.bytes (broker config) 或 max.message.bytes (topic config)定义。注意,消费者是并行执行多个提取的。

fetch.max.wait.ms

  1. 此参数与fetch.min.bytes有些关联,因为如果kafka仅仅参考fetch.min.bytes的值,如果发送方一直不发送消息,那么consumer可能会一直阻塞等待。fetch.max.wait.ms用于指定kafka最大的等待时间,默认值500ms,如果业务应用对延迟比较敏感,可以调小参数。

max.partition.fetch.bytes

  1. 从每个分区里返回给 Consumer的最大数据量 ,默认值为 1048576字节(1MB)。
  2. max.partition.fetch.bytes用来限制一次从每个分区拉取的最大消息大小,fetch.max.bytes限制一次拉取中整体消息大小。

auto.offset.reset

  1. 当Kafka中没有初始offset或如果当前的offset不存在时(例如,该数据被删除了或者位移越界了)的策略
    • earliest:指定从最早的位移开始消费(最早的位移不一定就是0)
    • latest:指定从最新处位移开始消费 ,这是默认值
    • none:指定如果未发现位移信息或位移越界,则抛出异常。
  2. 对于第一次运行consumer Group并且指定earliest开始消费,因为此时group没有任何位移信息,所以该group会从头开始消费所有数据。一旦group成功提交位移后,重启了group(还是配置earliest),此时并不会重头开始消费,因为kafka已经保存了该group的位移信息,因此会无视auto.offset.reset的设置。

enable.auto.commit

  1. enable.auto.commit指定consumer是否自动提交。如果为true,consumer在后台周期性自动提交offset,默认为true。如果为false,需要手动提交offset。
  2. 对于需要"精确处理一次"语义的需求,最好将参数设置为false,手动提交位移。

auto.commit.interval.ms

  1. 如果enable.auto.commit设置为true,则消费者偏移量自动提交给Kafka的频率(以毫秒为单位),默认5000ms

max.poll.records

  1. 在单次调用poll()中返回的最大记录数,默认500。消息比较小,可以适当提高此值

heartbeat.interval.ms

  1. 当 coordinator 决定开启新一轮 rebalance 时,它会将这个决定以 REBALANCE_IN_PROGRESS 异常的形式"塞进" consumer 心跳请求的 response 中,这样其他成员拿到 response 后才能知道它需要重新加入 group。这个过程显然是越快越好,heartbeat.interval.ms就是设置这个时间的
  2. 推荐设置一个比较低的值,让group下的其他consumer成员能尽快感知新一轮rebalance开启了。但是该值必须小于session.timeout.ms,通常不高于1/3,默认3000ms

connections.max.idle.ms

  1. 指定在多少毫秒之后关闭闲置的连接,默认540000ms(9分钟)。此值如果设置的太小,Kafka会定期地关闭与Broker的空闲 Socket连接,导致下次 consumer处理请求时需要重新创建Socket连接。
  2. 推荐设置为-1,即永远不要关闭空闲连接。

request.timeout.ms

  1. 客户端等待请求响应的最长时间。如果在超时之前未收到响应,客户端将在必要时重新发送请求,如果重试耗尽,则该请求将失败。 这应该大于replica.lag.time.max.ms,以减少由于不必要的生产者重试引起的消息重复的可能性。
  2. request.timeout.ms默认3000ms,如果broker在30s内都没有给consumer发送响应,那么consumer就会任务该请求超时了

exclude.internal.topics

  1. Kafka 中有两个内部的主题:_consumer_offsets_transaction_state。exclude.internal.topics 用来指定 Kafka 中的内部主题是否可以向消费者公开,默认值为 true。如果设置为 true,那么只能使用 subscribe(Collection)的方式而不能使用 subscribe(Pattern)的方式来订阅内部主题,设置为 false 则没有这个限制。

其他配置

  1. bootstrap.servers含义与Producer相同、key.deserializervalue.deserializer,与Producer序列化类似,这里是反序列化

Broker重要参数

zookeeper.connect

  1. broker要连接的zookeeper地址加端口号,多个地址使用都好分隔,比如

    zookeeper.connect=zk-master:2181,zk-slave1:2181,zk-slave2:2181
    
  2. 最佳实践是再加一个chroot路径(不指定默认使用zookeeper根路径),可以实现多个kafka集群服用一套zookeeper集群,可以节省机器资源。

    zookeeper.connect=zk-master:2181,zk-slave1:2181,zk-slave2:2181/kafka
    

listeners

  1. broker监听客户端连接的地址列表,配置格式为协议://hostname:port,多个使用逗号分隔。kafka支持的协议类型有PLAINTEXT,SSL,SASL_SSL.如果未开启安全认证,则直接使用PLAINTEXT即可

    listeners=PLAINTEXT://kafka-master:9092
    
  2. 如果不指定主机名,则表示绑定默认网卡,如果默认绑定到127.0.0.1,则无法对外提供服务。如果主机名是 0.0.0.0,则表示绑定所有的网卡

advertised.listeners

  1. 与 listeners类似,该参数也是用于发布给 clients 的监听器,不过该参数主要用于 IaaS 环境,比如云上的机器通常都配有多块网卡(私网网卡和公网网 卡)。对于这种机器,用户可以设置该参数绑定公网 IP供外部clients使用,然后配置上面的 listeners来绑定私网IP供 broker间通信使用。当然不设置该参数也是可以的, 只是云上的机器很容易出现 clients 无法获取数据的问题,原因就是 listeners 绑定的是默认网卡,而默认网卡通常都是绑定私网 IP 。在实际使用场景中,对于配有多块网卡的机器而言,这个参数通常都是需要配置的。

broker.id

  1. 指定 Kafka 集群中 broker 的唯一标识,默认值为-1.如果没有设置kafka会自动生成一个唯一值。

log.dir与log.dirs

  1. log.dir用来配置单个根目录,而log.dirs用来配置多个根目录,多个使用逗号分隔。
  2. log.dirs保存日志数据的目录,多个目录使用逗号分隔,生产环境一般情况下需要指定多个目录,这样kakfa可以把负载均匀地分配到多个目录下,如果使用多块磁盘,每个目录挂载一个磁盘,则多块磁盘可以同时写,极大提升吞吐量。如果未设置,则使用log.dir中的值,即log.dirs的优先级高。默认情况下只配置log.dir,默认值为/tmp/kafka-logs。

unclean.leader.election.enable

  1. 是否开启 unclean leader选举,在kafka 0.11.0 版本开始默认为false,之前版本是true
  2. ISR 中的所有副本都有资格随时成为新的 leader,但若 ISR变空而此时 leader又宕机了, Kafka应该如何选举新的 leader呢?为false表示不允许从剩下存活的非ISR副本中选择一个当 leader,因为这可能会导致消息丢失。

message.max.bytes

  1. 服务器可以接收的消息的最大大小,默认值为1000012字节(977KB,约等于1MB)

delete.topic.enable

  1. 是否允许kafka删除topic,kafka1.0.0版本默认为true,kafka1.0.0版本之前默认为false。如果为false,并不会真正的删除topic

消息删除策略

  1. log.retention.{hours|minutes|ms}:消息数据的留存时间,默认配置是log.retention.hours=168,即7天
  2. log.retention.bytes:消息日志的总大小,默认-1表示不会通过消息总大小判断是否需要删除

min.insync.replicas

  1. 配合producer的ack参数使用。只有ack=-1,配置min.insync.replicas才有意义,表示broker端必须成功响应 clients 消息发送的最少副本数。
  2. 在实际使用中,假设每个分区有3个副本,如果min.insync.replicas=2,则表示能容忍一台broker宕机而不影响服务。如果设置为min.insync.replicas=3,则只要任何一台broker宕机,整个kafka集群将不可用。

num.network.threads

  1. num.network.threads控制broker在后台用于处理网络请求(转发请求)的线程数,默认为3.

num.io.threads

  1. broker用于执行网络请求的io线程数,默认为8

Broker-Topic参数

  1. 每个topic可以设置自己的参数,即可以覆盖全局broker配置。

  2. 可以在创建主题时通过提供一个或多个–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
    
  3. 创建topic后修改

    bin/kafka-configs.sh --zookeeper localhost:2181 --entity-type topics --entity-name my-topic --alter --add-config max.message.bytes=128000
    
  4. 检查是否生效

    bin/kafka-configs.sh --zookeeper localhost:2181 --entity-type topics --entity-name my-topic --describe
    
  5. 删除

    bin/kafka-configs.sh --zookeeper localhost:2181  --entity-type topics --entity-name my-topic --alter --delete-config max.message.bytes
    

delete.retention.ms

  1. 每个 topic可以设置自己的日志留存时间以覆盖全局默认值

max.message.bytes

  1. 覆盖全局的 message.max.bytes,为每个 topic 指定不同的最大 消息尺寸

retention.bytes

  1. 覆盖全局的 log.retention.bytes,每个 topic 设置不同的日志留存尺寸

auto.create.topics .enable

  1. 默认true,当Producer向一个尚未创建的主题发送消息时,会自动创建一个分区数为 num.partitions (默认值为 1)、副本因子为 default.replication.factor (默认值为 1)的Topic
  2. 当一个Consumer开始从未知主题中读取消息时,或者当任意一个客户端向未知主题发送元数据请求时,都会按照配置参数 num.partitions 和 default.replication.factor 的值来创建一个相应的主题
  3. 不建议将 auto .create.topics. enable 参数设置为 true,这个参数会增加topic的管理与维护的难度。

无消息丢失配置

  1. 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 会被允许将未完成的消息发送出去, 这样就有可能造成消息乱序
  2. 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

你可能感兴趣的:(#,Kafka实战)