redis其本质是一个key-value类型的数据库,value的类型可以是:字符串、哈希、列表、队列、集合。由于redis自生在性能和并发中的优势,使用redis场景大多是高并发的场景。试想一下假设每次进行查询操作的时候都是之间从底层数据库中查询,那么在大并发的情况下,我们的数据库很有可能就gg了。所以目前就这种并发场景而言,我们一般都是先从缓存中读取数据,这样大大减少了数据库的负担。redis是基于内存或是磁盘持久化的一种数据库,在不是较大并发量的情况下使用redis足可以满足我们对性能的需要。

在使用redis的过程中不可避免的要解除其锁机制。试想一下c1进程获得了锁,但是由于什么原因造成客户端崩溃导致无法释放该锁就造成了死锁。针对死锁的发生有两种处理方式常被提及。

方案1:如图1 所示。例如c1、c2、c3三个进程都去请求加锁,c1首先获得了锁并设置了有效时间,此刻c2、c3无法获得该锁。那么c2、c3等待一段时间后再次访问。过来一段时间后c2、c3再次请求锁时发现c1的锁已经过了有效时间所以准备删除c1的锁。由于redis时单进程操作,假设c2先进行了删锁操作然后重新创建了锁;之后c3又进行删锁操作并创建锁。那么此时可以看到c3这个时候删除的是c2刚刚创建的锁,这显然不是我们想要看到的。


方案2:如图2所示。c1、c2、c3三个进程都去请求加锁,c1首先获得了锁并设置了有效时间,此刻c2、c3无法获得该锁。那么c2、c3等待一段时间后再次访问。过来一段时间后c2、c3再次请求锁时发现c1的锁已经过了有效时间,c2先进行操作,此时不是删除c1的锁,而是再次取得该锁的有效时间进行核对发现该锁确实是已经失效,然后赋予该锁一个新的值获得锁。随后c3取得c2刚刚更新的锁的失效时间发现未实效,继续等待。可以看到这种方式对失效时间其实是进行了两次校验,既解决了死锁问题,又避免方案1中误删锁的现象发生。在这个方案中一般我们使用getset方法进行操作。

除了以上两种方案以外,我们还可以自己对锁进行过期时间的设置,加锁时间超过一定时间后自行失效。redis锁机制的具体实现方案是根据业务的不同来自行改造优化的。在这里也只是列举了大家常用的几个方案,欢迎指正。