以下是我们的物联网平台中的入站消息流:
Device ---(MQTT)---> RabbitMQ Broker ---(AMQP)---> Apache Storm ---> Kafka
我希望实施一个解决方案,有效地限制/限制每个客户每秒发布到Kafka的数据量。
现有的策略使用Guava的RateLimiter,其中每个设备都有自己的本地缓存实例。收到设备消息时,将从缓存中获取映射到该deviceId的RateLimiter,并调用tryAquire()
方法。如果成功获得许可证,则会像往常一样将元组转发给Kafka,否则会超出配额并且会默默地丢弃消息。这种方法相当麻烦,在某些时候注定要失败或成为瓶颈。
我一直在阅读Kafka的字节速率配额,并相信这在我们的情况下会完美运行,特别是因为Kafka客户端可以动态配置。在我们的平台中创建虚拟设备时,应在client.id == deviceId
。
让我们假设以下用例为例:
这是我的问题。如果使用单个Producer实例,是否可以在调用client.id
之前在ProducerRecord或Producer中的某个位置指定send()
?如果生产者只允许一个client.id
,这是否意味着每个设备必须有自己的生产者?如果只允许一对一映射,那么是否明智地缓存可能有数百个(如果不是数千个)生产者实例,每个设备一个?有没有更好的方法我还没有意识到?
注意:我们的平台是一个"开门系统"意味着客户永远不会收到错误回复,例如"费率超过"或者任何错误。它对最终用户都是透明的。出于这个原因,我无法干扰RabbitMQ中的数据或将消息重新路由到不同的队列..我唯一的选择是集成这些东西,在Storm或Kafka之间。
答案 0 :(得分:0)
虽然您可以在client.id
对象上指定Producer
,但请记住它们是重量级的,您可能不愿意为它们创建多个实例(特别是在每个设备的基础上)。 / p>
关于减少Producer
的数量,您是否考虑过按用户而不是按设备创建一个,或者甚至有一个有限的共享池?然后可以使用Kafka消息头来辨别实际生成数据的设备。缺点是您需要限制消息生成,以便一台设备不会从其他设备获取所有资源。
但是,您可以限制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
)答案 1 :(得分:0)
您可以按以下应用程序配置client.id
:properties.put ("client.id", "humidity")
或properties.put ("client.id", "temp")
根据每个client.id
,您可以设置值
producer_byte_rate = 1024, consumer_byte_rate = 2048,
request_percentage = 200
怀疑我是否与此配置(producer_byte_rate = 1024, consumer_byte_rate = 2048, request_percentage = 200
)有关,由于使用者工作正常,生产者未采用插入的配置