前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Redis源码走读及编程实践——数据安全篇(一)

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

原创
作者头像
王鹏程1990
修改2021-06-19 18:55:49
7860
修改2021-06-19 18:55:49
举报
文章被收录于专栏:源码阅读源码阅读

导语

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触发时机

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

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

RDB主流程为rdbSaveBackground接口

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

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

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

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

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

redis的主循环
redis的主循环

RDB落地流程

代码语言:txt
复制
redis的RDB是通过fork一个进程实现的,由于进程之间是独立地址空间的,借助Linux的COW机制,当RDB过程中有数据发生修改,被修改的数据只会体现在redis主进程中,对rdb进程没有影响。
代码语言:txt
复制
另一方面,当redis写请求大的时候,会导致redis内存耗用量变大,为了避免redis在RDB过程中被OOM,需要配置redis的内存占用,避免因为占用内存多大导致进程挂掉。
最大内存占用配置
最大内存占用配置
RDB落地的入口方法
RDB落地的入口方法
RDB落地的主控流程
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文件格式
RDB文件中每个DB的存储格式
RDB文件中每个DB的存储格式
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

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

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 导语
  • 磁盘备份
    • RDB
      • RDB触发时机
      • RDB落地流程
      • RDB文件加载
  • 参考资料
相关产品与服务
云数据库 Redis
腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档