Redis的持久化一共有三种
- AOF
- RDB
- 混合模式
AOF
AOF是通过一种将写操作执行后,将命令记录在文件当中,当系统重启后只要重新加载AOF文件就能实现数据的持久化的方式。
AOF持久化的流程
在看完AOF持久化的流程以后,相信都有一点对AOF的理解了,现在我们就来了解一下AOF为了实现持久化都做了哪些操作,以及为什么这么做?
命令追加
Redis进行命令追加是在缓存中执行写命令之后再将命令记录的,那么为什么需要这么做呢?
原因有二:
- 可以减少对语句合法的检测,减少试错成本。如果是先执行的记录操作,Redis的命令错误,还要重新修改AOF中记录的语句。
- 避免线程阻塞。因为Redis的写操作和命令追加都是在主线程里面执行操作的,如果此时IO的速度很慢是有可能阻塞主线程的,所以在写操作执行以后再去将命令写入到AOF文件中就不会导致线程阻塞。
但是AOF也还是有一些潜在风险的,比如:会阻塞下一个写入的命令、先写后记在突然断电这类场景下会有数据丢失的情况。
而这些潜在的风险其实都有一个共同的相同点就是和写入的时机有关。
AOF写入时机
AOF一共有三种写入时机(也叫写回策略)
- appendfsync always:主线程调用 write 执行写操作后,后台线程( aof_fsync 线程)立即会调用 fsync 函数同步 AOF 文件,fsync 完成后线程返回,这样会严重降低 Redis 的性能(write + fsync)。
- appendfsync everysec:主线程调用 write 执行写操作后立即返回,由后台线程( aof_fsync 线程)每秒钟调用 fsync 函数(系统调用)同步一次 AOF 文件(write+fsync,fsync间隔为 1 秒)
- appendfsync no:主线程调用 write 执行写操作后立即返回,让操作系统决定何时进行同步,Linux 下一般为 30 秒一次(write但不fsync,fsync 的时机由操作系统决定)。
可以看出:这 3 种持久化方式的主要区别在于 fsync
同步 AOF 文件的时机。
这三种写入时机虽然不能够同时解决阻塞主线程和数据丢失的问题,但是也能解决一样。
AOF重写
当AOF文件过大的时候,这个时候会触发AOF的重写机制。AOF 重写机制是在重写时,读取当前数据库中的所有键值对,然后将每一个键值对用一条命令记录到「新的 AOF 文件」,等到全部记录完后,就将新的 AOF 文件替换掉现有的 AOF 文件。
总结
将写命令添加到 AOF 文件(Append Only File)的末尾。
使用 AOF 持久化需要设置同步选项,从而确保写命令同步到磁盘文件上的时机。这是因为对文件进行写入并不会马上将内容同步到磁盘上,而是先存储到缓冲区,然后由操作系统决定什么时候同步到磁盘。有以下同步选项:
选项 | 同步频率 |
---|---|
always | 每个写命令都同步 |
everysec | 每秒同步一次 |
no | 让操作系统来决定何时同步 |
- always 选项会严重减低服务器的性能;
- everysec 选项比较合适,可以保证系统崩溃时只会丢失一秒左右的数据,并且 Redis 每秒执行一次同步对服务器性能几乎没有任何影响;
- no 选项并不能给服务器性能带来多大的提升,而且也会增加系统崩溃时数据丢失的数量。
随着服务器写请求的增多,AOF 文件会越来越大。Redis 提供了一种将 AOF 重写的特性,能够去除 AOF 文件中的冗余写命令。
RDB
RDB执行流程
相对于AOF来说RDB的实现就简单很多了。
RDB会将某个时间点的所有数据都存放到硬盘上。
可以将快照复制到其它服务器从而创建具有相同数据的服务器副本。
如果系统发生故障,将会丢失最后一次创建快照之后的数据。
如果数据量很大,保存快照的时间会很长。
不过要尽量避免使用save命令,因为会在主进程中创建RDB的快照可能会导致主线程的堵塞。
RDB与AOF的选择
RDB的优缺点
优点:数据都是经过压缩的二进制数据,文件更小,恢复起来更快。
缺点:数据丢失会更多。因为是每隔一段时间才保存一次。
AOF的优缺点
优点:数据丢失量少,记录的格式简单便于后期的分析。
缺点:由于Redis是单线程的所以在进行写回的时候很慢。重写期间如果有数据的修改,需要执行两次。
总结
Redis 保存的数据丢失一些也没什么影响的话,可以选择使用 RDB。
不建议单独使用 AOF,因为时不时地创建一个 RDB 快照可以进行数据库备份、更快的重启以及解决 AOF 引擎错误。
如果保存的数据要求安全性比较高的话,建议同时开启 RDB 和 AOF 持久化或者开启 RDB 和 AOF 混合持久化。
混合持久化
为了让Redis的持久化既能拥有RDB那样的恢复速度,又能拥有AOF那样的数据安全性。Redis推出了混合持久化的方式。混合持久化就是在AOF重写的时候将原来的数据以RDB格式写入到AOF文件中,后面主线程的新增数据就会以AOF的形势被保留。
这样的好处在于,重启 Redis 加载数据的时候,由于前半部分是 RDB 内容,这样加载的时候速度会很快。
加载完 RDB 的内容后,才会加载后半部分的 AOF 内容,这里的内容是 Redis 后台子进程重写 AOF 期间,主线程处理的操作命令,可以使得数据更少的丢失。当然缺点也是有的, AOF 里面的 RDB 部分是压缩格式不再是 AOF 格式,可读性较差。
参考文献