Redis 工作时数据都存储在内存中,如若服务器宕机,则所有数据都会丢失。针对这种情况,Redis 采用持久化机制来增强数据的安全性,简单的来说就是把内存里面的数据保存到硬盘上。
对于 Redis 而言,持久化机制是指把内存中的数据存为硬盘文件,这样当 Redis 重启或者服务器故障时能够根据持久化后的硬盘文件恢复数据。其意义在于故障恢复。
Redis 提供了两种不同形式的持久化方式:
在指定的时间间隔内将内存你的数据集快照写入磁盘,它恢复时是将快照文件直接读到内存中。Redis 默认开启 RDB 机制。
这种格式是经过压缩的二进制文件
RDB 文件的保存位置,可以在 Redis 的配置文件 redis.conf 中修改。默认在 Redis 启动时命令行所在的目录下。
RDB 保存的文件名,也可以在 redis.conf 中配置,文件名称默认为 dump.rdb。
可以通过查看 Redis 的配置文件 redis.conf 来验证,下面为部分配置:
430
431 # The filename where to dump the DB
432 dbfilename dump.rdb
433
......
447 # The working directory.
448 #
449 # The DB will be written inside this directory, with the filename specified
450 # above using the 'dbfilename' configuration directive.
451 #
452 # The Append Only File will also be created inside this directory.
453 #
454 # Note that you must specify a directory here, not a file name.
455 dir ./
查看位置及名称如下:
[root@localhost bin]# ls
dump.rdb redis-benchmark redis-check-aof redis-check-rdb redis-cli redis-sentinel redis-server
[root@localhost bin]# pwd
/usr/local/bin
[1] RDB 默认配置
在 Redis.conf 配置文件中可以查看到以下配置内容:
380 # You can set these explicitly by uncommenting the three following lines.
381 #
382 # save 3600 1
383 # save 300 100
384 # save 60 10000
385
386 # By default Redis will stop accepting writes if RDB snapshots are enabled
387 # (at least one save point) and the latest background save failed.
388 # This will make the user aware (in a hard way) that data is not persisting
389 # on disk properly, otherwise chances are that no one will notice and some
390 # disaster will happen.
快照默认配置:
- save 3600 1:表示 3600 秒内(一小时)如果至少有 1 个 key 的值变化,则触发保存操作。
- save 300 100:表示 300 秒内(五分钟)如果至少有 100 个 key 的值变化,则触发保存操作。
- save 60 10000:表示 60 秒内(一分钟)如果至少有 10000 个 key 的值变化,则触发保存操作。
[2] save 和 bgsave 命令
手动触发 Redis 进行 RDB 持久化的命令有两种:
[3] flushall 命令
执行 flushall 命令,也会触发 RDB 规则。但是产生的 dump.rdb 文件是空的(没有意义)。
[4] 服务器关闭
如果执行 shutdown 命令让 Redis 正常退出,那么此前 Redis 就会执行一次持久化操作。
[1] stop-writes-on-bgsave-error
默认值为 yes。表示当 Redis 无法写入磁盘的话,直接关闭 Redis 的写操作。
392 # If the background saving process will start working again Redis will
393 # automatically allow writes again.
394 #
395 # However if you have setup your proper monitoring of the Redis server
396 # and persistence, you may want to disable this feature so that Redis will
397 # continue to work as usual even if there are problems with disk,
398 # permissions, and so forth.
399 stop-writes-on-bgsave-error yes
[2] rdbcompression
默认值为 yes。表示对于存储到磁盘中的快照,可以设置是否进行压缩存储。如果是的话,Redis 会采用 LZF 算法进行压缩。如果你不想消耗 CPU 来进行压缩的话,可以设置为关闭此功能,但是存储在磁盘上的快照会比较大。
401 # Compress string objects using LZF when dump .rdb databases?
402 # By default compression is enabled as it's almost always a win.
403 # If you want to save some CPU in the saving child set it to 'no' but
404 # the dataset will likely be bigger if you have compressible values or keys.
405 rdbcompression yes
[3] rdbchecksum
默认值为 yes。表示在存储快照后,我们还可以让 Redis 使用 CRC64 算法来进行数据校验,但是这样做会增加大约 10% 的性能消耗,如果希望获取到最大的性能提升,可以关闭此功能。
407 # Since version 5 of RDB a CRC64 checksum is placed at the end of the file.
408 # This makes the format more resistant to corruption but there is a performance
409 # hit to pay (around 10%) when saving and loading RDB files, so you can disable it
410 # for maximum performances.
411 #
412 # RDB files created with checksum disabled have a checksum of zero that will
413 # tell the loading code to skip the check.
414 rdbchecksum yes
只需要将 rdb 文件放在 Redis 的启动目录,Redis 启动时会自动加载 dump.rdb 并恢复数据。
优点:
缺点:
以日志的形式来记录每个 写 操作,将 Redis 执行过的所有写指令记录下来。AOF 默认是不开启的。AOF 机制通俗的理解就是日志记录。
注意:
- 如果 AOF 和 RDB 机制并存时,Redis 会优先采纳 AOF 机制,使用 AOF 持久化文件恢复内存中的数据
- 而 AOF 刚刚开启时,appendonly.aof 持久化文件中没有任何数据。用空的 appendonly.aof 持久化文件恢复内存,就会导致以前所有数据都丢失。
AOF 文件的保存位置,可以在 Redis 的配置文件 redis.conf 中修改。默认在 Redis 启动时命令行所在的目录下。
AOF 保存的文件名,也可以在 redis.conf 中配置,文件名称默认为 appendonly.aof。
下面为 redis.conf 的部分配置
1255 # The name of the append only file (default: "appendonly.aof")
1256
1257 appendfilename "appendonly.aof"
开启 AOF 机制需要修改配置文件中的 appendonly no 选项,将 no 改为 yes。修改完需要重启 Redis 服务。
1251 # Please check https://redis.io/topics/persistence for more information.
1252
1253 appendonly no
配置同步频率:appendfsync everysec
1280 # If unsure, use "everysec".
1281
1282 # appendfsync always
1283 appendfsync everysec
1284 # appendfsync no
参数含义:
- appendfsync always:始终同步,每次 Redis 的写入都会立刻记入日志,性能较差但数据完整性好。
- appendfsync everysec:每秒同步,每秒计入日志一次,如果宕机,本秒的数据可能丢失。
- appendfsync no:由操作系统在适当的时候执行写入操作,Redis 性能最好,数据保存次数最少。
对比以下两组命令:
两组命令执行后对于 num 来说最终的值是一致的,但是进行 AOF 重写后省略了中间过程,可以让 AOF 文件体积更小,缩短数据恢复时间。
而 Redis 会根据 AOF 文件的体积来决定是否进行 AOF 重写。参考的配置项如下:
1321 # Specify a percentage of zero in order to disable the automatic AOF
1322 # rewrite feature.
1323
1324 auto-aof-rewrite-percentage 100
1325 auto-aof-rewrite-min-size 64mb
含义:
- auto-aof-rewrite-percentage 100:文件体积增大 100% 时执行 AOF 重写
- auto-aof-rewrite-min-size 64mb:文件体积增长到 64mb 时执行重写
注意:
- 不要进行频繁的 AOF 重写,因为 CPU、内存资源和硬盘资源二者之间肯定是 CPU、内存资源更加宝贵,所以不应该过多耗费 CPU 性能去节省硬盘空间。另外数据恢复也不是高频操作,所以节约数据恢复时间价值也不是非常大。
优点:
缺点:
Redis 服务器启动时,如果读取了损坏的持久化文件会导致启动失败,此时为了让 Redis 服务器能够正常启动,需要对损坏的持久化文件进行修复。这里以 AOF 文件为例,介绍修复操作的步骤。
[root@localhost src]# ls | grep dump.rdb
dump.rdb
[root@localhost src]# ls | grep appendonly.aof
appendonly.aof
[root@localhost src]# pwd
/opt/redis-6.2.6/src
[root@localhost src]# cp appendonly.aof appendonlybak.aof
修复文件(redis-check-aof 或 redis-check-rdb)位置 --fix 持久化文件位置(appendonly.aof 或 dump.rdb)
[root@localhost src]# /usr/local/bin/redis-check-aof --fix /opt/redis-6.2.6/src/appendonly.aof
[root@localhost src]# ps -ef | grep redis
root 43529 1 0 10:29 ? 00:00:01 ./redis-server *:6379
root 44041 1902 0 10:42 pts/0 00:00:00 grep --color=auto redis
[root@localhost src]# kill -9 43529
[root@localhost src]# ./redis-cli
Could not connect to Redis at 127.0.0.1:6379: Connection refused
not connected>
[root@localhost src]# ./redis-server ../redis.conf
注意:所谓修复持久化文件,仅仅只是把损坏的部分去掉,而没法把受损的数据找回。
关于两种持久化方式的优缺点可以参考上面的介绍。
由于 RDB 和 AOF 各有优势,于是,Redis 4.0 开始支持 RDB 和 AOF 的混合持久化(aof-use-rdb-preamble)。redis.conf 的相关配置如下:
1351 # When rewriting the AOF file, Redis is able to use an RDB preamble in the
1352 # AOF file for faster rewrites and recoveries. When this option is turned
1353 # on the rewritten AOF file is composed of two different stanzas:
1354 #
1355 # [RDB file][AOF tail]
1356 #
1357 # When loading, Redis recognizes that the AOF file starts with the "REDIS"
1358 # string and loads the prefixed RDB file, then continues loading the AOF
1359 # tail.
1360 aof-use-rdb-preamble yes
如果把混合持久化打开,AOF 重写的时候就直接把 RDB 的内容写到 AOF 文件开头。这样做的好处是可以结合 RDB 和 AOF 的优点,,快速加载同时避免丢失过多的数据。当然缺点也是有的, AOF 里面的 RDB 部分是压缩格式不再是 AOF 格式,可读性较差。