我是靠谱客的博主 开放麦片,最近开发中收集的这篇文章主要介绍为什么redis不能保证100%数据不丢失起因准备环境阅读源码,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

为什么redis不能保证100%数据不丢失

  • 起因
  • 准备环境
  • 阅读源码

起因

  前段时间面试被问到,Redis能否保证100%数据不丢失,我回答不能。面试官又问,为什么呢?我一时语塞,慌忙回答因为异步写盘。
  随后我在百度上搜了搜,发现很多博客都讲,将appendfsync值设置为always就可以了。这回答让我对《redis设计与实现》产生了怀疑。难道新版本的redis能够保证数据100%不丢失?!
  搜不到答案,自己找答案好了,于是开始阅读redis源码。

准备环境

  1. 下载source insight4.0软件,阅读c代码很方便。
  2. 下载redis4源码,解压,源码位于src下
  3. 附上redis源码结构

阅读源码

  1. 按照知乎上的源码结构,并未找到redis.c,应该是server.c
  2. 打开server.c,找到main函数在这里插入图片描述
    main函数最后,有调用事件循环的函数
    在这里插入图片描述
    我们进入aeMain函数看下在这里插入图片描述
      可以看到,是一个while循环,我们把这个循环叫做事件循环。在循环中做了两件事情,分别是执行beforesleepaeProcessEvents方法。
      重点关注下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%数据不丢失起因准备环境阅读源码所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(37)

评论列表共有 0 条评论

立即
投稿
返回
顶部