最近线上es在更新数据时,经常在gc时压力很大,大量报错429,请求被reject。
为了解决这一问题,我们分了两步走,第一步是引入重试队列,将报错的数据延时重试。保证最起码的数据不会丢。
第二步是引入限流,在es gc时,减少最大并发更新的协程数量,es恢复后,再恢复,也是类似于熔断检测的原理。
在选取延迟队列技术方案时,有如下方案可供选择:
方案1
使用redis zset实现的延时队列。
优点:
- 实现简单,现有逻辑。
缺点:
- 如果es有大量的失败时,可能导致队列特别长。
- 可调试性不友好
- 数据在内存中未落地,容易出问题。
方案2
使用db来实现延时队列。
优点:
- 数据存储可靠
- 可调试性友好
缺点:
- 需新实现一套
- 需要保证每条消息只被消费一次。
- 分布式锁解决
- 利用行锁,锁定后改为handling,每个消费者取消息时limit 10.
做了技术评审后,最终决定采用db的方式来实现。
表结构设计:
retry_delay_queue:
字段 | 类型 | 含义 | 备注 |
---|---|---|---|
id |