V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
daimaosix
V2EX  ›  程序员

请教消息队列的选择

  •  
  •   daimaosix · 1 天前 via Android · 447 次点击
    目前正在调研 Kafka 和 RabbitMQ ,项目需要给每个客户创建一个主题,该主题下客户所有的设备作为消费者,每台设备独立消费并确认消费结果,客户端和服务端均使用 Rust 编写,发现 Kafka 对于消费结果确认似乎不如 RabbitMQ 方便,可能需要自己实现。但 Kafka 性能要比 RabbitMQ 优异,所以就不太清楚选择哪一个比较合适。
    另外对于负载能力,这个项目是安全相关,如果攻击量比较大,那可能对于消息队列而言并发就比较大,暂时预估 3000-5000 这样子吧。消息不需要持久存储,属于消费者实时快速消费完可以直接删除。
    有经验的老哥多谢指导!
    10 条回复
    keakon
        1
    keakon  
       1 天前   ❤️ 1
    RabbitMQ 在低负载(< 30 MB/s )下延迟更低,资源开销、易用性和稳定性都更好。但是如果 topics 过多,例如上千,就会显著影响性能。当然你也可以多部署几个 RabbitMQ ,将不同客户打散到不同的实例,让每个实例的 topics 减少。
    Kafka 的内存开销很大(毕竟 Java ),稳定性不够好,但是 topics 增长基本不影响性能。
    souryou
        2
    souryou  
       1 天前
    恰巧两个都用过,不过没在 rust 下用过

    1.对于这个 '发现 Kafka 对于消费结果确认似乎不如 RabbitMQ 方便' 我没有太理解不方便指具体是哪方面,我看 [demo]( https://github.com/kafka-rust/kafka-rust/blob/master/examples/example-consume.rs#L47) 中没有太复杂

    2. 你所提到的 3000-5000 负载远远没有达到他俩的正常运行阈值,所以这点应该没啥问题,这个量再 X10 的话推荐 Kafka

    3. 'Kafka 性能要比 RabbitMQ 优异' ,这个也得结合具体项目来看,按照你说的极端情况在 5k 左右的话,他俩哪个都没有问题

    4. 其他方面还要根据项目、人员使用熟练度来选

    **注意 ** : 一个客户一个主题,客户下设备数量需要考虑

    kafka 根据 consumer 多于 partition 数量会闲置,rabbit 默认是轮训
    daimaosix
        3
    daimaosix  
    OP
       1 天前
    @keakon 如果只有一个消费者只创建一个主题,那将所有用户的客户端全部作为消费者来消费这一个主题,让消费者来根据消息内容中的用户 ID 来决定是否消费,这样是否可行呢?
    daimaosix
        4
    daimaosix  
    OP
       1 天前
    @souryou
    1.因为 Kafka 消费者对于消息的消费成功与否根据偏移量来进行,而 RabbitMQ 原生就支持从队列中确认消息是否未消费或者已消费或者忽略消费,这种状态控制比较明确,而 Kafka 需要在程序中实现消息消费状态的计数等。

    感谢最后提及的,客户下的消费者这个没办法控制,可能多大几十个,也有可能只有几个这样子,具体按照用户的服务器数量来
    keakon
        5
    keakon  
       1 天前
    @daimaosix 假设你有 1000 个 topics ,5000 个客户端。
    原方案是某个 topic 收到消息,只会通知 5 个客户端来获取消息。
    你的方案会导致 5000 个客户端来获取消息,然后大部分丢弃掉。
    性能差异可想而知。

    此外,RabbitMQ 默认是不允许同一条消息被多个消费者并发消费的,需要使用 Fanout Exchange 。此时每个消费者都是一个单独的队列,即变成 5000 条队列,发布消息的开销会增大 5000 倍。
    souryou
        6
    souryou  
       1 天前
    @daimaosix
    1. 它俩的确认应该都不用在编程逻辑中处理,需要处理的就是消息去重逻辑,避免二次消费

    2. 对于 consumer 数量问题,是不是可以考虑每个客户对应一个 agent 来消费来自这个客户的 topic ,然后在根据服务器 ip 、mac 等唯一参数,进一步划分二级 topic ;或者根据客户 ID 加上服务器 ID 直接细化 topic ,但是每引进一个中间(件)过程,系统的鲁棒性就多一次考验。


    将所有用户的客户端全部作为消费者来消费这一个主题,让消费者来根据消息内容中的用户 ID 来决定是否消费,这样是否可行呢?

    不建议这么搞。这个无用处理有点儿多(每个机器处理客户机器数量 n 的消息,但是有 n-1 是忽略的),而且属于广播模式,恰巧应该消费的机器由于网络或真实掉线,消息容易丢失。
    daimaosix
        7
    daimaosix  
    OP
       1 天前
    @keakon
    @souryou
    感谢两位老哥的宝贵建议。我现在考虑使用 RabbitMQ 的路由模式,为每个用户的消费者指定唯一的路由键,确保消息只被需要的消费者消费,因为业务逻辑不是很复杂,能确保消息抵达对应用户的消费者即可。

    但如果消费者过多,比如超过 1000+,这可能就需要分片或集群了....
    flmn
        8
    flmn  
       1 天前
    你这个场景,这俩都不合适啊。

    MQTT 比较合适。
    daimaosix
        9
    daimaosix  
    OP
       1 天前
    @flmn 为啥啊大哥
    flmn
        10
    flmn  
       15 小时 21 分钟前
    @daimaosix 因为你提到了设备,而 MQTT 是物联网消息队列/订阅事实上的标准,我感觉很适合你的场景,你调研一下
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1351 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 20ms · UTC 17:25 · PVG 01:25 · LAX 10:25 · JFK 13:25
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.