赞
踩
缓存更新策略
直接删除缓存更快,当缓存内查询不到时,再从数据库中读取并更新缓存。
先操作数据库,再删除缓存
线程安全存在问题的两种情况如下:
- 当线程1删除缓存后,线程2获得时间片,进行缓存查询,发现缓存不存在后查询到数据库的旧数据,并将该数据写入缓存。当线程1重新获得时间片后,更新数据库。此时,缓存与数据库的数据不一致。
- 在线程2进行数据库更新之前,有一个缓存失效的请求恰好抢先到达,拿到时间片,进行查询旧数据的操作。线程2重新获得时间片后更新数据库,删除缓存。当线程1重新获得时间片后,将查询到的旧数据写入缓存。此时,缓存与数据库数据不一致。
更推荐的方法:先操作数据库,再删除缓存
原因是:由于更新数据库需要较长时间,因此在线程1删除缓存和更新数据库之间,很有可能出现查询缓存写入缓存的请求,因此第一种情况很容易出现线程安全问题。
而第二种情况很少出现,首先要求在更新数据库操作之前恰好有一个缓存key失效,其次,由于查询缓存和写入缓存的操作时间很快,速度在微秒级别,在这两个操作之间,出现更新数据库的操作的概率很小,因此第二种线程安全问题发生概率较低。所以应该先操作数据库,再删除缓存
解决方案
- 缓存空对象
- 布隆过滤
- 对于同一时段大量缓存的key同时失效的情况:
- 给不同的key的TTL加上一个随机值,使其不在同一时间失效
- 对于Redis服务宕机的情况:
- 利用Redis集群,主从模式或者哨兵模式来应对某一台服务器宕机问题
- 当整个服务器宕机时,上面的集群模式也失效,因此,可以通过对缓存业务进行降级限流,即通过直接拒绝一些缓存请求来降低数据库压力。
flag是Boolean而不是boolean,Boolean是可以为null,为了避免空指针异常,用了工具包,工具包将null和false都返回为false
- 获得锁之后,假如在同步代码块中发生了异常的话,就会导致解锁unlock()操作无法执行,这样可能会导致死锁。
- 而放在try--finally结构中,就保证了解锁操作一定会执行,这样就避免了死锁问题。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。