Redis的数据是如何持久化的?
- 一种是RDB方式、
- 则“定时”将内存中的数据存储在硬盘上
- 另一种是AOF(append-only-file)方式。
- 在每次执行命令后将命令本身记录下来
- 两种持久化方式可以单独使用其中一种,
- 也可以将这两种方式结合使用
RDB方式
- 当符合一定条件时,
- Redis会单独创建(fork)一个子进程来进行持久化,
- 会先将数据写入到一个临时文件中,等到持久化过程都结束了,
- 再用这个临时文件替换上次持久化好的文件。
- 整个过程中,主进程是不进行任何IO操作的,
- 这就确保了极高的性能。
- RDB的缺点是最后一次持久化后的数据可能丢失
- --fork的作用是复制一个与当前进程一样的进程。
Redis会在以下几种情况下对数据进行快照
- 根据配置规则进行自动快照
- Redis允许用户自定义快照条件,
- 当符合快照条件时,Redis会自动执行快照操作
- 配置格式如下:
- save 900 1
- 第一个参数是时间窗口,第二个是键的个数
- 在900秒(15分)内有一个以上的键被更改则进行快照。
- 每条快照规则占一行,每条规则之间是“或”的关系。
- save 900 1
- Redis允许用户自定义快照条件,
- 用户执行SAVE或者GBSAVE命令
- 当我们对服务进行重启或者服务器迁移我们需要人工去干预备份
- redis提供了两条命令来完成这个任务
- save命令
- 当执行save命令时,Redis同步做快照操作,
- 在快照执行过程中会阻塞所有来自客户端的请求。
- 当redis内存中的数据较多时,
- 通过该命令将导致Redis较长时间的不响应。
- 所以不建议在生产环境上使用这个命令,
- 而是推荐使用bgsave命令
- 当执行save命令时,Redis同步做快照操作,
- bgsave命令
- bgsave命令可以在后台异步地进行快照操作,
- 快照的同时服务器还可以继续响应来自客户端的请求。
- 执行BGSAVE后,Redis会立即返回ok表示开始执行快照操作。
- bgsave命令可以在后台异步地进行快照操作,
- save命令
- 通过LASTSAVE命令可以获取最近一次成功执行快照的时间;
- (自动快照采用的是异步快照操作)
- 执行FLUSHALL命令
- 会清除redis在内存中的所有数据
- 执行该命令后,只要redis中配置的快照规则不为空,也就是save 的规则存在。
- redis就会执行一次快照操作。
- 不管规则是什么样的都会执行。
- 如果没有定义快照规则,就不会执行快照操作
- 执行复制(replication)时
- 在主从模式下,redis会在复制初始化时进行自动快照。
- 这里只需要了解当执行复制操作时
- 即使没有定义自动快照规则,并且没有手动执行过快照操作,
- 它仍然会生成RDB快照文件
AOF方式
- 当使用Redis存储非临时数据时,
- 一般需要打开AOF持久化来降低进程终止导致的数据丢失。
- AOF可以将Redis执行的每一条写命令追加到硬盘文件中,
- 这一过程会降低Redis的性能,
- 但大部分情况下这个影响是能够接受的,
- 另外使用较快的硬盘可以提高AOF的性能
- 开启AOF
- 默认情况下Redis没有开启AOF
- 可以通过appendonly参数启用,
- 在redis.conf 中找到 appendonly yes
- 开启AOF持久化后
- 每执行一条会更改Redis中的数据的命令后
- Redis就会将该命令写入硬盘中的AOF文件。
- 每执行一条会更改Redis中的数据的命令后
- AOF文件的保存位置和RDB文件的位置相同,
- 都是通过dir参数设置的,
- 默认的文件名是apendonly.aof.
- 可以在redis.conf中的属性 appendfilename appendonlyh.aof修改
- 都是通过dir参数设置的,
- AOF的实现
- AOF文件以纯文本的形式记录Redis执行的写命令
- 通过vim的方式可以看到aof文件中的内容
- set foo 1
set foo 2
set foo 3
get - 从内容中我们发现Redis只记录了3 条命令
- get 未记录
- 这时有一个问题是前面2条命令其实是冗余的
- 随着执行的命令越来越多,AOF文件的大小也会越来越大,
- 其实内存中实际的数据可能没有多少
- 因此我们希望Redis可以自动优化AOF文件
- 实际上Redis也考虑到了,可以配置一个条件,
- 每当达到一定条件时Redis就会自动重写AOF文件,
- 这个条件的配置问 auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb
- auto-aof-rewrite-percentage
- 表示的是当目前的AOF文件大小
- 超过上一次重写时的AOF文件大小的百分之多少时
- 会再次进行重写,如果之前没有重写过,
- 则以启动时AOF文件大小为依据
- auto-aof-rewrite-min-size
- 表示限制了允许重写的最小AOF文件大小,
- 通常在AOF文件很小的情况下
- 即使其中有很多冗余的命令我们也并不太关心。
- BGREWRITEAOF 命令手动执行AOF,
- 执行完以后冗余的命令已经被删除了
- 在启动时,Redis会逐个执行AOF文件中的命令来将硬盘中的数据载入到内存中,
- 载入的速度相对于RDB会慢一些
- set foo 1
AOF的重写原理
- 重写后的新 AOF 文件包含了恢复当前数据集所需的最小命令集合。
- 重写的流程是这样,
- 主进程会fork一个子进程出来进行AOF重写,
- 这个重写过程并不是基于原有的aof文件来做的,
- 而是有点类似于快照的方式,全量遍历内存中的数据,
- 然后逐个序列到aof文件中。
- 在fork子进程这个过程中,服务端仍然可以对外提供服务,
- 这个过程中,主进程的数据更新操作,会缓存到aof_rewrite_buf中,
- 也就是单独开辟一块缓存来存储重写期间收到的命令,
- 当子进程重写完以后再把缓存中的数据追加到新的aof文件。
- 当所有的数据全部追加到新的aof文件中后,把新的aof文件重命名,
- 此后所有的操作都会被写入新的aof文件。
- 如果在rewrite过程中出现故障,不会影响原来aof文件的正常工作,
- 只有当rewrite完成后才会切换文件。
- 因此这个rewrite过程是比较可靠的
- 这个过程中,主进程的数据更新操作,会缓存到aof_rewrite_buf中,