默认的持久化方式,这种方式是就是将内存中数据以快照的方式写入到二进制文件中,默认的文件名为dump.rdb。RDB 触发机制分为使用指令手动触发和 redis.conf 配置自动触发。
指令手动触发
save ,save操作是在主线程中保存快照的,由于redis是用一个主线程来处理所有 client的请求,这种方式会阻塞所有client请求。所以不推荐使用。bgsave,执行该命令时,Redis 会在后台异步执行快照操作,此时 Redis 仍然可以相应客户端请求。具体操作是 Redis 进程执行 fork 操作创建子进程,RDB 持久化过程由子进程负责,完成后自动结束。Redis 只会在 fork 期间发生阻塞,但是一般时间都很短。但是如果 Redis 数据量特别大,fork 时间就会变长,而且占用内存会加倍,这一点需要特别注意。自动触发 RDB 的默认配置如下所示: 配置redis在n秒内如果超过m个key被修改就自动做快照:
save 900 1 # 900秒内如果超过1个key被修改,则发起快照保存 save 300 10 # 300秒内容如超过10个key被修改,则发起快照保存 save 60 10000 # 表示60 秒内如果至少有 10000 个 key 的值变化,则触发RDB如果不需要 Redis 进行持久化,那么可以注释掉所有的 save 行来停用保存功能,也可以直接一个空字符串来停用持久化:save “”。 Redis 服务器周期操作函数 serverCron 默认每个 100 毫秒就会执行一次,该函数用于正在运行的服务器进行维护,它的一项工作就是检查 save 选项所设置的条件是否有一项被满足,如果满足的话,就执行 bgsave 指令。
RDB文件保存过程
redis调用fork,现在有了子进程和父进程。父进程继续处理client请求,子进程负责将内存内容写入到临时文件。由于os的写时复制机制(copy on write),父子进程会共享相同的物理页面,当父进程处理写请求时os会为父进程要修改的页面创建副本,而不是写共享的页面。所以子进程的地址空间内的数据是fork时刻整个数据库的一个快照。当子进程将快照写入临时文件完毕后,用临时文件替换原来的快照文件,然后子进程退出。RDB的优点
整个Redis数据库将只包含一个文件(dump.rdb),方便备份。RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快。RDB 可以最大化 Redis 的性能:父进程在保存 RDB 文件时唯一要做的就是 fork 出一个子进程,然后这个子进程就会处理接下来的所有保存工作,父进程无须执行任何磁盘 I/O 操作。RDB的缺点
每次快照持久化都会将主进程的内存数据复制到子进程内存中,这样将导致内存开销加倍,若此时内存不足,则会阻塞服务器运行,直到复制结束释放内存;子进程内存数据将完整写入磁盘一次,所以如果内存数据量大的话,将会写io操作频繁,必然会引起大量的磁盘I/O操作,严重影响性能由于是子进程保存的是一个快照,所以有可能丢失数据AOF也分为指令手动触发和自动触发
指令手动触发 执行BGREWRITEAOF命令,redis会生成一个全新的AOF文件,其中包括了可以恢复现有数据的最少的命令集。
自动触发,配置策略
appendonly yes # 启用aof持久化方式 appendfsync always # 每次收到写命令就立即强制写入磁盘,最慢的,但是保证完全的持久化,不推荐使用 appendfsync everysec # 每秒钟强制写入磁盘一次,在性能和持久化方面做了很好的折中,推荐(默认) appendfsync no # 完全依赖os,性能最好,持久化没保证AOD文件保存过程
redis调用fork ,现在有父子两个进程子进程根据内存中的数据库快照,往临时文件中写入重建数据库状态的命令父进程继续处理client请求,除了把写命令写入到原来的aof文件中。同时把收到的写命令缓存起来。当子进程把快照内容写入已命令方式写到临时文件中后,子进程发信号通知父进程。然后父进程把缓存的写命令也写入到临时文件。父进程可以使用临时文件替换老的aof文件,并重命名,后面收到的写命令也开始往新的aof文件中追加。需要注意到是重写aof文件的操作,并没有读取旧的aof文件,而是将整个内存中的数据库内容用命令的方式重写了一个新的aof文件,这点和快照有点类似。
AOF的优点
易读,文件中保存的都是操作Redis的命令数据安全有保障,配置每秒追加一次后最多丢失一秒的数据AOF的缺点
AOF 文件的体积通常要大于 RDB 文件的体积AOF 的速度可能会慢于 RDB除了上诉,AOF还有以下特点
如果在追加日志时,恰好遇到磁盘空间满、inode满或断电等情况导致日志写入不完整,也没有关系,redis提供了redis-check-aof工具,可以用来进行日志修复。因为采用了追加方式,如果不做任何处理的话,AOF文件会变得越来越大,为此,redis提供了AOF文件重写(rewrite)机制,即当AOF文件的大小超过所设定的阈值时,redis就会启动AOF文件的内容压缩,只保留可以恢复数据的最小指令集。举个例子或许更形象,假如我们调用了100次INCR指令,在AOF文件中就要存储100条指令,但这明显是很低效的,完全可以把这100条指令合并成一条SET指令,这就是重写机制的原理。在进行AOF重写时,仍然是采用先写临时文件,全部完成后再替换的流程,所以断电、磁盘满等问题都不会影响AOF文件的可用性。通常,如果你要想提供很高的数据保障性,那么建议你同时使用两种持久化方式。如果你可以接受灾难带来的几分钟的数据丢失,那么你可以仅使用 RDB。
目前,通常的设计思路是利用复制(Replication)机制来弥补 aof、rdb性能上的不足,达到了数据可持久化。即 Master 上 rdb 和 aof 都不做,来保证 Master 的读写性能,而 Slave 上则同时开启 rdb 和 AOF 来进行持久化,保证数据的安全性。
https://juejin.im/post/6844903886189395982 https://blog.csdn.net/ljheee/article/details/76284082 https://www.jianshu.com/p/eb2729362c61