`
DiaoCow
  • 浏览: 244352 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

《Redis源码学习笔记》RDB

阅读更多
《Redis源码学习笔记》文章列表

由于图片较大,缩放较为模糊,请双击打开查看原图 ^_^

主从复制过程中,我们提到过RDB文件,作为Redis持久化方式之一,RDB把数据库某一时刻的内容,也就是快照,以二进制的方式记录到文件,并且在下次启动的时候可以用来初始化Redis;

RDB最重要的两个过程是rdbSave和rdbLoad,下面我就这两个过程分别叙述;

rdbSave
在具体看rdbSave过程之前,我们先看下RDB文件格式:



我们可以简单思考下,RDB文件协议为什么会那样设计?
1. RDB文件以"REDIS"开头是为了区分普通文件,这样redis在加载的时候,读取前五个字节就可以判断该文件是否为一个合法的RDB文件;
2. 写明RDB文件版本是因为不同版本之间有一定差异性,根据版本号需要保持向下兼容;
3. 以数据库为单位,存入键值对,因为一个redis实例中,可以包含16个数据库,所以一定要标明该键值对属于哪个数据库,否则无法还原到相应位置;
4. 在写入键值对信息时,超时时间是可选的,标明值类型(value-type)是为了在加载的时候知道这是一个string,还是list或者hashtable;

rdbSave过程就是把redis每一个数据库中的键值对按照上面定义的格式写入文件,伪代码:
def rdbSave(filename):
    # 创建临时文件,用于保存rdb数据
    tempFile = createTempFile()
    rio = rioInitWithFile(tempFile)
    # ----------------------------------
    # 1.保存RDB文件版本
    rdbSaveVersion(rio, "REDIS" + REDIS_RDB_VERSION)
    # 2.保存redis所有数据库中的键值对
    for db in redisServer.dbs:
        # 记录键值对所在数据库
        rdbSaveSelectDB(rio, db.num)
        # 保存该数据库中所有键值对
        for key, val in db.getKeyValuePairs():
            expired_time = getExpiredTime(key)
            rdbSaveKeyValuePair(rio, key, val, expired_time)
    # 3.写入RDB文件结束符
    rdbSaveEOF(rio, REDIS_RDB_OPCODE_EOF)
    # 4.写入校验和
    rdbSaveCkSum(rio)    
    # ----------------------------------
    # 确认数据都被flush到磁盘
    fsync()
    rename(tempFile, filename)    

def rdbSaveKeyValuePair(rio, key, val, expired_time):
    if expired_time != -1:
        # 过滤过期键
        if expired_time < now_time:
            return
        rdbSaveMillisecondTime(rio, expired_time)
    # 保存值类型(list? string? hashtable?)
    rdbSaveValueType(rio, val)
    # 保存键
    rdbSaveKey(rio, key)
    # 保存值
    rdbSaveValue(rio, val)

更多细节请看:rdb.c/rdbSave函数

触发rdbSave过程,主要有4种方式:
1. SAVE命令
2. BGSAVE命令
3. master接收到slave发来的sync命令
4. 定时save(配置文件中制定)

第一种情况,Redis保存RDB文件是在主进程中进行,所以在这其间,Redis无法响应客户端请求(再次强调:Redis是单线程Server);第二种情况,Redis fork出一个子进程,然后在子进程中进行rdbSave,因此也就不会阻塞主进程对客户端请求的处理;第三种情况和第四种情况同第二种情况,也是在子进程中进行;

rdbLoad
rdbload过程就比较简单了,它会按照RDB文件协议,把键值对还原到相应的数据库,伪代码:
def rdbLoad(filename):
    rio =  rioInitWithFile(filename);
    # 设置标记:
    # a. 服务器状态:rdb_loading = 1
    # b. 载入时间:loading_start_time = now_time
    # c. 载入大小:loading_total_bytes = filename.size
    startLoading(rio)
    # ------------------------------------------
    # 1.检查该文件是否为RDB文件(即文件开头前5个字符是否为"REDIS")
    if !checkRDBHeader(rio):
        redislog("error, Wrong signature trying to load DB from file") 
        return
    # 2.检查当前RDB文件版本是否兼容(向下兼容)
    if !checkRDBVersion(rio): 
        redislog("error, Can't handle RDB format version") 
        return
    # 3.读取文件内容,加载键值对
    while not end_of_file:
        # 每循环一千次就处理一下客户端请求
        if loops % 1000  == 0:
            processClientRequest()

        key, val, expired_time, dbnum = rdbLoadKeyValuePair()
        # 过滤过期键
        if expired_time != -1 and expired_time <= now_time: 
            continue

        redisServer.db[dbnum].dict.add(key,value)
        if expired_time > now_time
            redisServer.db[dbnum].expires.add(key, expired_time)
        loops = loops + 1

    # 4. 校验和
    if (!checkCkSum()): return
    # ------------------------------------------
    # 更新标记:rdb_loading = 0
    stopLoading()

触发rdbLoad过程,主要有两种方式:
1. Redis启动时候的初始化;
2. slave接收到master发来的RDB文件;

总结:
1. 了解RDB文件格式;
2. 了解rdbSave和rdbLoad过程以及触发条件;



  • 大小: 4.2 KB
分享到:
评论

相关推荐

    Redis全套学习笔记

    Redis 安装简单,可以通过源码编译或使用包管理器安装。启动Redis有前台和后台两种方式,后台启动更常见。Redis 可通过`redis-cli`命令行工具进行交互,提供一系列命令用于操作数据库。 2. Redis 数据类型: - **...

    狂神redis源码笔记.rar

    在“狂神redis源码笔记”中,我们可以期待学习到Redis的源码分析、内部机制以及如何通过Java进行高效操作。源码分析是深入理解Redis工作原理的关键,有助于开发者优化使用方式或进行定制化开发。 Redis的核心知识点...

    7.Redis学习笔记.pdf

    Redis支持数据持久化,可以通过RDB(快照)和AOF(追加文件)两种方式来保存数据到硬盘,使得即使在系统崩溃的情况下数据也不会丢失。在配置文件中,可以通过修改不同的配置项来控制持久化的行为。 在安装Redis时,...

    redis入门学习笔记

    Redis是一个开源的、基于内存的数据...总的来说,Redis入门学习笔记详细介绍了Redis的特性、安装、数据类型、使用场景、备份与恢复、性能测试、Python客户端使用等基础知识和技巧,非常适合新手作为入门学习的资料。

    Redis的学习笔记

    Redis 的环境搭建相对简单,可以从官方网站或源码仓库下载最新稳定版本的源码包,例如 Redis 2.0.4。解压后通过 `make` 命令编译,编译完成后会有 `redis-server` 和 `redis-cli` 两个可执行文件。直接运行 `./redis...

    Redis学习笔记

    本学习笔记将基于提供的压缩包文件,深入探讨Redis的关键特性、工作原理以及常见应用场景。 首先,"深入redis学习(一)--readme and conf.doc"介绍了Redis的安装和配置过程。在配置文件中,我们可以设置服务器的...

    redis学习笔记

    ### Redis 学习笔记知识点概览 #### 一、Redis 简介及特性 - **Redis**(Remote Dictionary Server)是一种开源的、基于内存的数据结构存储系统,它支持多种数据结构,如字符串(strings)、散列(hashes)、列表...

    燕十八redis视频教程笔记资料

    首先,从官方网站下载最新稳定版的Redis源码或二进制包。在Linux环境下,可以使用编译源码的方式进行安装,涉及到`make`和`make install`等命令。对于Windows用户,可直接下载预编译的二进制包,解压后配置环境变量...

    Redis学习笔记整理

    ### Redis学习笔记整理 #### 一、Redis环境搭建 ##### 1.1 简介 Redis是一款开源的键值(Key-Value)型数据库系统,因其高性能和丰富的数据结构而广受欢迎。它不仅可以作为数据库使用,还可以作为一种数据结构服务器...

    2022年redis学习笔记

    这份2022年的Redis学习笔记涵盖了Redis的基础概念、核心特性、使用场景以及最佳实践。 一、Redis简介 Redis是一个开源(BSD许可)的,非关系型、内存中的数据结构存储系统,可以用作数据库、缓存和消息中间件。它...

    Redis学习笔记1

    本文将基于提供的“Redis学习笔记1”内容,详细介绍Redis的安装、启动、单线程特性、发布订阅机制、持久化策略以及AOF和RDB的区别。 1. **Redis安装与启动** Redis的安装通常涉及下载源码包、解压、编译和安装。在...

    redis学习笔记,redis详解,Java源码.zip

    Redis是一款高性能的键值对数据库,它以内存存储为主,数据持久...通过阅读本学习笔记和源码分析,你可以深入了解Redis的工作原理,掌握如何在实际项目中高效地使用Redis。不断实践和探索,你将成为Redis的熟练驾驭者。

    Redis.zip学习笔记

    在"Redis.zip学习笔记"中,我们可以预期包含以下几个主要的知识点: 1. Redis简介:Redis是一个开源(BSD许可),内存中的数据结构存储系统,它可以用作数据库、缓存和消息代理。它支持多种数据结构,如字符串、...

    redis初级入门笔记

    Redis 是一个高性能的键值对数据库,常被用于数据缓存、消息队列以及数据库功能。...同时,不断学习和实践 Redis 的高级特性,如事务、持久化策略、集群等,将有助于提升你的数据库管理和应用开发能力。

    redis学习笔记详细整理手册

    本手册详细整理了Redis的学习过程,包括基础概念、安装部署和实战应用。 一、Redis基础知识 Redis是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。它的数据模型包括字符...

    Redis全面深入学习笔记(强烈推荐).docx

    在深入学习Redis时,还需要掌握更多高级特性,如持久化(RDB和AOF)、事务、发布订阅、主从复制、哨兵系统和Cluster集群等。理解这些特性将有助于在实际应用中更好地利用Redis的优势。此外,了解Redis的数据结构(如...

    Redis笔记.md

    1. **下载安装包**:通常是从Redis官方网站获取最新的源码包。 2. **解压**:使用命令行工具进行解压。 3. **编译安装**:利用`make`和`make install`完成编译安装过程。 4. **环境配置**:通过`yum`安装必要的依赖...

Global site tag (gtag.js) - Google Analytics