一、复制技术
1. 快照snapshot:保存待备份文件某一时刻的状态,出问题可以回滚。便捷,但是实时性不高。
2. 写时复制Copy-on-Write:复制一个对象不是开新内存多放一份,而是在新对象的内存映射表中指向原对象的位置;修改时先复制到新位置,修改内存映射,进行写入操作。 优点:复制时节省内存空间,读操作不会复制。 缺:大文件修改时要复制一遍或者比较上个版本,比较费时。
二、Redis的持久化
redis是基于内存的存储,持久化能保证数据安全。redis的持久化分为RDB和AOF,默认开启RDB。
1. RDB:Redis DataBase
1. 原理:将某一时刻的数据生成快照存储到磁盘,默认开启rdb。
2. 执行频率:在redis.conf中配置在n秒内超过m个key被修改时,触发RDB操作。
3. 持久化的过程:fork一个子进程做持久化的操作:先写到一个临时文件dump.rdb,持久化结束后用临时文件替换上次的rdb文件,保证快照文件总是完整可用的。
4. 优:子进程中备份,不影响主进程效率。
缺:不适合对数据完整性要求高的场景:当redis发生故障时,距离上一次RDB之间的操作都丢失了
2. AOF:Append Only File
1. 原理:aof文件只允许追加不允许修改,redis执行过的所有写指令追加在文件末尾(类似mysql的binlog),回复数据时按顺序重跑整个aof文件中的指令即可。aof默认关闭,在redis.conf中配置 appendonly yes 可打开aof。
2. 执行频率:默认每秒fsync一次,把缓存中的写指令通过磁盘IO写到aof文件。
3. 优:每秒追加一次,数据完整性更高。加日志时如果出问题了,可以通过redis-check-aof工具做日志修复。
在aof文件被重写之前,可以直接删aof中的指令恢复之前的场景(比如flushAll,手速快也能恢复)。
缺:AOF文件比RDB文件体积大,恢复速度也更慢;
4. AOF文件重写机制:
原因:追加模式如果不处理的话文件会越来越大。当文件大小超过阈值时会进行内容压缩,只保留恢复数据的最少指令集。如:N条incr合成一条set。
流程:AOF重写机制也会fork一个子进程,先写临时文件,写完之后通知父进程把写指令写到新文件文件,完成替换。 重写时不是基于原aof文件的,而是基于copy-on-write全量遍历内存中数据,然后依次加到AOF文件中(不基于原aof文件重写是为了防止[指令记录+merge+回放]这种方式出现bug)。
手动触发aof重写:BGREWRITEAOF指令
缺点:重写期间,所有的写操作需要双写。 优点是可靠高效。
3. RDB和AOF的对比
1. RDB安全性较差,但是文件尺寸较小,数据恢复速度快,在redis的“正常时间”,数据备份和主从同步用RDB效率高。
2. AOF更安全、数据完整性更高;但是AOF需要更多的磁盘IO开销、文件尺寸更大、数据恢复速度相对较慢;
master 通常使用AOF(保证数据完整性),slave 使用RDB(快速响应客户端的read请求)