主要介绍下kafka的producer配置参数,只取了其中的一部分常用的,后续的有时间,也会补充一些,更多的详细参数,可以参考《kafka官网》,参数的内容,主要是选取《apache kafka实战》书中的一些讲解和官网相互参看
和 Java 版本 producer 相同,这是必须要指定的参数。该参数指定了一组 host:port 对,用于 创建与 Kafka broker 服务器的 Socket 连接 。 可以指定多组,使用逗号分隔,如kafkal :9092,kafka2:9092,kafka3 :9092。在实际生产环境中需要替换成线上 broker 列表。
另外,若 Kafka集群中 broker 机器数很多,我们只需要指定部分 broker 即可,不需要列出完整的 broker 列表 。这是因为不管指定了几台机器, consumer 启动后都能通过这些机器找到完整的 broker 列表,因此为该参数指定多台机器通常只是为了常规的 failover 使用 。 这样即使某一台 broker 挂掉了,consumer 重启后依然能够通过该参数指定的其他 broker 连接 Kafka 集群。
需要注意的是,如果 broker 端没有显式配置 listeners (或 advertised.listeners )使用 IP 地址的话,那么最好将 bootstrap.servers 配置成主机名而不要使用 IP 地址,因为Kafka 内部使用的是全称域名( FQDN, Fully Qualified Domain Name )。倘若不统一 , 会出现无法获取元数据的异常。
该参数指定的是 consumer group 的名字。它能够唯一标识一个 consumer group o 细心的读者可能会发现宫网上该参数是有默认值的,即一个空字符串 。 但在开发 consumer 程序时我们依然要显式指定 group.id ,否则 consumer 端会抛出 InvalidGroupldException 异常 。
通常为group.id 设置一个有业务意义的名字就可以了。
consumer 代码从 broker 端获取的任何消息都是宇节数组的格式,因此消息的每个组件都要执行相应的解序列化操作才能“还原”成原来的对象格式 。 这个参数就是为消息的 key 做反序列化的 。
该参数值必须是实现 org.apache .kafka.common.serialization.Deserializer 接口的 Java类的全限定名称。
Kafka 默认为绝大部分的初始类型( primitive type )提供了现成的解序列化器。上面代码中使用了 org.apache.kafka.common.serialization.StringDeserializer 类。 该类会将接收到的字节数组转换成 UTF-8 编码的字符串。 consumer 支持用户自定义 deserializer, 这通常都与 producer 端自定义 serializer “遥相呼应”。值得注意的是,不论 consumer 消费的消息是否指定了间, consumer 都必须要设置这个参数,否则程序会抛出 ConfigException,提示“key.deserializer” 没有默认值。
与 value.deserializer 类似,该参数被用来对消息体(即消息 value )进行反序列化,从而把消息“还原”回原来的对象类型。
value.deserializer 可以设置成与key.deserializer 不同的值,前提是 key.serializer 与 value.serializer 设置了不同的值 。
在使用过程中,我们一定要谨记 key.deserializer 和 value.deserializer 指定的是类的全限定名,单独指定类名是行不通的 。
非常重要的参数之一 !
session.timeout.ms
是 consumer group 检测组内成员发送崩溃的时间 。
假设你设置该参数为 5 分钟,那么当某个 group 成员突然崩攒了(比如被 kill -9 或岩机), 管理 group 的 Kafka 组件(即消费者组协调者,也称 group coordinator)有可能需要 5 分钟才能感知到这个崩溃。显然我们想要缩短这个时间,让coordinator 能够更快地检测到 consumer 失败 。
这个参数还有另外一重含义 :consumer 消息处理逻辑的最大时间。
倘若 consumer 两次 poll 之间的间隔超过了该参数所设置的阑值,那么 coordinator 就会认为这个 consumer 己经追不上组内其他成员的消费进度了,因此会将该 consumer 实例“踢出”组,该 consumer 负责的分区也会被分配给其他 consumer。
在最好的情况下,这会导致不必要的 rebalance,因为 consumer 需要重新加入 groupo 更糟的是,对于那些在被踢出 group 后处理的消息, consumer 都无法提交位移一一这就意味着这些消息在rebalance 之后会被重新消费一遍。如果一条消息或一组消息总是需要花费很长的时间处理,那么 consumer 甚至无法执行任何消费,除非用户重新调整参数 。鉴于以上的“窘境”, Kafka 社区于 0 .10.1.0 版本对该参数的含义进行了拆分 。 在该版本及以后的版本中, session.timeout.ms 参数被明确为“ coordinator 检测失败的时间” 。
因此在实际使用中,用户可以为该参数设置一个比较小的值,让 coordinator 能够更快地检测 consumer 崩溃的情况,从而更快地开启 rebalance,避免造成更大的消费滞后( consumer lag ) 。 目前该参数的默认值是 10 秒。
如前所述, session. neout.ms 中“ consumer 处理逻辑最大时间”的含义被剥离出来了,
Kafka 为 i主部分含义单独开放了 一个参数一一max.poll.interval.ms 。在一个典型的 consumer 使用
场景中,用户对于消息的处理可能需要花费很长时间。这个参数就是用于设置消息处理逻辑的
最大时间的 。 假设用户的业务场景中消息处理逻辑是把消息、“落地”到远程数据库中,且这个
过程平均处理时间是 2 分钟,那么用户仅需要将 max.poll.interval.ms 设置为稍稍大于 2 分钟的值
即可,而不必为 session. neout.ms 也设置这么大的值。
通过将该参数设置成实际的逻辑处理时间再结合较低的 session.timeout.ms 参数值,
consumer group 既实现了快速的 consumer 崩溃检测,也保证了复杂的事件处理逻辑不会造成不
必要的 rebalance 。
指定了无位移信息或位移越界(即 consumer 要消费的消息的位移不在当前消息日志的合理区间范围)时 Kafka 的应对策略 。 特别要注意这里的无位移信息或位移越界,只有满足这两个条件中的任何一个时该参数才有效果 。
关于这一点,我们举一个实际的例子来说明 。 假设你首次运行一个 consumer group 并且指定从头消费 。 显然该 group 会从头消费所有数据,因为此时该 group 还没有任何位移信息 。 一旦该 group 成功提交位移后,你重启了 group,依然指定从头消费 。 此时你会发现该 group 并不会真的从头消费一一因为 Kafka 己经保存了该 group 的位移信息,因此它会无视 auto.offset.reset 的设置。
目前该参数有如下 3 个可能的取值 :
该参数指定 consumer 是否自动提交位移 。
若设置为 true,则 consumer 在后台自动提交位移;
否则,用户需要手动提交位移。
对于有较强“精确处理一次”语义需求的用户来说,最好 将该参数设置为 false,由用户自行处理位移提交问题 。
一个经常被忽略的参数。它指定了 consumer 端单次获取数据的最大字节数 。 若实际业务消息很大,则必须要设置该参数为一个较大的值,否则 consumer 将无法消费这些消息 。
该参数控制单次 poll 调用返回的最大消息数 。
比较极端的做法是设置该参数为 1,那么每次 poll 只会返回 1 条消息。如果用户发现 consumer 端的瓶颈在 poll 速度太慢,可以适当地增加该参数的值。如果用户的消息处理逻辑很轻量,默认的 500 条消息通常不能满足实际的消息处理速度 。
该参数和 request.timeout.ms
、max.poll.interval.ms
参数是最难理解的 consumer 参数 。 前面己经讨论了后两个参数的含义,这里解析一下heartbeat.interval.ms
的含义及用法 。
从表面上看,该参数似乎是心跳的问隔时间,但既然己经有了上面的 session.timeout.ms 用于设置超时,为何还要引入这个参数呢?
这里的关键在于要搞清楚 consumer group 的其他成员,如何得知要开启新一轮 rebalance;当 coordinator 决定开启新一轮 rebalance 时,它会将这个决定以 REBALANCE_IN_PROGRESS 异常的形式“塞进” consumer 心跳请求的 response 中,这样其他成员拿到 response 后才能知道它需要重新加入 group。显然这个过程越快越好,而heartbeat. interval.ms 就是用来做这件事情的 。
比较推荐的做法是设置一个比较低的值,让 group 下的其他 consumer 成员能够更快地感知新一轮 rebalance. 开启了。
注意,该值必须小于 session.timeout.ms !这很容易理解,毕竟如果 consumer 在 session.timeout.ms 这段时间内都不发送心跳, coordinator 就会认为它已经 dead,因此也就没有必要让它知晓 coordinator 的决定了。
这又是一个容易忽略的参数!经常有用户抱怨在生产环境下周期性地观测到请求平均处理时间在飘升,这很有可能是因为 Kafka 会定期地关闭空闲 Socket 连接导致下次 consumer 处理请求时需要重新创建连向 broker 的 Socket 连接 。
当前默认值是 9 分钟,如果用户实际环境中不在乎这些Socket资源开销,比较推荐设置该参数值为-1
,即不要关闭这些空闲连接。