08Redis持久化
本篇文章介绍Redis持久化的技术说明。
官网文档:https://redis.io/topics/persistence
一.Redis中提供的不同持久化选项
- RDB(Redis DataBase):RDB 持久性以指定的时间间隔执行数据集的时间点快照。
- AOF(Append Only File):AOF 持久化记录服务器收到的每个写操作,在服务器启动时会再次播放,重建原始数据集。命令使用与 Redis 协议本身相同的格式以仅附加的方式记录。当日志变得太大时,Redis 能够在后台重写日志。
- 无持久性:如果您希望数据在服务器运行时一直存在,您可以完全禁用持久性。
- RDB + AOF:可以在同一个实例中组合 AOF 和 RDB。请注意,在这种情况下,当 Redis 重新启动时,AOF 文件将用于重建原始数据集,因为它保证是最完整的。
二.持久化是怎么执行的
Redis会单独创建(fork)一个子进程来进行持久化,会先将数据写入一个临时文件中,待持久化过程都结束了,再用这个临时文件替换上次持久化好的文件。整个过程中,主进程是不进行任何IO操作的,这就确保了极高的性能,如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加高效。RDB的缺点是最后一次持久化后的数据可能丢失。
Fork的作用是赋值一个与当前进程一样的进程。新进程中的所有数据(变量,环境变量,程序计数器等)数值和原进程一致,但是是一个全新的进程,并作为原进程的子进程。
在Linux程序中,fork会产生一个和父进程完全相同的子进程,但子进程在此后会exec系统调用,出于效率考虑,Linux中引入了'写时复制技术'。
一般情况父进程和子进程会共享共同一段物理内存,只有进程空间的各段内容要发生变化时,才会将父进程的内容复制一份给子进程。

