Redis持久化
1、持久化方式
Redis提供两种持久化方式:①RDB持久化(原理:将Reids在内存中的数据进行周期性快照存储,dump到磁盘文件进行持久化);②AOF(append only file)持久化(原理:将Reids的操作日志以追加方式写入文件)。
AOF持久化机制:对每条写入命令作为日志、以append-only模式写入一个日志文件中,在redis重启时通过AOF写入的指令来重新构建整个数据集。
通过RDB和AOF都可以将redis内存中的数据持久化到硬盘上,然后将数据备份到云服务器上。
2、RDB原理
两种方式:手动方式与自动方式。
①手动方式:
使用save命令:此命令会使用Redis主线程进程同步存储,阻塞当前的Redis服务器,造成服务不可用,影响整个RDB过程完成。
使用bgsave命令:通过fork()创建子进程在后台进程存储。只有fork阶段会阻塞当前Redis服务器,不会影响整个RDB过程结束,耗时很短。因此Redis内部涉及到RDB都采用bgsave命令。注意:无论RDB还是AOF,由于使用写时复制,fork出来的子进程不需要拷贝父进程的物理内存空间,但是会复制父进程的空间内存页表。
②自动方式:
一般不会直接用命令生成RDB文件的,Redis支持自动触发RDB持久化机制,默认在redis.conf配置文件中。
save 900 1 #表示300 秒内,如果至少有1个key的值变化,则保存
save 300 10 #表示300 秒内,如果至少有10个key的值变化,则保存
save 60 10000 #表示60 秒内,如果至少有10000个key的值变化,则保存
stop-writes-on-bgsave-error yes #yes:bgsave命令失败时Redis停止写入操作;no:bgsave命令失败时Redis继续写入操作;
rdbcompression yes #是否对RDB文件进行压缩,LZF压缩会消耗更多CPU
rdbchecksum yes #是否对RDB文件进程校验
dbfilename dump.rdb #配置文件名称,默认dump.rdb
dir ./ #文件存储路径,默认当前路径
rdb-save-incremental-fsync yes #
①Redis调用系统的fork()函数创建一个子进程;
②子进程将数据集写入一个临时的RDB文件;
③当子进程完成对临时的RDB文件的写入时,Redis用新的RDB文件来替换原来旧的RDB文件并将旧的RDB文件删除。
Redis在进行快照的过程中不会对旧的RDB文件进行修改,只有快照结束后才会将旧快照替换成新快照,也就是说任何时候RDB都是完整的。
3、AOF原理
①手动方式:
使用bgrewriteoaf命令:Redis主进程fork子进程来执行AOF重写,这个子进程创建新的AOF文件来存储重写数据,防止影响旧文件。fork采用写时复制机制,子进程不能访问被创建后产生的新数据。Redis使用“AOF重写缓冲区”保存这部分新数据,最后父进程将AOF重写缓冲区的数据写入新的AOF文件中然后使用新AOF文件替换老文件。
②自动方式:和RDB相同,配置在redis.conf文件中。
appendonly no #是否打开AOF持久化功能
appendfilename "appendonly.aof" #AOF文件名称
appendfsync everysec #同步频率
no-appendfsync-on-rewrite no #no:是最安全的方式,不会丢失数据,但会发生阻塞。yes:相当于appendfsync设置为no,说明没有执行磁盘操作,只是写入缓冲区,这样不会造成阻塞(因为没有竞争磁盘),但是如果此时Redis挂掉会丢失数据。丢失多少数据呢?在linux的操作系统的默认设置下,最多会丢失30s的数据。
auto-aof-rewrite-percentage 100 #Redis记录最近一次AOF操作的文件大小,如果当前AOF文件大小增长超过这个百分比则触发一次重写,默认100
auto-aof-rewrite-min-size 64mb #如果文件大小小于此值不会触发AOF,默认64MB
aof-load-truncated yes #指Redis在恢复时,是否忽略最后一条可能存在问题的指令。默认值yes,在aof写入时,可能存在指令写错的问题(突然断电部分写入),此时yes会log并继续;而no会直接恢复失败
aof-use-rdb-preamble yes #aof与rdb混合模式
aof-rewrite-incremental-fsync yes #每次批量写入磁盘的数据量控制参数,默认为32M。避免单次刷盘数据过多造成硬盘阻塞。
appendfsync参数的可配置值:
always:命令写入aof缓冲区后,每一次写入都需要同步写入磁盘(阻塞,系统调用fsync)结束后返回。显然和Redis高性能背道而驰,不建议配置
everysec:命令写入aof缓冲区后,在写入系统缓冲区直接返回(系统调用write),然后有专门线程每秒执行写入磁盘(阻塞,系统调用fsync)后返回
no:命令写入aof缓冲区后,在写入系统缓冲区直接返回(系统调用write)。之后写入磁盘(阻塞,系统调用fsync)的操作由操作系统负责,通常最长30s
4、持久化方式优劣势对比
RDB优势:
①全量备份:RDB是一个非常紧凑的文件,它保存了某个时间点的数据集,非常适用于数据集的备份。比如,你可能打算每个小时归档一次最近24小时的数 据,同时还要每天归档一次最近30天的数据。通过不同备份策略,一旦出现灾难性故障,根据需求恢复到不同版本的数据集;
②传输:RDB是一个紧凑的单一文件,很方便传送到另一个远端数据中心,非常适用于灾难恢复;
③IO性能:对于Redis的服务进程而言,在开始持久化时,它唯一需要做的只是fork出子进程,之后再由子进程完成这些持久化的工作,这样就可以极大的避免服务进程执行IO操作了。
④相比于AOF,如果数据集很大,RDB的启动效率会更高。
RDB劣势:
①如果想保证数据的高可用性,即最大限度的避免数据丢失,那么RDB将不是一个很好的选择。因为系统一旦在周期性持久化之前出现宕机,此时未及时写入磁盘的数据将会丢失;
②由于RDB是通过fork子进程来协助完成数据持久化工作的,当数据集较大时,可能会导致整个服务器停止服务几百毫秒,甚至是1秒钟。
AOF优势:
①AOF可以带来更高的数据安全性,即数据持久性。Redis中提供了3中同步策略,即每秒同步、每修改同步和不同步。事实上,每秒同步也是异步完成的,效率也是非常高的,所差的是一旦系统出现宕机现象,那么这一秒钟之内修改的数据将会丢失。而每修改同步,我们可以将其视为同步持久化,即每次发生的数据变化都会被立即记录到磁盘中。可以预见,这种方式在效率上是最低的。至于无同步,不再赘述。
②AOF对日志文件的写入操作采用的是append模式,写入过程中即使发生宕机,也不会破坏日志文件中已经存在的内容。如果是在写入数据过程中发生系统崩溃问题,可以在Redis下一次启动之前,通过redis-check-aof工具来帮助我们解决数据一致性的问题。
③如果日志过大,Redis可以自动启用rewrite机制。即Redis以append模式不断的将修改数据写入到旧的磁盘文件中,同时Redis还会创 建一个新的文件用于记录此期间有哪些修改命令被执行。因此在进行rewrite切换时可以更好的保证数据安全性。
④AOF包含一个格式清晰、易于理解的日志文件用于记录所有的修改操作。可以通过该文件进行数据的重建。
AOF劣势:
①对于相同数量的数据集,AOF文件通常要大于RDB文件。RDB在恢复大数据集时的速度比AOF的恢复速度要快。
②根据同步策略的不同,AOF在运行效率上往往会慢于RDB。