1 导读
Redis 是当前最流行的 NoSQL数据库。Redis主要用来做缓存使用,在提高数据查询效率、保护数据库等方面起到了关键性的作用,很大程度上提高系统的性能。当然在使用过程中,也会出现一些异常情景,导致Redis失去缓存作用。
2 异常类型
异常主要有 缓存雪崩 缓存穿透 缓存击穿。
2.1 缓存雪崩
2.1.1 现象
缓存雪崩是指大量请求在缓存中没有查到数据,直接访问数据库,导致数据库压力增大,最终导致数据库崩溃,从而波及整个系统不可用,好像雪崩一样。
2.1.2 异常原因
缓存服务不可用。
缓存服务可用,但是大量KEY同时失效。
2.1.3 解决方案
1.缓存服务不可用
redis的部署方式主要有单机、主从、哨兵和 cluster模式。
单机
只有一台机器,所有数据都存在这台机器上,当机器出现异常时,redis将失效,可能会导致redis缓存雪崩。
主从
主从其实就是一台机器做主,一个或多个机器做从,从节点从主节点复制数据,可以实现读写分离,主节点做写,从节点做读。优点:当某个从节点异常时,不影响使用。缺点:当主节点异常时,服务将不可用。
哨兵
哨兵模式也是一种主从,只不过增加了哨兵的功能,用于监控主节点的状态,当主节点宕机之后会进行投票在从节点中重新选出主节点。优点:高可用,当主节点异常时,自动在从节点当中选择一个主节点。缺点:只有一个主节点,当数据比较多时,主节点压力会很大。
cluster模式
集群采用了多主多从,按照一定的规则进行分片,将数据分别存储,一定程度上解决了哨兵模式下单机存储有限的问题。优点:高可用,配置了多主多从,可以使数据分区,去中心化,减小了单台机子的负担.缺点:机器资源使用比较多,配置复杂。
小结
从高可用得角度考虑,使用哨兵模式和cluster模式可以防止因为redis不可用导致的缓存雪崩问题。
2.大量KEY同时失效
可以通过设置永不失效、设置不同失效时间、使用二级缓存和定时更新缓存失效时间
设置永不失效
如果所有的key都设置不失效,不就不会出现因为KEY失效导致的缓存雪崩问题了。redis设置key永远有效的命令如下:PERSIST key缺点:会导致redis的空间资源需求变大。
设置随机失效时间
如果key的失效时间不相同,就不会在同一时刻失效,这样就不会出现大量访问数据库的情况。redis设置key有效时间命令如下:Expire key示例代码如下,通过RedisClient实现
/**
* 随机设置小于30分钟的失效时间
* @param redisKey
* @param value
*/
private void setRandomTimeForReidsKey(String redisKey,String value){
//随机函数
Random rand = new Random();
//随机获取30分钟内(30*60)的随机数
int times = rand.nextInt(1800);
//设置缓存时间(缓存的key,缓存的值,失效时间:单位秒)
redisClient.setNxEx(redisKey,value,times);
}
使用二级缓存
二级缓存是使用两组缓存,1级缓存和2级缓存,同一个Key在两组缓存里都保存,但是他们的失效时间不同,这样1级缓存没有查到数据时,可以在二级缓存里查询,不会直接访问数据库。示例代码如下:
public static void main(String[] args) {
CacheTest test = new CacheTest();
//从1级缓存中获取数据
String value = test.queryByOneCacheKey("key");
//如果1级缓存中没有数据,再二级缓存中查