Redis 持久化
redis的持久化方式有两种,一种是RDB持久化,一种是AOF持久化。
RDB快照(snapshot)
redis把数据以快照的方式保存在磁盘上。默认的情况下,redis将数据保存在文件名为dump.rdb的二进制文件中。
redis在运行时,会把内存中的数据快照保存到磁盘上,在redis重启时,会从rdb文件中读取数据还原redis数据库的状态。
rdb是自动默认开启的,但并没有开启触发规则。
触发机制
RDB的触发可分为两大类,一类是自动触发,一类是手动触发。
自动触发
自动触发
当数据操作满足一定的规则,自动触发。详细规则如下
默认开启rdb,但没有配置规则,若需要使用或配置则需要在配置文件中将注释放开
1 |
# RDB自动持久化规则 |
手动触发
save命令
在客户端执行save命令,会触发一次保存快照。save命令是同步命令,在save执行时,会占用主进程,导致redis其他命令无法使用。在数据量过大时,可能会导致redis反应变慢。
bgsave命令
bgsave命令是异步操作,执行bgsave命令保存快照,可以在生成快照的同时,依然可以正常处理其他命令。bgsave子进程是由主线程fock生成的,它不影响主进程的执行,同时还可以共享主进程的数据
save和bgsave对比
命令 | save | bgsave |
---|---|---|
IO类型 | 同步 | 异步 |
是否阻塞redis | 是 | 是(在生成子进程时有短暂阻塞,速度很快,基本没有影响) |
时间复杂度 | O(n) | O(n) |
优点 | 不消耗额外内存 | 不阻塞客户端 |
缺点 | 阻塞客户端命令 | 需要fork子进程,消耗内存 |
关闭RDB
虽然这种方式可能不需要,但若需要关闭rdb的时候,在redis-shell中只需要执行即可
1 |
config set save "" |
当然也可以在配置文件中将 save ""
注释打开,也可以。
AOF(Append Only File)
默认情况下,Redis 异步转储磁盘上的数据集。RDB模式在很多应用场景中已经足够好了,但是 Redis 进程的问题或断电可能会导致几分钟的写入丢失(取决于配置的保存点)。 Append Only File 是另一种持久性模式,可提供更好的持久性。
例如,使用默认的数据 fsync 策略(见后面的配置文件)Redis 可能会在服务器断电等戏剧性事件中丢失一秒钟的写入,或者如果 Redis 进程本身发生问题,则会丢失一次写入,但是操作系统仍然正常运行。可以同时启用 AOF 和 RDB 持久化。如果在启动时启用了 AOF,Redis 将加载 AOF,即具有更好持久性保证的文件。
AOF是通过将修改的每一条指令写入一个记录文件件appendonly.aof中(先写入os cache,每隔一段时间 fsync到磁盘)。这样子的话,在redis重启时,可以通过读取指令来重新写入数据达到重建数据库的目的。
开启AOF
可以通过修改配置文件来打开AOF功能与命令,配置文件中如下:
在配置文件中将
appendonly yes
注释打开即可
1 |
appendonly yes |
命令
1 |
config set appendonly yes |
AOF保存策略
- appendfsync always:每次有新命令追加到 AOF 文件时就执行一次 fsync ,非常慢,也非常安全。
- appendfsync everysec:每秒 fsync 一次,足够快,并且在故障时只会丢失 1 秒钟的数据。
- appendfsync no:从不 fsync ,将数据交给操作系统来处理。更快,也更不安全的选择。
推荐(也就是默认)的措施为每秒 fsync 一次, 这种 fsync 策略可以兼顾速度和安全性。
AOF重写
由于AOF不断的将命令追加到文件的末尾,因此随着命令的不断增加,AOF文件的体积会变的越来越大。
例如执行INCR命令执行了1000次,在AOF内会生成1000个操作命令。但实际上来说,只需要SET到当前值的命令就可以存储了,前面的999次INCR都是无意义的。
实际上可能不止这一种多余的废操作,因此Redis可以对AOF文件进行重写,会把命令进行精简整合成一个新的AOF文件,新的文件里包含生成当前数据的最少命令。
执行AOF重写的方式也有两种,一种是命令,一种是配置文件
配置文件配置aof重写
默认开启重写,但需要先开始aof
1 |
当前大小大于指定的百分比触发重写 |
将此基本大小与当前大小进行比较。如果当前大小大于指定的百分比,则触发重写。此外,您还需要为要重写的 AOF 文件指定最小大小,这对于避免重写 AOF 文件(即使达到百分比增加但仍然很小)很有用。指定百分比为零以禁用自动 AOF 重写功能。
命令
1 |
bgrewriteaof |
RDB 与 AOF对比
RDB
优点
- 文件紧凑,很适合进行数据备份和容灾恢复
- 恢复大量数据时RDB速度快
缺点
- 数据量越大,二进制保存到磁盘会耗时越久
- 遇见意外的情况下,如宕机等,可能导致未持久化的数据完全丢失
AOF
优点
- 可以使用不同的fsync策略,在默认的每秒fsync下,最多丢失1s的数据
- AOF的持久化记录是文件追加,保存速度快
- 存储的是操作命令,AOF文件易读,可以轻易的进行文件分析
缺点
- 文件体积较RDB大
- 重启时恢复数据速度较慢
类型 | RDB | AOF |
---|---|---|
启动优先级 | 低 | 高 |
体积 | 小 | 大 |
宕机恢复速度 | 快 | 慢 |
数据安全性 | 可能丢失数据 | 每秒fsync最多丢失1s数据 |
是rdb还是aof?
使用可以根据需要来自行选择,如果对数据丢失不敏感的,使用rdb即可。当然在生产环境使用时,可以两种方式都启用。rdb文件可以用来做备份,aof文件来保证数据的安全性
RDB与AOF混用
必须先开启aof
在redis4.0之后,出现了一个新的持久化选项——混合持久化。 可以通过以下配置开启混合持久化
1 |
在配置文件中设置 |
开启混合持久化后,AOF在重写时,不是单纯的把命令写入AOF文件,而是把重写这一刻之前的内存数据做RDB快照处理,在重写之后的还是继续使用AOF命令的形式保存。这样aof文件里就有历史的RDB快照和增量的AOF命令。
我们知道,RDB文件的恢复速度比AOF快的多,因此这种混合的模式,在redis重启的时候能大大提升效率。
Redis淘汰机制
将内存使用限制设置为指定的字节数。当达到内存限制时,Redis 将尝试根据选择的驱逐策略删除键。
MAXMEMORY 策略:
当达到 maxmemory 时,Redis 将如何选择要删除的内容。可以从以下行为中选择一项
noeviction:默认禁止驱逐数据。内存不够使用时,对申请内存的命令报错。
volatile-lru:从设置了过期时间的数据集中淘汰最近没使用的数据。
volatile-ttl:从设置了过期时间的数据集中淘汰即将要过期的数据。
volatile-random:从设置了过期时间的数据中随机淘汰数据。
allkeys-lru:淘汰最近没使用的数据。
allkeys-random:随机淘汰数据。
注意:使用上述任何一种策略,当没有合适的键用于驱逐时,Redis 将在需要更多内存的写操作时返回错误。这些通常是创建新密钥、添加数据或修改现有密钥的命令。一些示例是:SET、INCR、HSET、LPUSH、SUNIONSTORE、SORT(由于 STORE 参数)和 EXEC(如果事务包括任何需要内存的命令)。
如果 Redis 无法根据策略删除键,或者如果策略设置为“noeviction”,Redis 将开始对会使用更多内存的命令(如 SET、LPUSH 等)回复错误信息,并将继续回复像 GET
这样的只读命令。简而言之…如果附加了副本,建议为 maxmemory 设置一个下限,以便系统上有一些空闲 RAM 用于副本输出缓冲区(但如果策略是“noeviction”,则不需要这样做)
警告:如果您将副本附加到启用了 maxmemory 的实例,则从使用的内存计数中减去提供副本所需的输出缓冲区的大小,以便网络问题重新同步不会触发密钥被逐出的循环,并且在将副本的输出缓冲区填满,删除键的 DEL
触发删除更多键,依此类推,直到数据库完全清空