[redis] redis数据持久化
1. 数据持久化的步骤
一次完整的数据从客户端到达服务端磁盘的过程如下:
a. 客户端执行向服务端发送数据的写操作(数据保存在客户端内存中,忽略拷贝时经过内核和网卡缓存/缓冲,因为情况可能不完全相同)
b. redis服务器接受到数据(数据被redis接收并保存在内存用户空间中,此处忽略网卡和socket缓存)
c. 客户端通过系统调用向磁盘写入数据(由于现代操作系统缓存IO的特性,实际上数据被拷贝到了系统缓冲区)
d. 操作系统将缓冲区数据写入磁盘中(数据进入磁盘缓存)
e. 磁盘控制器将数据写入磁盘物理介质中
其中第c步,可能由于开启DirectIO而被跳过,而第d步,由于目前民用级磁盘缓存仅针对读操作起效,因此一般也会被跳过。
只要进行到了c步,那么即使redis故障数据也不会丢失。而若服务器完全故障(如断电或宕机),则只有完成e步后数据才不会丢失。
2. RDB持久化
redis的默认持久化方式,在指定时间间隔中将内存数据快照写入磁盘。
可以通过配置设置自动快照持久化的方式,例如设置redis在n秒内若超过m个key被修改,则自动做快照。
RDB文件保存过程
利用fork的copy-on-writ机制;
redis在触发写入快照操作后,fork得到子进程;
父进程继续处理请求,子进程则负责写入内容;
父子进程会继续共享相同的内存页面,直到父进程收到请求需要进行修改,才会创建新的副本并复制数据。这样可以确保尽量不浪费资源和提高效率,同时保证子进程写数据不受干扰。
子进程将数据快照写入临时文件后,将原本的快照文件进行替换,随后子进程退出。
优势
a. 便于备份和管理(一次快照生成一个文件)
b. 恢复大数据集时更快(因为只有单个文件)
c. 对redis性能影响甚微
劣势
a. 快照保存间隔较长,仍有丢失数据风险(尤其是对保存数据敏感的业务)
b. 执行快照保存时,若数据集较为庞大,因为产生子进程的开销较大,会产生服务停顿现象(此时系统资源被fork占用)
3. AOF文件保存过程
redis每次收到的写(更新)命令都通过系统调用追加写入到文件中。
因为系统的缓存IO特点,仍有可能在宕机时有部分数据被保存在系统缓冲区而未被写入磁盘,redis配置可以设置AOF的磁盘写入策略(立即强制写入磁盘、每秒钟强制写入磁盘、完全依赖系统策略)
压缩AOF持久化文件
redis提供了bgrewriteaof命令以将AOF的追加写文件压缩未类似于快照的数据文件。
注意:此过程没有读取旧的AOF文件,而是备份了内存中数据集的快照。
过程为:
redis调用fork得到子进程
子进程根据内存中的数据向临时文件中写入数据快照
父进程继续处理请求,除继续追加写AOF文件以外,还缓存这些新的写命令
子进程完成快照写入并通知父进程,父进程将缓存的写命令写入临时文件
父进程使用临时文件替换旧的AOF文件,之后新的写命令向新的AOF文件追加。
优势
a. 相比于RDB,不会产生卡顿,并且也可以保证数据几乎不会丢失。
b. AOF文件是一个 append only log,即使写入时产生了意外(磁盘故障、停机等),也可以被快速修复。
c. AOF更容易被阅读和分析,便于运维工程师使用。
劣势
a. AOF文件体积显著大于RDB文件。
b. AOF速度可能慢于RDB。
c. 某些以外情况可能会导致恢复时出现bug。
4. 对比和选择
如果对数据安全性要求极高的话,可以采用同时开启两种持久化方式的办法。
如果数据安全性要求相对不高,可以接受数分钟内的数据丢失,可以只使用RDB。
如果仅仅能接受一点点的数据丢失,那么可以使用AOF。
浙公网安备 33010602011771号