redis学习系列(八)--redis-AOF基础
来源:互联网 发布:mac修改mysql登录密码 编辑:程序博客网 时间:2024/06/05 05:06
redis另外一种持久化方式就是AOF方式(Append Only File)
上一篇 RDB的持久化方式是通过保存键值对来记录数据库状态的不同,AOF持久化不同点在于它不是通过键值对,而是通过保存Redis服务器执行的写命令来记录的。
这样的话感觉在实时性上面,AOF是要优于RDB的,因为这样至少能保证不会丢数据,而RDB方式的话会丢到达到它保存条件中间的一部分数据。
例如:
对于上面的操作过程:
RDB方式:保存的是键值对
AOF方式:保存的是set命令
注意的是,第一行是出现了一个SELECT命令,这是Redis自动添加的,说明这个数据是存在哪一个数据库内的
AOF持久化的实现
AOF持久化功能的实现分为命令追加(append)、文件写入、文件同步(sync)三个步骤
命令追加
当AOF功能打开时,服务器在执行完一个写命令之后,会以协议格式将被执行的命令追加到服务器状态的aof_buf缓冲区的末尾
struct redisServer { sds aof_buf; /* AOF buffer, written before entering the event loop */}
AOF文件的写入和同步
这里面讲到一个事件的概念,暂时我还不清楚,不过知道下Redis的服务器进程就是一个事件循环,这个循环中的文件事件负责接收客户端的命令请求,以及向客户端发送命令回复,而另外一个时间事件则负责执行定时运行的函数。
这是因为当服务器在处理文件事件时可能会执行写命令,使得有一些命令被追加到了aof_buf缓冲区里面,因此在一个事件循环结束之前,都会调用flushAppendOnlyFile函数,考虑是否需要将aof_buf缓冲区的内容写入和保存到AOF文件里面
flushAppendOnlyFile函数的行为是受配置项的值决定的
关于AOF持久化的效率和安全性
一般受推荐的配置就是everysec。
AOF文件的载入与数据还原
可见上图中的简单流程图,需要创建一个伪客户端(fake clinet)
AOF重写及实现
AOF是保存命令行的,对比RDB不同,有可能对于一直set操作,RDB最终保存的是键值对,而AOF保存的是set命令,这就造成了,如果你不断的修改set的值,那么最终结果其实只有一个,但是命令却有1000行。那么还原的时间就会越长,相信Redis肯定解决了这个问题,就是重写操作。
例如下面的操作,这一篇就不去改了,下一篇会去着重试验,而且虚拟机出了一点问题,,,只能截图了现在
可以看见对一个list进行了至少5个操作,但是AOF确保存了6条命令,因此Redis提供了重写(rewrite)功能,通过此功能,Redis服务器可以创建一个新的AOF文件来代替现有的AOF文件,新旧两个AOF所保存的数据库状态相同,单新的AOF不会包含冗余命令。
实现
但是重写并不是去读取现有的AOF文件,而是直接从数据库中读取键值对,然后用一条命令去记录键值对,代替之前的多条命令,这就是重写功能的实现原理。
保存之后的状态:可以看见没有一条多余的命令
这边有个实际处理的问题,我也没有实践过,记录一下:
列表、哈希表等集合会有很多元素,当元素数量超过64个时,会将一条命令拆分成两个,至于为什么,不清楚,效率?内存?不懂。
#define REDIS_AOF_REWRITE_ITEMS_PER_CMD 64
AOF后台重写
重写函数aof_rewrite可以很好的完成创建一个新的AOF文件,但是这个函数会大量的进行写入操作,因此会被长时间阻塞,那么Redis不能处理来自客户端的任何请求了,因此在此处也会出现一个子进程用于AOF的重写。
但是考虑下面一个问题,万一在子进程在重写的阶段,父进程一直在处理请求,此时键值对的值改变了,但是子进程怎么知道呢,它读到的数据库内的值可能在它刚读完之后就立马改变了。
为了解决这个问题,Redis设置了一个AOF缓冲区,这个缓冲区在服务器创建子进程之后开始使用,当Redis执行完一个写命令之后,会同时将写命令发送给AOF缓冲区和AOF重写缓冲区。
根据上图可知道一些信息:
1.服务器进程执行客户端发来的命令。
2.将执行后的写命令追加到AOF缓冲区。
3.将执行后的写命令追击到AOF重写缓冲区。
这样能保证几点:
1.AOF缓冲区的内容会定期被写入和同步到AOF文件,对现有AOF文件的处理工作会正常进行,不影响
2.从创建子进程开始,服务器的所有写命令会被记录到AOF重写缓冲区里面,保证写命令不丢失。
当子进程完成AOF重写工作之后:
一旦子进程完成AOF重写之后,会发送一个信号给父进程,父进程处理以下事情:
1.调用信号处理函数(这个函数不知道是什么函数),将AOF重写缓冲区的所有内容写入到新AOF文件中,这保证了新AOF文件所保存的数据库状态和服务器当前的一致。
2.对新AOF文件进行改名,原子地覆盖现有AOF文件,完成交替。
这边注意下,对于AOF重写缓冲区的数据是父进程在子进程完成之后保存的,不是子进程读取写入的,我一开始还天真的以为是子进程边读边写,,,,,
因此看下这边的流程,只有信号处理函数时父进程调用的,当调用它时,才会阻塞父进程。其实我这边我不清楚一个问题,在AOF重写缓冲区里面是不是存储的可能是多条命令,比如set num 1; set num 2;set num 3,这里并没有提到这个问题,应该是这样的,重写的时候读取的是数据库的键值对,但是缓冲区存储的确是命令。
- redis学习系列(八)--redis-AOF基础
- redis学习系列(八)--redis-RDB基础
- redis学习系列(九)--redis-AOF和RDB实践
- Redis源码学习-AOF
- redis学习之 aof
- 《Redis源码学习笔记》AOF
- redis aof
- redis aof
- redis-AOF
- redis-aof
- redis学习系列(四)--redis基础SDS的构造
- redis学习系列(五)--redis基础字典的构造
- 【Redis】redis的AOF
- Redis关键点(AOF)
- redis系列(一)redis基础
- 结合redis设计与实现的redis源码学习-13-AOF持久化(aof.c/bio.h)
- Redis系列~列表(List)(八)
- Redis windows学习(二)——Redis的AOF模式和RDB模式
- 最全的JS DOM操作集合
- Android笔试面试指南
- 观察者模式
- PullToRefreshScrollView和Banner
- 普元EOS之我要初始化数据库
- redis学习系列(八)--redis-AOF基础
- CSS3实现三角形
- ASP.NET的DataList和Repeater控件
- python-sklearn中RandomForestClassifier函数以及ROC曲线绘制
- 通过代码认识openstack 环境中连接到rabbit服务器
- JavaScript继承的方式
- Node.js学习笔记(一)安装
- AngularJS 用户名查询、年龄查询、性别查询、全部删除、批量删除、添加用户、修改密码
- win10 uwp ApplicationView