专栏首页源码阅读Redis源码走读及编程实践——数据安全篇(一)
原创

Redis源码走读及编程实践——数据安全篇(一)

导语

redis作为内存数据库,为了防止因为程序bug或者机器故障导致的数据丢失,redis采取了多维度的措施来保障redis写入数据的安全。从单机层面:采取备份磁盘镜像+数据流水的形式,将内存状态落地到本地磁盘,防止因程序bug或者系统故障导致的数据丢失;从多机层面:通过主备机制,进行远程热备,保障数据安全。

本文分为拆分为多篇,分别从RDB、AOF、主备等角度介绍redis的数据落磁盘机制,介绍落地原理及相关源码流程、主备机制,包括原理,相关协议,以及具体实现。因笔者能力有限,行文观点若有疏漏,恳请指正。更多内容,移步作者个人博客

磁盘备份

redis通过磁盘实现数据落地,主要通过内存镜像定时备份和记录操作流水两种方式:

  1. 所谓内存镜像定时备份,即RDB(Redis DataBase):redis定时对内存进行全量备份,落地到本地磁盘文件;
  2. 所谓记录操作流水,即AOF(Append Only File):由于内存全量备份资源开销大,因此RDB只能做到定时更新&备份的时间粒度比较大,所以redis又通过记录操作流水的方式(即AOF),实现存储数据操作的回放。

RDB

所谓RDB,即内存镜像备份机制我们主要关注以下几个问题:

  1. 什么情况下,会触发redis进程执行RDB操作?
  2. redis如何进行RDB,期间发生数据的修改怎么办?
  3. RDB文件的格式是怎样,redis如何解析rdb文件?

我们结合代码,逐个问题进行分析。

RDB触发时机

在redis的配置文档中,我们可以看到rdb触发的时机分为两个维度:时间维度和修改维度;当修改次数超过指定配置,或者修改后超过指定时间,则触发RDB流程。
RDB落地频率的配置项

以下为RDB主调流程的框架,其中:

RDB主流程为rdbSaveBackground接口

触发RDB流程分为两种情形:

客户端执行SAVE/BGSAVE指令,主动触发RDB流程;

二者区别在于,save会阻塞主进程直到RDB完成,bgsave会fork子进程执行rdb流程

定时任务触发(serverCron),当指定时间内修改次数超过阈值时触发RDB流程;

RDB流程是互斥的,即同一时刻只能一个RDB流程在跑;在这期间若是出现客户端执行BGSAVE指令,服务器也是不响应的,会推迟到本地RDB结束之后再执行;

redis的主循环

RDB落地流程

redis的RDB是通过fork一个进程实现的,由于进程之间是独立地址空间的,借助Linux的COW机制,当RDB过程中有数据发生修改,被修改的数据只会体现在redis主进程中,对rdb进程没有影响。
另一方面,当redis写请求大的时候,会导致redis内存耗用量变大,为了避免redis在RDB过程中被OOM,需要配置redis的内存占用,避免因为占用内存多大导致进程挂掉。
最大内存占用配置
RDB落地的入口方法
RDB落地的主控流程
RDB键值对落地方法

以上为redis的RDB主流程,主要包括以下几点:

  1. redis通过fork子进程的形式进行RDB,父进程主要负责一些数据管理和状态记录,实际数据落地操作交给子进程来做;父子进程通过管道进行通信
  2. redis的落地和数据分为三层:
    1. 文件级:主要写入文件头、DB和系统相关的管理信息;在接口rdbSave和rdbSaveRio中进行
    2. DB级:逐个DB进行处理,包括每个DB的大小、DB ID等信息;主要在接口rdbSaveRio中进行
    3. 数据级:即DB里面每个KV对,主要在接口rdbSaveKeyValuePair中进行
  3. 需要落地的数据包括:
    1. Redis-server的元数据,包括redis版本号、系统信息、redis占用内存的大小等
    2. Database元数据信息:redis版本、键值对数目等
    3. DB中的字段
    4. 每个DB的lua脚本
  4. 由于字典rehash会触发系统的COW机制,所以为了降低内存开销,在RDB过程中,关闭rehash
  5. RDB文件的格式为:
RDB文件格式
RDB文件中每个DB的存储格式
DB中每个键值对的格式

RDB文件加载

Redis-server在启动过程中,会根据指令加载指定位置的rdb文件,核心流程的代码如下:

主要需要注意的是:

  1. Redis-server实例启动之后,在完成初始化工作后,通过调用栈:loadDataFromDisk-> rdbLoad->rdbLoadRio完成rdb文件的载入;其中loadDataFromDisk是根据标志位走入rdb分支还是AOF分支,而rdbLoad主要为RDB流程进行相关的准备工作;而真正载入rdb数据的,是rdbLoadRio接口
  2. server.loading是用于标识当前是否处于加载文件的阶段,这个标志位会对很多模块的逻辑产生影响,亦即,若是在加载rdb文件过程中,很多操作是不允许被执行的
  3. 超时的KV,在载入RDB数据的时候会删除掉

