前言
Redis的用途广泛, 但最常用的用途是用于数据库中作为"缓存", 因为数据库的访问数据慢, 而Redis将数据存放在内存中等优点, 很适合作为数据库的缓存进行快速访问数据
缓存更新策略
Redis无法存放数据库中的所有数据, 只能筛选出热门的, 最近常常被访问的数据, 存放在Redis中,
而这种"热点数据"的往往需要更新.
定时更新
利用日志的方式先将所有用户的搜索词进行记录, 然后在日志中进行排序. 筛选出最热门的数据存放到Redis中, 然后每隔一段时间(一天/一个月....)对缓存中的数据进行更新. 但这种方式不具有时效性. 当网络上突然发生了热门事件就无法及时的更新数据
实时更新
如果用户的搜索词存在Redis中,那么就立即返回
如果用户的搜索词不存在, 就会从数据库中获取, 然后存放在Redis中.
这种方式解决了时效性的问题, 但因为Redis的数据容量有上限, 所以需要考虑当容量不够时, 对某些数据进行淘汰.
内存淘汰机制
内存中数据的淘汰机制主要有四种:
1.FIFO(First In First Out):
先进先出原则. 淘汰数据会优先从那个存在时间最长的开始
2.LRU(Latest Resently Used):
未被访问时间最久原则. 淘汰数据会从先淘汰那个被访问的时间距离现在最久的那个开始淘汰
3.LFU(Latest Frequently Used):
访问次数最少原则. 淘汰数据会从被访问次数最少的那个数据开始淘汰
4.Random:
随机对数据进行淘汰
Redis所采用的策略:
- volatile-lru 当内存不⾜以容纳新写⼊数据时,从设置了过期时间的key中使⽤LRU(最近最 少使⽤)算法进⾏淘汰
- allkeys-lru 当内存不⾜以容纳新写⼊数据时,从所有key中使⽤LRU(最近最少使⽤)算法进⾏淘汰.
- volatile-lfu 4.0版本新增,当内存不⾜以容纳新写⼊数据时,在过期的key中,使⽤LFU算法 进⾏删除key.
- allkeys-lfu 4.0版本新增,当内存不⾜以容纳新写⼊数据时,从所有key中使⽤LFU算法进⾏ 淘汰.
- volatile-random 当内存不⾜以容纳新写⼊数据时,从设置了过期时间的key中,随机淘汰数 据.
- allkeys-random 当内存不⾜以容纳新写⼊数据时,从所有key中随机淘汰数据.
- volatile-ttl 在设置了过期时间的key中,根据过期时间进⾏淘汰,越早过期的优先被淘汰. (相当于 FIFO, 只不过是局限于过期的 key)
- noeviction 默认策略,当内存不⾜以容纳新写⼊数据时,新写⼊操作会报错.
缓存机制中会遇到的问题
缓存预热
在实时更新中, 当Redis是第一次与数据库连接, 此时Redis中没有数据, 当用户进行访问时, 所有的请求都会给到数据库进行查询. 导致数据库压力极大. 所以在第一次的时候, 会利用离线操作将一些热点数据存放到Redis中. 分担数据库压力.
缓存穿透
查询用户的搜索词时, 会遇到在Redis中查询不到, 在数据库中也查询不到的情况. 另外一个用户也查询了相同的搜索词, 依然会进行一样的操作. 如果不处理这种情况会一直存在下去, 可能会导致服务器死机.
发生缓存穿透时,可以从这三个方面入手
缓存雪崩
在短时间内, Redis中有大量的Key超过过期时间而被删除 或 Redis直接宕机, 此时查询的数据都需要通过数据库进行查询, 进而导致系统宕机.
为避免这种情况, 主要有以下方法:
1.不再给Key设置过期时间
2.设置过期时间时, 附加一个随机时间因子, 避免短时间内大量Key同时过期
3.完善哨兵机制中的报警模式. 在遇到类似情况进行报警
缓存击穿
在短时间内, 热点数据失效, 而导致大量请求送往数据库, 进而使系统崩溃. 与缓存雪崩不同的是, 可能只有几个热点数据的失效就可以使系统崩溃. 因为热点数据被访问的次数远远超过了其他的数据.
这种情况的处理方式有:
1.基于统计的方式将热点数据设置为永不过期.
2.对服务器进行降级. 例如采用分布式锁, 限制请求的访问数量.