卡夫卡生产者配额

卡夫卡生产者配额

问题描述:

这里是我们的物联网平台的入站邮件传递流程:卡夫卡生产者配额

Device ---(MQTT)---> RabbitMQ Broker ---(AMQP)---> Apache Storm ---> Kafka 

我期待实现解决方案,有效地限制/节流数据以每个发布到卡夫卡每秒量客户基础。

当前的策略利用Guava的RateLimiter,每个设备都有自己的本地缓存实例。当接收到设备消息时,映射到该deviceId的RateLimiter从缓存中获取并调用tryAquire()方法。如果许可证被成功获得,那么该元组像往常一样被转发到卡夫卡,否则超出配额,并且消息被无声地丢弃。这种方法相当麻烦,并且在某种程度上注定要失败或成为瓶颈。

我一直在阅读卡夫卡的字节率配额,并相信这可以在我们的案例中完美工作,尤其是因为可以动态配置卡夫卡客户端。当在我们的平台上创建虚拟设备时,应该添加一个新的client.id,其中client.id == deviceId

让我们假定以下使用情况为例:

  1. 管理员创建2个虚拟设备:湿度&温度传感器
  2. 规则被激发到对于上述装置
  3. 创建卡夫卡新用户/的clientId条目
  4. 通过卡夫卡CLI
  5. 设置它们的生产配额值两款器件发出的入站事件消息
  6. ...?

这是我的问题。如果使用单个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

的消息是如何辨别取决于你的架构,可能的解决方案包括:

+0

_你能不能细说,请与expla“海边的卡夫卡消息头可以被用来辨别哪些设备实际产生的数据。”在如何实现它?即使我是以每个用户为基础做的,但我仍然需要弄清楚如何告诉Kafka,消息X源自客户端1,消息Y源自客户端2,等等......所有这些都通过* *单**,共享生产者实例。 – user2208562