Redis 是可以对 key 设置过期时间的,因此需要有相应的机制将已过期的键值对删除,而做这个工作的就是过期键值删除策略。
在说 Redis 过期删除策略之前,先跟大家介绍下,常见的三种过期删除策略:
在设置 key 的过期时间时,同时创建一个定时事件,当时间到达时,由事件处理器自动执行 key 的删除操作**
定时删除策略的优点:
定时删除策略的缺点:
不主动删除过期键,每次从数据库访问 key 时,都检测 key 是否过期,如果过期则删除该 key。**
惰性删除策略的优点:
惰性删除策略的缺点:
每隔一段时间「随机」从数据库中取出一定数量的 key 进行检查,并删除其中的过期key。
定期删除策略的优点:
定期删除策略的缺点:
Redis 选择「惰性删除+定期删除」这两种策略配和使用
1、不进行数据淘汰的策略
noeviction(Redis3.0之后,默认的内存淘汰策略) :它表示当运行内存超过最大设置内存时,不淘汰任何数据,这时如果有新的数据写入,则会触发 OOM,但是如果没用数据写入的话,只是单纯的查询或者删除操作的话,还是可以正常工作。
2、进行数据淘汰的策略
针对「进行数据淘汰」这一类策略,又可以细分为「在设置了过期时间的数据中进行淘汰」和「在所有数据范围内进行淘汰」这两类策略。
在设置了过期时间的数据中进行淘汰:
Redis 共有三种数据持久化的方式:
AOF 日志过大,会触发什么机制?
Redis 为了避免 AOF 文件越写越大,提供了 AOF 重写机制,当 AOF 文件的大小超过所设定的阈值后,Redis 就会启用 AOF 重写机制,来压缩 AOF 文件。
AOF 重写机制是在重写时,读取当前数据库中的所有键值对,然后将每一个键值对用一条命令记录到「新的 AOF 文件」,等到全部记录完后,就将新的 AOF 文件替换掉现有的 AOF 文件。
RDB 快照就是记录某一个瞬间的内存数据,记录的是实际数据,
Redis 提供了两个命令来生成 RDB 文件,分别是 save 和 bgsave,他们的区别就在于是否在「主线程」里执行:
Redis 还可以通过配置文件的选项来实现每隔一段时间自动执行一次 bgsave 命令,默认会提供以下配置:
save 900 1
save 300 10
save 60 10000
执行 bgsave 过程中,Redis 依然可以继续处理操作命令的。关键的技术就在于写时复制技术
如果主线程(父进程)要修改共享数据里的某一块数据(比如键值对 A)时,就会发生写时复制,于是这块数据的物理内存就会被复制一份(键值对 A'),然后主线程在这个数据副本(键值对 A')进行修改操作。与此同时,bgsave 子进程可以继续把原来的数据(键值对 A)写入到 RDB 文件。
Redis 4.0 提出了混合使用 AOF 日志和内存快照
AOF 文件的前半部分是 RDB 格式的全量数据,后半部分是 AOF 格式的增量数据。
产生的背景:
缓存穿透是指使用不存在的key进行大量的高并发查询,导致缓存无法命中,每次请求都要都要穿透到后端数据库查询(同时也查不到),使得数据库的压力非常大,甚至导致数据库服务压死;既不在缓存中,也不在数据库中
解决方案:
产生背景:
在高并发的情况下,当一个缓存key过期时,因为访问该key请求较大,多个请求同时发现缓存过期,因此对多个请求同时数据库查询、同时向Redis写入缓存数据,这样会导致数据库的压力非常大;
解决方案:
保证在分布式情况下,使用分布式锁保证对于每个key同时只允许只有一个线程查询到后端服务,其他没有获取到锁的权限,只需要等待即可;这种高并发压力直接转移到分布式锁上,对分布式锁的压力非常大。
使用本地锁与分布式锁机制一样,只不过分布式锁适应于服务集群、本地锁仅限于单个服务使用。
设置热点数据永不过期或者异步延长过期时间;
缓存雪崩指缓存服务器重启或者大量的缓存集中在某个时间段失效,突然给数据库产生了巨大的压力,甚至击垮数据库的情况。
解决思路:对不用的数据使用不同的失效时间,加上随机数
出现了缓存和数据库中的数据不一致的现象。
出现了缓存和数据库中的数据不一致的现象。
先删除缓存,再更新数据库,在「读 + 写」并发的时候,还是会出现缓存和数据库的数据不一致的问题。
写策略的步骤:
读策略的步骤:
1、Read Through 策略
先查询缓存中数据是否存在,如果存在则直接返回,如果不存在,则由缓存组件负责从数据库查询数据,并将结果写入到缓存组件,最后缓存组件将数据返回给应用。
2、Write Through 策略
当有数据更新的时候,先查询要写入的数据在缓存中是否已经存在:
Write Back(写回)策略在更新数据的时候,只更新缓存,同时将缓存数据设置为脏的,然后立马返回,并不会更新数据库。对于数据库的更新,会通过批量异步更新的方式进行。