参考资料

  1. 《Redis设计与实现》黄建宏著
  2. https://www.cnblogs.com/winterfells/p/9161540.html
  3. https://cloud.tencent.com/developer/article/1427626
  4. https://unix.stackexchange.com/questions/33381/getting-information-about-a-process-memory-usage-from-proc-pid-smaps
  5. https://blog.csdn.net/u010902721/article/details/46446031
  6. https://blog.csdn.net/petib_wangwei/article/details/38225929
  7. http://www.web-lovers.com/redis-source-rdb.html
  8. http://sunny90.com/a/server/2014/0905/103.html

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Redis源码走读及编程实践——数据安全篇(二)

    《Redis源码走读及编程实践——数据安全篇(一)》介绍了RDB的落地原理并走读了redis的RDB落地流程,本文继续介绍redis的另外一种数据落地机制AOF...

    王鹏程1990
  • redis代码走读与编程实践——网络交互篇(上)

    redis是一种内存数据存储系统,可被用作数据库、缓存、消息队列等;以高性能、高并发能力著称;本文分为上下两篇,其中上篇主要着眼于最简单的单机数据库&非事务命令...

    王鹏程1990
  • redis代码走读与编程实践——网络交互篇(下)

    在文章《redis代码走读与编程实践——网络交互篇(上)》中,对redis连接请求与建立流程进行源码剖析和走读;本文主要尝试编写一个简单的redis客户端和re...

    王鹏程1990
  • 有了它,Redis不再是你技术面试中的阻碍

    Redis在互联网技术存储方面使用非常广泛,几乎所有的后端技术面试官都要在Redis的使用和原理方面对求职小伙伴们进行各种刁难,特别是那些优秀的、竞争激烈的大型...

    博文视点Broadview
  • 2021 最新的Java 后端学习路线!凎!

    断断续续写了大半个月,终于把 2021 最新版的 Java 后端学习路线给整完了!

    Guide哥
  • Redis 深度历险:核心原理与应用实践

    Redis 是互联网技术架构在存储系统中使用最为广泛的中间件,它也是中高级后端工程师技术面试中面试官最喜欢问的工程技能之一,特别是那些优秀的、竞争激烈的大型互联...

    Bug开发工程师
  • 小白和进阶都适用! java学习路上必看的书单

    男怕入错行,女怕嫁错郎,学java最怕看错书!也是很久之前就想写这篇了,以前也零零星星的推荐过几本书,但是始终没有这样认真的整理一篇出来,这篇文章就是和...

    微笑的小小刀
  • 七种武器之一口箱子Redis

    江湖传言「在任何规模、任何类型的服务器项目中,都存在一些最适合用Redis存储的数据。」

    有福
  • 进BAT这些互联网大厂,面试之前刷几百道面试题真的有用吗?

    面试之前先刷几篇面经,或者做几道热门面试题,想必是大家很熟悉的一种复习方式了,就像我们当年经常做五年高考三年模拟一样。但是可不要把面试题和面经当成你的主要复习...

    美的让人心动
  • 惊艳!阿里内部445页爆款Redis源码分析宝典终开源

    在开源界,高性能服务的典型代表就是Nginx和Redis。纵观这两个软件的源码,都是非常简洁高效的,也都是基于异步网络I/O机制的,所以对于要学习高性能服务的程...

    烂猪皮
  • 【真荐书】双11书单,我们一起共读 36 + 1 本书

    《Redis开发与运维》全面讲解 Redis 基本功能及其应用,并结合线上开发与运维监控中的实际使用案例,深入分析并总结了实际开发运维中遇到的“陷阱”,以及背后...

    kirito-moe
  • 基于实践:一套百万消息量小规模IM系统技术要点总结

    本文由公众号“后台技术汇”分享,原题“基于实践,设计一个百万级别的高可用 & 高可靠的 IM 消息系统”,原文链接在文末。由于原文存在较多错误和不准确内容,有大...

    JackJiang
  • (码友推荐)2018-07-09 .NET及相关开发资讯速递

    4.为什么Kubernetes获得了胜利?--让Kubernetes成为开发人员最喜欢的容器编排平台的的秘诀是什么? - DockOne.io

    Rector
  • 2017年,Java程序猿10本经典好书推荐

    1、Java 8实战 本书全面介绍了Java 8 这个里程碑版本的新特性,包括Lambdas、流和函数式编程。有了函数式的编程特性,可以让代码更简洁,同时也能自...

    Java技术栈
  • Spring Boot整合ELK 处理为服务日志,妙!

    在排查线上异常的过程中,查询日志总是必不可缺的一部分。现今大多采用的微服务架构,日志被分散在不同的机器上,使得日志的查询变得异常困难。工欲善其事,必先利其器。如...

    OwenZhang
  • 阿里,百度,腾讯一线互联网公司中,Java开发的招聘标准(文末福利)!

    精讲java
  • 学习 Java,有什么书籍推荐?学习的方法和过程是怎样的?

    为什么要学 Linux 呢?因为在实际的开发工作中,项目基本上都要部署到 Linux 环境下。Windows 作为服务器的很少,除了慢没别的原因。

    AI码师
  • 今日推荐:awesome-architecture

    但是这条路还是有很多人走,而且也留下了相应的封神之法,今天推荐的就是一个相当详细的架构师框架学习图。内容很充实,看目录的时候,滚动条滚了很多次!学习起来肯定也不...

    仇诺伊
  • BATJTMD,大厂招聘,都招什么样Java程序员?

    最近总看到类似这样的问题,也有一些工作3年左右的小伙伴问小傅哥,该怎么进大厂。其实你说 Java 学多少可以找到工作,主要看你想在哪个城市找、找什么样的公司、找...

    小傅哥

扫码关注云+社区

领取腾讯云代金券