V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
fatyoung
V2EX  ›  程序员

生产环境消息堆积如何处理?

  •  
  •   fatyoung · 334 天前 · 2332 次点击
    这是一个创建于 334 天前的主题,其中的信息可能已经有所发展或是发生改变。
    我的想法是
    机器配置上:增加分区 partition ,增加组内 consumer ,并最好让分区跟 consumer 数量比例为 1:1
    代码上:一般消息堆积都是 consumer 消费逻辑里有长时间 I/O 行为导致,所以可以在 consumer 中开启多线程消费
    面试官反问:还有其他方法吗? 还有,如果我想这个分区的消息都可以顺序消费,开启多线程怎么保证顺序消费?
    如何回答?
    15 条回复    2024-01-01 20:14:11 +08:00
    cyaki
        1
    cyaki  
       334 天前
    只用增加 partition 就完事吧, 得注意增加 partition 时, 会暂时性打乱消息顺序.
    因为上面这个原因, 所以最好 partition 数量在一开始时就多设置一点
    后面消息堆积时, 就只能增加 consumer 就好了

    代码上建议保持原样或者缩短长 IO 行为, 不必要引入多线程来增加复杂度
    cyaki
        2
    cyaki  
       334 天前
    @cyaki 还有增加节点数, 提高整个集群的读写能力上限
    cyaki
        3
    cyaki  
       334 天前
    @cyaki 还有看消息分布, 是不是集中分布到了部分 parition 上, 导致 consumer 无法处理过来
    abcfyk
        4
    abcfyk  
       334 天前
    无论什么问题
    1. 先确定问题背景和现状
    2. 确定问题原因

    第三步才是设计解决方案
    fatyoung
        5
    fatyoung  
    OP
       334 天前
    @cyaki 谢谢老哥的回复。对我当时也是想到消息可能因为是根据 key 分区然后都打到同一个分区去了,但是我没想到解决方案,将分区策略从根据 key 分区改为轮询?
    fatyoung
        6
    fatyoung  
    OP
       334 天前
    @abcfyk 谢谢老哥回复。确实是,我应该先问一句因为什么导致的消息堆积
    admol
        7
    admol  
       334 天前
    如果是面试这样回答肯定是有些问题的,你这个回答感觉应该是在设计之初就要想到的方案

    堆积的消息重要吗?
    - 不重要,过期未处理的消息;都是可以直接删除的
    - 重要;那你就得考虑为什么导致消息堆积了,生产者变快还是消费者变慢都有不同的处理方式,比如你说的开启多线程消费,或者还有生产者限流(不推荐)

    还可以从事前、事中、事后再考虑下发生这些问题该怎么处理
    chutianyao
        8
    chutianyao  
       334 天前
    得考虑消费能力啊, 有些场景就是因为下游处理能力不足, 才用消息进行削峰填谷的. 比如异步落库, 你一股脑扩实例、增加队列、并行消费等措施全搞上, 堆积是没有了, 结果把数据库打挂了
    fatyoung
        9
    fatyoung  
    OP
       334 天前
    @chutianyao 谢谢老哥回复。那生产环境数据库如何扩容呢? 这个倒是没有考虑过
    fatyoung
        10
    fatyoung  
    OP
       334 天前
    @fatyoung #9 分库分表? 但是短期内应该做不了这么大改动吧
    fatyoung
        11
    fatyoung  
    OP
       334 天前
    @admol 谢谢老哥回复。是重要的消息,不能直接 purge
    justplaymore
        12
    justplaymore  
       334 天前
    分开看消息的处理流程
    1.从消息队列中取消息
    2.用消息去执行业务逻辑

    当 1 和 2 同步时,就容易产生消息队列的消息堆积,影响线上增量实时消息。
    当 1 和 2 异步时,取消息速度非常快,不会产生消息堆积,把取到的消息放到另外的存储介质里,异步取数据慢慢执行业务逻辑。

    消息顺序性是有局限性的,基于什么范围内要保证顺序的?全局?单个用户?单个门店?单个商户?顺序性的范围越小,维护成本越低,并发处理性能越高。
    potatowish
        13
    potatowish  
       334 天前 via iPhone
    单个分区开启多线程了还怎么保证顺序呢,后面再进行的一系列保证顺序的操作,都会使它串行化。一般我们会有一个配置,当队列长度超过一个阈值时,就先切换到异步落库模式,然后小批量拉数据进行消费。
    qianckjuan
        14
    qianckjuan  
       334 天前
    我自己遇到的,是因为有重试逻辑,但是大概率会 fail ,所以消费多少基本就会重试多少,会堆积,导致怎么增加 consumer 都没有用。
    还是要看为什么堆积的
    julyclyde
        15
    julyclyde  
       330 天前
    如果都是值钱的业务数据,那恭喜你锻炼的机会到了
    如果是垃圾数据,比如直接删了算

    分享一个古代我遇到的类似情况
    https://julyclyde.org/?p=512
    是软件本身的设计问题
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5512 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 08:58 · PVG 16:58 · LAX 00:58 · JFK 03:58
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.