我们一般可以用redisson提供的分布锁实现进行应用
它的大致原理是在操作某个键值之前先查看下一个标识键值是否存在,如果存在,证明已经有其他redis请求在操作,那么会进行循环判断,
如果不存在,那么将会设置这个标识键值,为其附上自己的线程id及设置过期时间,以防自己操作过程中宕机导致无法删除此锁标识,导致死锁现象发生,
而在操作完之后,会删除自己之前设置的锁标识键值,从而让其他redis请求可以操作对应的键值
所有的设置操作很多都是通过lua脚本的执行来保证加锁,释放锁的原子性
并且在finally中进行释放锁的操作,以防在执行过程中发生异常导致无法正常释放锁
如果要实现更高并发的锁,我们可以采用分段锁的思想,
比如将一个预售1000个的商品分到100个键值对中,每个键值对负责10个库存的预售
这样子就可以达到扩大100倍的并发
redis带来的一些问题
缓存穿透,指的是查询不存在的字段导致一直会将请求打到数据库,可以通过布隆过滤器加以避免
缓存击穿,指的是一个热点数据的缓存在某一时刻过期了导致大量请求涌入数据库,可以通过上锁的方式先让一个请求去查找,后面解锁就可以将后面的请求都挡在缓存层面了
缓存雪崩,指的是缓存在同一时间内大量过期,导致大量请求打到数据库,通过随机设置过期时间可以避免同一时间的大量过期.
双写一致性,根据对一致性和可用性的权衡,
当需要更高的可用性是我们可以通过定期的更新缓存或者设置缓存过期主动拉取最新数据来实现延迟的一致性
当需要更高的一致性时我们可以通过加锁的方式加以解决
也可以用阿里的canal,通过binlog的机制进行同步