redis怎么解决并发问题?

77 阅读2分钟

单个命令

单个命令是原子的,比如set get,都是原子的。

因为redis是单线程。

原子组合命令

首先,在redis侧,如果是单个命令,是不存在并发问题的。

但是呢,在业务侧,也就是客户端侧,是存在并发问题的,比如多个线程去既读又写。

那这个时候怎么解决这个问题呢?java里面的解决方法是,
1.锁
说白了,就是把多个操作上了一把锁。同一时间,只有一个线程执行。
2.并发包里的原子类
比如实现自增功能。


那redis怎么解决呢?

其实解决思想完全类似。

第一种方法,也是锁。把多个命令锁住,同一时间,只有一个线程执行。

第二种方法,也是原子组合命令,比如自增命令。类似java并发包里的原子类。所以,redis里面也是有自增命令的。自增命令的本质,其实就是组合了先读后写两个命令,从而解决了并发问题。

自增命令的应用场景?

比如文章阅读数量计数,如果是先get,再set,那就有并发问题。但是如果使用自增命令,就没有并发问题。

setnx命令

除了自增命令是组合命令,setnx其实也是组合命令。只有不存在,才set成功;否则,就失败。说白了,也是先读后写的问题。setnx命令,只不过是组合了一下而已。

setnx命令,最常用的应用场景是分布式锁。而分布式锁的目的,就是为了解决分布式系统的并发问题。

八股文

面试的时候,问这种问题,如果只是简单的回答redis是单线程,所以没有并发问题。显然是不够的,显然不是面试官想要的答案,面试官想让你展开讲讲。

具体展开的内容,大概就是上文内容。其实就是看站在哪个维度看问题,如果只是站在redis侧服务器端,那么是没有并发问题的;但是如果站在业务侧客户端,那么确实是有并发问题的。

实际上,上文提到的组合命令,只是redis解决并发问题的其中一种方案。除了组合命令,还有lua脚本、事务等方案。

具体使用哪种方案,具体问题具体分析。

阻塞

既然redis是单线程,那多线程会阻塞吗?会。

阻塞了怎么办?排队。然后等待。

排队久了,就超时。超时时间,可设置。