概述
为什么redis不能保证100%数据不丢失
- 起因
- 准备环境
- 阅读源码
起因
前段时间面试被问到,Redis能否保证100%数据不丢失,我回答不能。面试官又问,为什么呢?我一时语塞,慌忙回答因为异步写盘。
随后我在百度上搜了搜,发现很多博客都讲,将appendfsync值设置为always就可以了。这回答让我对《redis设计与实现》产生了怀疑。难道新版本的redis能够保证数据100%不丢失?!
搜不到答案,自己找答案好了,于是开始阅读redis源码。
准备环境
- 下载source insight4.0软件,阅读c代码很方便。
- 下载redis4源码,解压,源码位于src下
- 附上redis源码结构
阅读源码
- 按照知乎上的源码结构,并未找到redis.c,应该是server.c
- 打开server.c,找到main函数
main函数最后,有调用事件循环
的函数
我们进入aeMain函数看下
可以看到,是一个while循环,我们把这个循环叫做事件循环
。在循环中做了两件事情,分别是执行beforesleep
和aeProcessEvents
方法。
重点关注下beforesleep方法,具体的执行函数在server.c中被设置进来aeSetBeforeSleepProc(server.el,beforeSleep);
。所以到server.c中搜索beforeSleep
方法。
注释写的很详细,在函数末尾,有flushAppendOnlyFile(0);
的调用,会将aof buffer写到磁盘上。看一看flushAppendOnlyFile方法:
我们读一读函数注释,大体意思就是:先把写命令追加到aof buffer中,下一次进入事件循环循环后,再将buffer写到磁盘上。
结合while循环处方法的调用顺序,可以看出确实是这样的。那么也就是说,这次写到磁盘上的内容是上一个事件循环产生的。看下flushAppendOnlyFile完整的代码:
注释很详细,在方法最后部分,有if (server.aof_fsync == AOF_FSYNC_ALWAYS)
的判断,如果条件符合,会使用fdatasync()
的方法来写磁盘。
到这里,我们可以肯定,redis即使在配制appendfsync=always
的策略下,还是会丢失一个事件循环的数据
,与《redis设计与实现》中的相关描述一致。
最后
以上就是开放麦片为你收集整理的为什么redis不能保证100%数据不丢失起因准备环境阅读源码的全部内容,希望文章能够帮你解决为什么redis不能保证100%数据不丢失起因准备环境阅读源码所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复