开发者学堂课程【Redis 数据库入门:Redis_AOF_RDB 持久化_2】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/15/detail/56
Redis_AOF_RDB 持久化_2
内容介绍:
一、RDB 持久化
二、RDB 文件储存的数据
三、总结
四、AOF 持久化
一、RDB持久化
1、BGSAVE 创建 RDB 文件
BGSAVE 创建子进程,会消耗额外的内存。因此 SAVE 创建 RDB 文件的速度比BDSAVE 快,谈论两者的优劣需要综合考虑。SAVE 创建速度较快,但是其会阻塞服务器,可能会需要维护。在服务器空闲时,比如在夜里的时候,可以直接使用SAVE,速度较快。
2、自动创建 RDB 文件
自动创建 RDB 文件需要写入服务器要满足的条件,以上节课在配置文件看到记录为例:
(1)save 300 10
“300”表示 seconds,即“秒”,“10”表示 changes,即“写入数据的记录”,整体表示“如果距离上一次创建 RDB 文件已经过去了300秒,并且服务器所有数据库一共已经发生了不少于10次的修改,就会执行 BGSAVE 命令”,换言之,从上一次进行 BGSAVE 到这次进行 BGSAVE 的300秒间隔之内,如果超过了10次的修改,就会执行落地文件。
(2)再如 save 60 10000
表示“如果距离上一次创建 RDB 文件已经过去了60秒,并且服务器所有数据库一共已经发生了不少于10000次的修改,就会执行 BGSAVE 命令”。若进行频繁操作,每60秒进行一次 BGSAVE 操作。则表示从上一次进行 BGSAVE 到这次进行BGSAVE 的60秒间隔之内,如果超过了10000次的修改,就会执行落地文件。
(3)默认情况
save 900 1
save 300 10
save 60 10000
默认情况下会写入以上三条,只要任意满足一条,服务器就会调用 BGSAVE 命令,而不是累加。简言之,若60秒修改次数达到10000条,即会执行一次 BGSAVE 命令。继而开始记录下一次执行 BGSAVE 命令的间隔时间,而不会累计。而如果长时间没有进行操作,如果间隔时间约为300秒,则判断是否有超过10次修改,而如果超过900秒都没有操作,则有一次修改则记录一次,进行一次持久化。
以上配置可以根据自身业务需求,自行配置条件,甚至可以配置多个条件。在每次创建 RDB 文件之后,服务器为实践自动持久化而设置时间计数器和次数技术器就会被清零,并开始重新技术,多个保存条件的效果是不会累加的。
打开配置文件,可以看到默认的3条配置,可以对其进行修改,也可以增加更多的条件。
二、RDB文件存储的数据
如果 RDB 文件中存储了部分数据,而这部分数据是二进制文件,无法直接打开查看。而如果可以打开该二进制文件,里面会体现多个数据库,
如下图所示:
其中存储的是 redis,后面 db0、db1、……dbN 是指0号到 N 号数据库的各个数据库,其中各自存储着各类数据。如0号数据库,打开后里面存的各个间值段,可以发现其首先存储的是超时的时间(EXPIRETIME_MS),然后存储间值的类型(REDIS_RDB_TYPE_STRING)(此处储存的值的类型为 string)最后存储的是间的值,可以看出它是以压缩的种格式存储的。最后会有 checksome。
三、总结
1、Redis 提供 RDB 持久化和 AOF 持久化这两种持久化功能,用于将存储在内存里面数据库数据以文件的形式保存到磁盘中,以避免因为服务器关闭而导致数据。
2、RDB 文件是一个二进制文件,常见的三种创建 RDB 文件的方法是:
(1)手动执行 SAVE 命令;
(2)手动执行 BGSAVE 命令;
(3)使用 SAVE 选项设置保存条件(配置条件),当满足配置条件的情况下,服务器自动执行 BGSAVE,其中配置文件的格式是 save second(时间/秒) changes(修改次数)。
需要区别的一点是 save 会阻塞服务器,而 bgsave 不会阻塞服务器,因为后者是通过 fork 子进程的方式,使得子进程执行创建 RDB 文件的操作。而由于执行该操作的是子进程,因此执行 BGSAVE 会比执行 SAVE 消耗更多的内存,创建 RDB 文件的速度也比较慢。
3、RDB 持久化中的每一个 dump.rdb 文件需要定期拷贝转移,并以当时的名称命名,后续即可根据需求还原每时刻的数据。这是由于每次执行命令都会覆盖旧文件,而没有增量的备份,因此需要自行把其拷贝转移。
4、RDB 文件是一个整体的落地证明,而不会切割为多个文件,如果数据库较大,则文件也对应的也较大,创建的速度相应就会很慢比较慢。而实际操作过程中,服务器一般不会重启,即使重启的话,内存数据库也较小,写入的数据很难达到几十GB。
四、AOF持久化
1、功能
AOF 持久化存储的不是真正的数据,而是操作。RDB 持久化是将数据以二进制的文件存储在磁盘中,其缺点在于创建 RDB 文件需要将服务器所有的数据都保存起来,非常消耗资源和时间,而且要执行该操作,服务器需要隔一段时间创建 RDB 文件,如果在该时间段之内,负载超标导致宕机,则需要重启,重新加载 RDB,也就是在间隔之内操作数据会丢失。为防止在该时间段内数据丢失,可以整合 AOF 持久化以解决 RDB 文件的操作不能执行过于频繁的问题,否则会影响服务器的性能。
如果按照 RDB 持久化中配置文件中的条件进行配置:
save 900 1
save 300 10
save 60 10000
至少每60秒创建1次 RDB 文件,在这60秒钟一旦服务器意外停机,可能导致数据丢失。而 AOF 持久化相对于 RDB 持久化来说,其具有一些巨大的优势,即用户可以根据自己需要对 AOF 持久化的进行调整,让Redis在遭遇意外停机的时候不丢失任何的数据,因为其把每一条间隔之内的每条命令都进行了记录。在恢复数据的时候,先把21位加载进来,再来执行 AOF 的命令,就会回到宕机之前那个时刻的数据状态。需要强调的是 AOF 持久化会记录执行命令。
2、运作原理
AOF 保存数据库的方法:每当有修改数据库的命令被执行的时候,服务器就会将执行的命令写入到 AOF 文件的末尾,并不断追加,因此该种持久化方式被命名为Append Only File 。因为 AOF 文件中存储了服务器所有的数据修改命令,所以给定一个 AOF 文件,服务器只要重新执行一遍所有命令就可以达到还原数据库的目的。
如果建立一个 msg 文件“hello”,就会将这条命令写到 AOF 文件中,然后INCR counter 又会写入 AOF 文件,接下来 SADD 又会往创建的集合里写入元素“a”“b”“c”,也会将命令写入 AOF 文件。
3、实例
对于包含以下内容的 AOF 文件来说,会写入许多条命令:
SELECT 0
SET msg “hello”
INCR counter
SADD alphabets “a ” “b” “c”
INCR counter
而服务器只要重新执行些命令就可以还原出下图的数据库。
4、安全性问题
虽然服务器执行修改数据库命令,就会被执行的命令写入到 AOF 文件,但是,这并不意味着 AOF 文件持久化不会丢失任何数据。严格意义上来说,即使使用了 AOF持久化,它也并不意味着100%任何的数据不会丢失。在目前常见的操作系统中,执行系统调用 write 函数,将一些内容写到某个文件里面时,为了提高效率,系统通常不会直接将内容写入到硬盘里面,而是先将它写入到内存缓存区(buffer),这是系统级别的操作,等到缓冲区被填满或者用户执行 fsync 调用和 fdatasync 调用时才会将内存缓存区中缓存的数据的真正写入到硬盘中。也就是说,从写入文件命令开始到真正写入文件存在时间间隔。
如果系统操作中 buffer 没有充满,往 AOF 文件里面写入命令,就会显示没有追加,而恰巧此时宕机了,数据仍旧会丢失,因为数据此时还在系统里的 buffer 里面。为解决此类问题,AOF 有一些针对性的策略。
(1)对于 AOF 持久化来说,当一条命令真正被写入硬盘时,这条命令才不会因为宕机而意外丢失。因此,AOF 持久化在遭遇停机时丢失的命令的数量取决于被写入硬盘的时间,越早将命令写入到硬盘,发生意外宕机时丢失数据都越少,而越晚写入到硬盘,发生意外停机时丢失数据就越多。
(2)越频繁地写入命令,不断地将数据从系统 buffer 中调用,使其去写入磁盘,系统中cpu的消耗越多。
5、AOF 持久化数据安全性策略
为了控制 Redis 服务器在遇到意外停机时丢失的数据量,Redis 为 AOF 持久化提供了 appendfsync 选项,这个选项的值可以是 always、everysec 或 no,也就是 AOF 持久化的三个策略:
(1)Always:服务器还没有写入命令,Redis 就调用了一次 fdatasync(调用系统里的函数),将缓冲区里的命令写入到硬盘中。在种模式下呢,服务器即使遭遇意外停机也不会丢失任何数据,但是该种情况下 Redis 只要写入命令,就会落地到AOF,导致落地磁盘的数量较为庞大,可能会影响服务器的性能
(2)everysec:sec 表示的是 seconds,即服务器每秒会重新调用函数,将缓冲区里的命令写入到硬盘中。在这种模式下,服务器即使遭遇停机,最多只丢失一秒的命令数据。
(3)no:并不是指不写入命令,而是指 Redis 服务器不主动调用系统里的fdatasync,而取决于系统 buffer 本身,丢失命令的数量是不确定的。
从运行的速度来说,always 速度慢,everysec 和 no 较快;
默认值:everysec,配置文件中默认是每秒落地一次 AOF 文件。