三.RDB配置文件中的参数设置
在Redis中的redis.conf文件中包含了RDB的相关配置。
1 ################################ SNAPSHOTTING ################################ 2 3 # Save the DB to disk. //将数据库保存到磁盘 4 # 5 # save <seconds> <changes> 6 # 7 # Redis will save the DB if both the given number of seconds and the given //如果达到给定的毫秒数和给定的写操作的次数,Redis就会保存数据库 8 # number of write operations against the DB occurred. 9 # 10 # Snapshotting can be completely disabled with a single empty string argument //使用一个空字符串参数可以完全禁用快照 11 # as in following example: 12 # 13 # save "" 14 # 15 # Unless specified otherwise, by default Redis will save the DB: //除非另有规定,默认情况下Redis将保存数据库 16 # * After 3600 seconds (an hour) if at least 1 key changed //3600秒(一小时)后,如果至少有一个Key发生了变化 17 # * After 300 seconds (5 minutes) if at least 100 keys changed //300秒(5分钟)后,如果至少更改了100个键 18 # * After 60 seconds if at least 10000 keys changed //60秒后,如果至少10000个键发生了变化 19 # 20 # You can set these explicitly by uncommenting the three following lines. //您可以通过取消以下三行的注释来显式地设置它们 21 # 22 # save 3600 1 23 # save 300 100 24 # save 60 10000 25 26 # By default Redis will stop accepting writes if RDB snapshots are enabled //默认情况下,如果启用RDB快照,Redis将停止接受写操作(至少一个保存点)和最新的后台保存失败。 27 # (at least one save point) and the latest background save failed. 28 # This will make the user aware (in a hard way) that data is not persisting //这将使用户意识到(以一种强硬的方式)数据没有正确地保存在磁盘上,否则很可能没有人会注意到,并且会发生一些灾难。 29 # on disk properly, otherwise chances are that no one will notice and some 30 # disaster will happen. 31 # 32 # If the background saving process will start working again Redis will //如果后台保存过程重新开始工作,Redis将自动再次允许写操作。 33 # automatically allow writes again. 34 # 35 # However if you have setup your proper monitoring of the Redis server //但是,如果您已经设置了对Redis服务器和持久性的正确监视, 36 # and persistence, you may want to disable this feature so that Redis will //那么您可能需要禁用此功能,以便即使在磁盘、权限等方面出现问题时,Redis仍能正常工作。 37 # continue to work as usual even if there are problems with disk, 38 # permissions, and so forth. 39 stop-writes-on-bgsave-error yes 40 41 # Compress string objects using LZF when dump .rdb databases? //在转储.rdb数据库时使用LZF压缩字符串对象? 42 # By default compression is enabled as it's almost always a win. //默认情况下,压缩是启用的,因为它几乎总是成功的。 43 # If you want to save some CPU in the saving child set it to 'no' but //如果要在保存子级中保存一些CPU,请将其设置为“否”,但如果有可压缩的值或键,则数据集可能会更大。 44 # the dataset will likely be bigger if you have compressible values or keys. 45 rdbcompression yes 46 47 # Since version 5 of RDB a CRC64 checksum is placed at the end of the file. //自从RDB版本5,CRC64校验和放在文件的末尾。 48 # This makes the format more resistant to corruption but there is a performance //这使格式更能抵抗损坏,但在保存和加载RDB文件时,性能会受到影响(约10%),因此可以禁用它以获得最大性能。 49 # hit to pay (around 10%) when saving and loading RDB files, so you can disable it 50 # for maximum performances. 51 # 52 # RDB files created with checksum disabled have a checksum of zero that will //在禁用校验和的情况下创建的RDB文件的校验和为零,这将告诉加载代码跳过检查。 53 # tell the loading code to skip the check. 54 rdbchecksum yes 55 56 # Enables or disables full sanitation checks for ziplist and listpack etc when //在加载RDB或还原负载时启用或禁用ziplist和listpack等的完全卫生检查 57 # loading an RDB or RESTORE payload. This reduces the chances of a assertion or //这减少了以后处理命令时断言或崩溃的机会。 58 # crash later on while processing commands. 59 # Options: 60 # no - Never perform full sanitation //切勿进行全面卫生 61 # yes - Always perform full sanitation //始终保持全面卫生 62 # clients - Perform full sanitation only for user connections. 63 # Excludes: RDB files, RESTORE commands received from the master 64 # connection, and client connections which have the 65 # skip-sanitize-payload ACL flag. 66 # The default should be 'clients' but since it currently affects cluster //默认值应该是'clients',但是由于它当前通过MIGRATE影响集群的重编,所以默认情况下它被临时设置为'no'。 67 # resharding via MIGRATE, it is temporarily set to 'no' by default. 68 # 69 # sanitize-dump-payload no //清理转储负载 70 71 # The filename where to dump the DB //将数据库转储到的文件名 72 dbfilename "dump.rdb" 73 74 # Remove RDB files used by replication in instances without persistence //在未启用持久性的实例中删除复制使用的RDB文件。 75 # enabled. By default this option is disabled, however there are environments //默认情况下,此选项处于禁用状态,但是在某些环境中,出于管理法规或其他安全考虑, 76 # where for regulations or other security concerns, RDB files persisted on //应尽快删除由主服务器保留在磁盘上以馈送副本的RDB文件,或由副本存储在磁盘上以加载这些文件以进行初始同步 77 # disk by masters in order to feed replicas, or stored on disk by replicas 78 # in order to load them for the initial synchronization, should be deleted 79 # ASAP. Note that this option ONLY WORKS in instances that have both AOF //请注意,此选项仅适用于同时禁用AOF和RDB持久性的实例,否则将完全忽略。 80 # and RDB persistence disabled, otherwise is completely ignored. 81 # 82 # An alternative (and sometimes better) way to obtain the same effect is //获得相同效果的另一种方法(有时更好)是在主实例和副本实例上使用无盘复制。 83 # to use diskless replication on both master and replicas instances. However //但是,对于副本,无磁盘并不总是一种选择。 84 # in the case of replicas, diskless is not always an option. 85 rdb-del-sync-files no 86 87 # The working directory. 88 # 89 # The DB will be written inside this directory, with the filename specified //DB将被写入这个目录,使用上面使用'dbfilename'配置指令指定的文件名。 90 # above using the 'dbfilename' configuration directive. 91 # 92 # The Append Only File will also be created inside this directory. //只附加的文件也将在这个目录中创建。 93 # 94 # Note that you must specify a directory here, not a file name. //请注意,必须在此处指定目录,而不是文件名。 95 dir "/usr/local/redis-6.2.4/bin"
四.RDB的备份和恢复
测试步骤:
- 将redis.conf里面的
save 3600 1 #开启 save 300 100 #开启,并将该值设置为 save 30 10,意思是30秒内有10Key发生变化就进行RDB写操作 save 60 10000 #开启
![]()
- 保存该配置文件的修改并退出
- 重新启动redis。并查看该初始dump.rdb文件的大小
![]()
- 进入redis-cli并在30秒内put 12条数据

5.查看dump.rdb文件的大小

6.将dump.rdb备份

7.关闭redis-server,并将dump.rdb删除(相当于redis-server出现故障,我们用备份文件dump.rdb.bak进行恢复)
8.将dump.rdb.bak修改为dump.rdb,并启动redis-server,并查看数据

9.发现dump.rdb中只持久化了10个数据。这是因为在30秒有10个key发生了变化。那么根据配置文件中的配置,就会将这10个Key进行持久化。当第11个key set进入后,就会从当前key重新计时30s,但是在set k11 k12 的时候我们并不满足在30s内变化了10个key,因此这两个并没有被持久化即没有被写进dump.rdb文件中。因此,当我们使用该dump.rdb对redis-server进行启动的时候,并没有k11 和k12。
五.RDB的优势劣势
优势:
- 适合大规模的数恢复
- 对数据完整性和一致性要求不高的场景更加适用
- 节省磁盘空间
- 恢复速度快
劣势:
- Fork的时候,内存中的数据被克隆了一份,大致2倍的膨胀性需要考虑
- 虽然Redis在fork的时候使用写时拷贝技术,但是如果数据庞大时还是比较消耗性能
- 在备份周期在一定间隔时间做一次备份,所以如果redis意外down掉的话,就会丢失最后一次快照后修改的数据。



浙公网安备 33010602011771号