redis实现消息队列

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了redis实现消息队列相关的知识,希望对你有一定的参考价值。

工作中遇到一个业务场景,A系统会批量刷新主数据,每次以单条传递到我的系统B(A系统没有办法做一次传多条主数据信息),并且有时传递的数据会有顺序要求;
最近批量同步主数据系统时,出现了B没有可用连接提供给A;

  • 原因:大概是这样的,B系统每接收到一个请求,首先校验是否存在编号,存在做更新,不存在做插入,完事之后再同步给另外一个系统;
    系统B是多节点部署,在判断是在做更新或插入时,有并发问题,所以对编码进行了加锁处理;导致有些相同编码持有连接无法释放,耗尽系统资源;

1.使用MQ进行削峰

这种问题也只有在批量刷新主数据的时候才会有,平时的少数更新或插入不会出现这种问题;
想到使用MQ进行削峰,如果是使用DDMQ/RabbitMQ感觉有些小题大做,所以采用redis的队列进行处理;

2.redis实现消息队列

redis提供了list类型,此类型底层是通过双向链表来实现:

lpush、rpop 非阻塞式
blpop、brpop 阻塞式

先来对比一下上面阻塞与非阻塞会有什么问题;

1.阻塞式:如果队列里面没有消息,会阻塞连接,长时间占用redis连接,需要考虑redis配置的超时以及redis会对空闲连接进行释放以减少资源浪费,需要对异常进行捕获重试;
2.非阻塞式:如果是1s主动去redis中拉取一次消息,也不太适合;

解决方案:

1.存数据时,采用rpush,从右边添加;
2.取数据时:从左边lrange key 0 100; 每次拉取100条;程序定时1分钟拉一次;

存在的问题

1.上一个定时任务执行没有执行完毕,下一个定时任务会执行吗? 验证:不会;
2.如果拉取100条在处理,程序突然停机,怎么办?拉取100条后,每处理完成1条,就从list中将本条删除;lpop
3.多节点拉取redis list中的数据,怎么保证不会重复?
两台节点,提供了两个list,在rpush时,首先对编码进行hash,来决定放入哪个list中,两台消费节点,一台消费一个list;

以上是关于redis实现消息队列的主要内容,如果未能解决你的问题,请参考以下文章

Redis的基本使用(二) 消息队列

Redis 实现 消息队列

Redis(五)-特性-消息队列

redis怎么做消息队列

Redis 竟然能用 List 实现消息队列

使用redis实现消息队列