redis的持久化有两个方式:RDB快照和AOF
redis是默认做数据持久化操作的,默认的方式是快照(snapshotting),把内存中的数据写到本地文件dump.rdb文件中,
快照的实现原理:Redis借助了fork命令的copy on write机制。在生成快照时,将当前进程fork出一个子进程,然后在子进程中循环所有的数据,将数据写成为RDB文件,使用redis的save命令调用这个过程
RDB快照持久化的优点:
1. RDB是一个非常紧凑的文件,它保存了某个时间点得数据集,非常适用于数据集的备份,比如您可以在每个小时报保存一下过去24小时内的数据,同时每天保存过去30天的数据,这样即使出了问题您也可以根据需求恢复到不同版本的数据集.
2. RDB是一个紧凑的单一文件,很方便传送到另一个远端数据中心或者亚马逊的S3(可能加密),非常适用于灾难恢复.
3. RDB在保存RDB文件时父进程唯一需要做的就是fork出一个子进程,接下来的工作全部由子进程来做,父进程不需要再做其他IO操作,所以RDB持久化方式可以最大化redis的性能。
4. 与AOF相比,在恢复大的数据集的时候,RDB方式会更快一些.
RDB快照持久化的缺点:
一旦数据库出现问题,那么我们的RDB文件中保存的数据并不是全新的,从上次RDB文件生成到Redis停机这段时间的数据全部丢掉了
AOF日志的全称是append only file,从名字上我们就能看出来,它是一个追加写入的日志文件.
实现原理:
在使用aof时,redis会将每一个收到的写命令都通过write函数追加到文件中,当redis重启时会通过重新执行文件中保存的写命令来在内存中重建整个数据库的内容.Redis还能对AOF文件通过BGREWRITEAOF 重写,使得AOF文件的体积不至于过大.
由于AOF是把操作日志写入日志文件中,那么AOF的操作安全性如何保证?可以在配置文件中通过配置告诉redis我们想要使用fsync函数强制写入到磁盘的时间。
配置分为三种:
1. appendfsync no
当设置appendfsync为no的时候,Redis不会主动调用fsync去将AOF日志内容同步到磁盘,所以这一切就完全依赖于操作系统的调试了。对大多数Linux操作系统,是每30秒进行一次fsync,将缓冲区中的数据写到磁盘上。
2. appendfsync everysec
当设置appendfsync为everysec的时候,Redis会默认每隔一秒进行一次fsync调用,将缓冲区中的数据写到磁盘。但是当这一次的fsync调用时长超过1秒时。Redis会采取延迟fsync的策略,再等一秒钟。也就是在两秒后再进行fsync,这一次的fsync就不管会执行多长时间都会进行。这时候由于在fsync时文件描述符会被阻塞,所以当前的写操作就会阻塞。所以,结论就是,在绝大多数情况下,Redis会每隔一秒进行一次fsync。在最坏的情况下,两秒钟会进行一次fsync操作。这一操作在大多数数据库系统中被称为group commit,就是组合多次写操作的数据,一次性将日志写到磁盘。
3. appednfsync always
当设置appendfsync为always时,每一次写操作都会调用一次fsync,这时数据是最安全的,当然,由于每次都会执行fsync,所以其性能也会受到影响。
AOF的优点:
1. 使用AOF会更加持久化数据。
2. redis可以在aof文件过大时使用BGREWRITEAOF 进行重写
3. 保存的aof日志格式文件是按照redis协议的格式保存,很容易读取。
AOF的缺点:
1. 对于相同的数据集来说,AOF 文件的体积通常要大于 RDB 文件的体积
2. 速度没有RDB速度快。
3. 在写入内存数据的同时将操作命令保存到日志文件,在一个并发更改上万的系统中,命令日志是一个非常庞大的数据,管理维护成本非常高,恢复重建时间会非常长,这样导致失去aof高可用性本意。另外更重要的是Redis是一个内存数据结构模型,所有的优势都是建立在对内存复杂数据结构高效的原子操作上,这样就看出aof是一个非常不协调的部分。其实aof目的主要是数据可靠性及高可用性.