1、redis的删除策略
key的生存时间到了,redis不会立即删除。
1.1 定期删除:redis每隔一段时间就会去查看redis设置了过期时间的key,会在100ms的间隔查看3个key。
1.2 惰性删除:查询一个key时,redis会先判断这个key是否设置了生存时间,是否已经过期。如果已经过期,则删除。
2、redis的淘汰机制
在redis内存已经满的时候,又添加了新的数据,则需要淘汰一些数据。
# volatile-lru -> 在已经设置了生存时间的key中,使用LRU淘汰 # allkeys-lru -> 在所有key中,使用LRU淘汰 # volatile-random -> 在设置了生存时间的key中,使用随机淘汰 # allkeys-random -> 在所有key中,使用随机淘汰 # volatile-ttl -> 在已经设置了生存时间的key中,将剩余生存时间最少的淘汰 # noeviction -> 不淘汰,只返回错误(默认)
maxmemory-policy noeviction #默认不淘汰
# maxmemory <bytes> #设置最大内存
3、缓存的问题
3.1 缓存穿透
原因:查询的数据,redis中没有,数据库中也没有。大量的查询造成数据库很大压力。
解决办法:
根据id查询时,如果id时自增的,将id的最大值放到redis中。在查询数据库之前,比较id,如果id非法,则不进行数据库的查询。
如果id不是自增,可以将全部的id放到set中,在用户查询之前,先在set中判断是否存在此id,如果不存在,则不进行数据库的查询。
获取客户端的ip地址,可以将ip加入限制名单。
3.2 缓存击穿
原因:redis中的热点数据大量到期,大量的请求都去访问数据库,造成数据库很大压力。
解决办法:
在redis中没有此key时,直接添加一个锁,只让少量请求访问数据库,避免数据库宕机。
将redis中的key的生存时间去除。
3.3 缓存雪崩
原因:redis中的数据大量同时到期,是缓存击穿的一种极端情况。
解决办法:
将redis的生存时间设置为一个范围内的随机时间。
3.4 缓存倾斜
原因:大量的热点数据,都存储在某一台或少量几台redis机器上,而其他节点比较空闲。繁忙的redis机器宕机。
解决办法:
给繁忙的机器增加大量的从节点。
在查询redis之前,先通过(Java)代码编写逻辑处理,对请求进行过滤。