node-rdkafka和kafkajs对比
node-rdkafka 和 kafkajs 都是用于在Node.js中操作Apache Kafka的组件库。
如果你对Kafka的高级功能有较高的要求,可以选择node-rdkafka。
如果你更倾向于使用纯JavaScript实现、简洁和轻量级的库,可以选择kafkajs。
实践出真知
kafkajs不支持设置rebalance分配策略
kafkajs默认是支持roundrobin轮询策略,这就会导致其中一个消费者移除后,所有消费者都会被rebalance。
所以不支持cooperative-sticky策略
参照issue:github.com/tulios/kafk…
kafkajs不支持设置session.timeout.ms和group.instance.id等配置
node-rdkafka支持设置partition.assignment.strategy
配置了rebalance_cb之后,cooperative-sticky不生效,起多个消费者时,不会进行分区;
这就导致cooperative-sticky时,无法监听rebalance回调
参照issue:github.com/Blizzard/no…
node-rdkafka headers不支持自定义的Buffer传输
由于node-kafka底层会默认将headers里的值,转成string进行传输,这就导致,若是有自定义的规范,发送后就会被编码出问题
参照issue:github.com/Blizzard/no…
以下示例:requestId为"76c9349a-6bcd-40e7-8965-4afdd6404dc4"
requestId是有自定义的封装规则,不能直接通过Buffer.from编码和toString解码
当我给requestId传入自定义的Buffer后,消费者消费到的跟生产时不一致
生产的headers
消费者消费到的headers
解决方案
- 和后端约定好规则,只用Buffer.from和toString编解码。
- npm安装 @nora/node-rdkafka 库,该库是我参照issue进行的改动。
Rebalance
弊端
- Rebalance 影响 Consumer 端 TPS,Coordinator 协调者组件完成订阅主题分区的分配的过程,该消费组下所有实例都不能消费任何消息。
- 如果你的组成员消费者实例很多的话,Rebalance 很慢,对业务会造成一定的影响。
- Rebalance 效率不高。当前 Kafka 的设计机制决定了每次 Rebalance 时,Consumer Group 下的所有成员都要参与进来,而且通常不会考虑局部性原理,但局部性原理对提升系统性能是特别重要的。
触发 Rebalance 机制的时机主要有:
- 有新的 Consumer 加入 Consumer Group
- 有 Consumer 宕机下线。Consumer 并不一定需要真正下线,例如遇到长时间的 GC、网络延迟导致消费者长时间未向 GroupCoordinator 发送 HeartbeatRequest 时,GroupCoordinator 会认为 Consumer 下线。
- 有 Consumer 主动退出 Consumer Group(发送 LeaveGroupRequest 请求)。比如客户端调用了 unsubscribe() 方法取消对某些主题的订阅。
- Consumer 消费超时,没有在指定时间内提交 offset 偏移量。
- Consumer Group 所对应的 GroupCoordinator 节点发生了变更。
- Consumer Group 所订阅的任一主题或者主题的分区数量发生变化。
partition.assignment.strategy配置
以下实验基于node-rdkafka库
定义12个分区,起5个消费者,归为同一个消费组,并订阅同一个topic
range
当移除第三个消费者
现象:所有的分区被重新依次分配
roundrobin
当移除第三个消费者
现象:所有的分区被重新依次分配
cooperative-sticky
当策略为cooperative-sticky,若配置了rebalance_cb,那么策略就会无效,不会给任何的消费这分配分区
移除第三个消费者
现象:会发现原先第三个消费者的分区,给了临近的4和5
再将第三个消费者加入
现象:有一定的黏性,但观察下来,不是100%
session.timeout.ms和group.instance.id配置
session.timeout.ms超过该值而没有任何心跳发送给 Broker,Broker 会剔除 Consumer,进行 Reblance。
对于 group.instance.id
配置不为空的,会再等待 session.timeout.ms
的时间才 Rebalance。