1:redis 过期策略
redis 过期策略是:定期删除+惰性删除的一个组合。
所谓定期删除,指的是 redis 默认是每隔 100ms 就随机抽取一些设置了过期时间的 key,检查其是否过期,如果过期就删除
惰性删除了。这就是说,在你获取某个 key 的时候,redis 会检查一下 ,这个 key 如果设置了过期时间那么就判断是否过期了?如果过期了此时就会删除,不会给你返回任何东西。 获取 key 的时候,如果此时 key 已经过期,就删除,不会返回任何东西。
1. 定时删除 原理:给每一个过期key都生成一个定时器,一旦过期了就马上删除。
优缺点:内存空间利用率高,但CPU占用高。
2. 惰性删除 原理:当key查询时才检查它是否过期,如果过期则直接删除。
优缺点:CPU占用低,但内存空间利用率低,容易出现OOM.
3. 定期删除 原理:以某种频率定期去扫描过期key,如果过期则删除。
优缺点:CPU占用较低,空间利用率较高。
2:用redis做缓存怎么保证数据不丢失?(缓存数据丢失会导致所有请求全部走数据库)(缓存击穿)
1:用分布式锁来保证只有一个请求进去,查完后保存一份到redis缓存就可以解决
2:做持久化防止缓存数据丢失,给它存到硬盘里去,会影响性能(性能和安全不可兼得)
3:redis持久化之快照
3.1:redis为什么要持久化?
Redis 是一种内存数据库,它将数据存储在内存中,一旦 Redis 进程退出,保存在内存中的数据将会丢失。
3.2:redis的持久化方法
redis有两种方法将数据存储到硬盘里面。
快照(snapshotting),它可以将存在于某一时刻的所有数据写入硬盘里面。
AOF(append-only file),它会在执行写命令时,将被执行的写命令复制到硬盘里面。
两种方法即可以同时使用也可以单独使用,如果redis单纯只用来做缓存系统的话,也可以不使用
快照持久化方法是 Redis 默认开启的持久化方法
3.3:主动快照
Redis 将某一时刻的快照保存成一种称为 RDB 格式的文件中
Redis 提供了两个命令用来生成 RDB 文件,一个是 SAVE,一个是 BGSAVE。
SAVE 命令会阻塞 Redis 服务器进程,走到 RDB 文件创建完毕为止,在 Redis 服务器进程阻塞期间,Redis 不能处理任何命令请求。在生产环境,我们一般不会直接使用 SAVE 命令,如果机器已没有足够的内存去执行BGSAVE 命令,或者即使等待持久化操作完毕也无所谓,我们也可以使用 SAVE 命令来生成 RDB 文件。
BGSAVE 命令会派生出一个子进程(fork),然后由子进程创建 RDB 文件,因此,BGSAVE 命令不会阻塞 Redis 服务器进程。
3.4:查看是否快照成功
可以使用 LASTSAVE 命令来检查保存 RDB 文件的操作是否执行成功。
3.5:自动保存 RDB 文件
除了手动执行 SAVE 和 BGSAVE 命令来生成 RDB 文件外,Redis 还提供了自动保存 RDB 文件的功能。
Redis 允许用户通过设置配置来让 Redis 服务器每隔一段时间自动执行一次 BGSAVE 命令。
下面是 Redis 配置文件 redis.conf 中有关自动保存 RDB 文件的有关配置内容:
save 900 1
save 300 10
save 60 10000
上面配置的含义是,Redis 服务器只要满足以下三个条件中的任意一个,BGSAVE 命令就会被执行:
Redis 服务器在 900 秒之内,对数据库进行了至少一次修改 Redis 服务器在 300 秒之内,对数据库进行了至少 10 次修改 Redis 服务器在 60 秒之内,对数据库进行了至少 10000 次修改
3 快照持久化的优点
快照持久化的方法采用创建一个子进程的方法来将 Redis 的内存数据保存到硬盘中,因此,它并不会对 Redis 服务器性能造成多大的影响,这可以说是快照持久化方法最大的一个优点。
快照持久化使用的 RDB 文件是一种经过压缩的二进制文件,可以方便地在网络中传输与保存。通过恰当的配置,可以让我们方便快捷地将 Redis 内存数据恢复到某一历史状态。这对于提高数据的安全性,应对服务器宕机等意外的发生很有帮助。
4 快照持久化的缺点
尽管快照持久化允许 Redis 恢复到快照文件的状态,但如果 RDB 文件生成后,Redis 服务器继续处理了写命令导致 Redis 内存数据有更新,这时恰好 Redis 崩溃了而来不及保存新的 RDB 文件,那么 Redis 将会丢失这部分新的数据。也就是说,如果系统真的发生崩溃,那么我们将会丢失最近一次生成 RDB 文件之后更改的所有数据。因此,快照持久化方法只适用于那些即使丢失一部分数据也不会造成问题的应用场景。
另外,快照持久化方法需要调用fork()方法创建子进程。当Redis 内存的数据量较大时,创建子进程和生成 RDB 文件得占用较多的系统资源和处理时间,这会对 Redis 正常处理客户端命令的性能造成较大的影响。
当然,如果我们可以妥善处理快照持久化方法可能带来的数据丢失,那么快照持久化仍然是一个不错的选择。