缓存问题
缓存的雪崩场景
原因: 缓存大面积的同时失效
解决:避免缓存设置相近的有效期
- 为有效期增加随机值
- 统一规划有效期,失效时间均匀分布
如果是热点信息,持续高并发
- 增加互斥锁(Jvm锁机制,分布式锁机制)
- 实现缓存永不过期,异步更新
- 优点:不阻塞线程,用户体验好,不会出现雪崩场景
- 缺点:不保证一致性,代码复杂度增大(每个value都要维护异步更新代码),容易堆积垃圾数据
使用缓存主要解决数据同步,并减少对数据库访问次数。因此,通常解决方案往往是使用互斥锁,让一个线程访问数据库,并将数据更新到缓存中,其他线程访问缓存中数据
。如果是基于jvm锁机制的话,只能解决单机问题,也就是只让本机一个线程访问缓存,但是分布式条件下是不能使用的。所以,要基于缓存的分布式锁来实现。
以redis为例解释下实现分布式锁的原理:
获取锁:
所有线程操作一个共同的key比如lock,如果redis中不存在key为lock的值,那么当前线程获取锁并为lock设置一个随机值。如果lock已经存在了,说明已经有线程获取锁,该线程不能再获取了。
释放锁:
获取锁的线程操作执行完毕后,清除lock的值,这样锁就释放了。所以,对锁的操作就是通过对同一个key值的添加和删除操作。