先说下为什么redis会存在并发问题,redis不是单线程吗,不管你多少个请求过来,我就只有一个线程,讲道理永远不会出现并发问题;

但上述情况仅适用于单机系统,如果是多个系统并发操作redis,就有可能造成数据丢失、数据覆盖等并发问题;

打个比方,有ABC三个系统

A系统要把变量a赋值为1;

B系统要把变量a赋值为2;

C系统要把变量a赋值为3;

本来我们期望顺序执行A > B > C后,a的值为3,但是如果并发太大,导致A晚了一步,让BC先执行了,最后a的值就成1了;

解决方案

1、分布式锁+时间戳

分布式锁目前的方案主要有三种:


1、基于数据库
2、基于redis;
3、基于zooKeeper


分布式锁具体实现思路请看分布式锁实现思路,讲的很详细

!!!

注意一点,很多小白不知道,像基于zk或者redis实现的分布式锁,都有封装好的工具,zk的是Apache开源的curator,redis的没用过不知道自己去找,所以其实是不需要我们自己手动实现锁,这些工具开箱即用,我们能像使用普通lock一样实现分布式锁;

在操作a变量时候,额外维护一个时间戳,打个比方

A在执行的时候时间是19:13:30

B在执行的时候时间是19:13:33

C在执行的时候时间是19:13:35

假如B先执行,B执行完后a变量对应的时间戳值应为19:13:33

这时候A再来,发现当前时间是19:13:30,而a对应的时间戳为19:13:33,早于当前时间,说明在自己执行之前已经有其他系统操作过了,这时候就根据实际业务来决定怎么继续,废弃A操作或者轮询等;

2、基于消息队列

这种实现方式比较简单,是目前主流的解决方案

把所有操作写入同一个队列,利用消息队列把所有操作串行化

详细思路请移步rabbitMQ如何保证消息顺序消费和避免消息重复消费