卡夫卡生产者配额
这里是我们的物联网平台的入站邮件传递流程:卡夫卡生产者配额
Device ---(MQTT)---> RabbitMQ Broker ---(AMQP)---> Apache Storm ---> Kafka
我期待实现解决方案,有效地限制/节流数据以每个发布到卡夫卡每秒量客户基础。
当前的策略利用Guava的RateLimiter,每个设备都有自己的本地缓存实例。当接收到设备消息时,映射到该deviceId的RateLimiter从缓存中获取并调用tryAquire()
方法。如果许可证被成功获得,那么该元组像往常一样被转发到卡夫卡,否则超出配额,并且消息被无声地丢弃。这种方法相当麻烦,并且在某种程度上注定要失败或成为瓶颈。
我一直在阅读卡夫卡的字节率配额,并相信这可以在我们的案例中完美工作,尤其是因为可以动态配置卡夫卡客户端。当在我们的平台上创建虚拟设备时,应该添加一个新的client.id,其中client.id == deviceId
。
让我们假定以下使用情况为例:
- 管理员创建2个虚拟设备:湿度&温度传感器
- 规则被激发到对于上述装置 创建卡夫卡新用户/的clientId条目
- 通过卡夫卡CLI
- 设置它们的生产配额值两款器件发出的入站事件消息
- ...?
这是我的问题。如果使用单个Producer实例,是否可以在调用send()
之前在ProducerRecord中或Producer的某处指定client.id
?如果一个生产者只允许一个client.id
,这是否意味着每个设备都必须有自己的生产者?如果只允许一对一的映射,那么缓存数百甚至数千个Producer实例是否明智呢,每个设备一个呢?有没有更好的方法我还没有意识到?
注意:我们的平台是一个“开门系统”,意味着客户永远不会收到错误响应,例如“超出率”或任何错误。这对最终用户来说都是透明的。出于这个原因,我不能干涉RabbitMQ中的数据或将消息重新路由到不同的队列。我唯一的选择是整合这些东西,位于Storm或Kafka之间。
尽管您可以在Producer
对象上指定client.id
,但请记住它们是重量级的,并且您可能不希望创建它们的多个实例(尤其是基于每个设备一个实例)。
关于减少Producer
的数量,您是否考虑过在每个用户的基础上创建一个,而不是基于每个设备的基础,甚至是否有共享池?然后可以使用Kafka消息标题来辨别哪个设备实际产生了数据。缺点是你需要抑制消息生产,这样一台设备就不会从其他设备获取所有资源。
但是,您可以限制对卡夫卡代理端用户,以配置适用于默认的用户/客户端:
> bin/kafka-configs.sh --zookeeper localhost:2181 --alter --add-config 'producer_byte_rate=1024,consumer_byte_rate=2048,request_percentage=200' --entity-type clients --entity-default
Updated config for entity: default client-id.
在深入更多的例子,并交代见https://kafka.apache.org/documentation/#design_quotas。
的消息是如何辨别取决于你的架构,可能的解决方案包括:
- 每个用户的话题/分区(例如
data-USERABCDEF
) 如果你决定使用共同的话题
- ,那么你就可以把生产数据为邮件标题 - https://kafka.apache.org/0110/javadoc/index.html?org/apache/kafka/common/header/Headers.html,或者你可以把它们放到有效载荷本身
_你能不能细说,请与expla“海边的卡夫卡消息头可以被用来辨别哪些设备实际产生的数据。”在如何实现它?即使我是以每个用户为基础做的,但我仍然需要弄清楚如何告诉Kafka,消息X源自客户端1,消息Y源自客户端2,等等......所有这些都通过* *单**,共享生产者实例。 – user2208562