一个经典的redis队列简单解决方案

需求场景:

一些异步的作业,比如订单信息同步,消息通知等,我们一般都是通过事件触发,然后先保存在队列里面,异步消费的方式去执行。

这个同步的技术需要保障两个点:

1、事件触发稳定性

2、事件消费的稳定性

 

我们先来聊第一个点:

要保证事件触发稳定,需要满足2个点,触发数据丢失可补偿,事件及时性,那么我们的方案可以是用canal监听mysql的方式,把事件数据触发写入到redis队列里面,这样的好处是canal可以方便的根据位点,恢复redis队列的数据(假设redis的数据是可以丢失的定位)。

那第二点,消费的稳定性,就要去对redis列队的数据进行消费,是稳定的。因为涉及到消费的性能要求,我们一般采取redis队列的pop方式,保障并发问题。但是pop有个致命的问题就是pop后,业务消费处理失败的处理能力有效,容易造成redis的pop后业务逻辑处理失败,队列数据丢失。解决方案就是数据和pop分开,触发数据放到一个hashmap里面,pop的消费数据放到list里面;每次从hashmap取hgetall到list,然后当我们pop的list时,消费成功,才将hashmap里面的数据删除。然后,消费失败的数据,放到另外一组hashmap和list里面,重复这个逻辑,与正常的队列区分开来。

 

posted @ 2021-06-29 17:16  zenghansen  阅读(581)  评论(0编辑  收藏  举报