Redis的持久化机制有两种:RDB持久化和AOF持久化。因为Redis是一个内存数据库,如果没有合适的持久化机制,那么一旦服务器进程退出,服务器中的数据库状态也会消失。本章介绍RDB持久化机制。

RDB持久化

RDB持久化,是Redis可以将数据库状态保存到一个RDB文件中,并可以通过该RDB文件生成RDB文件的时候的数据库状态。RDB文件是一个经过压缩的二进制文件。

生成RDB文件的Redis命令有两个:

  1. SAVE
  2. BGSAVE

SAVE命令会阻塞Redis服务器,此期间服务器不能处理任何命令请求;

BGSAVE命令是派生(fork)出一个子进程,然后子进程负责创建RDB文件,服务器继续处理命令请求;

BGSAVE命令执行的服务器状态

BGSAVE期间,服务器处理SAVE、BGSAVE、BGREWRIREAOF三个命令的方式与平时不同。

BGSAVE期间,服务器会直接拒绝客户端发送的SAVE命令,服务器禁止SAVE命令与BGSAVE命令同时进行是为了避免服务器进程和子进程同时执行两个rdbSave调用产生竞争条件。

同理,BGSAVE期间的BGSAVE命令也会直接拒绝。

BGREWRITEAOF和BGSAVE两个命令不能同时执行:

  • 如果BGSAVE命令正在执行,客户端发送的BGREWRITEAOF命令会被延迟到BGSAVE命令执行完毕之后执行;
  • 如果BGREWRITEAOF命令正在执行,那么客户端发送的BGSAVE命令会被服务器拒绝;

BGREWRITEAOF和BGSAVE不能同时使用主要是处于性能的考虑,因为两个命令都需要执行大量的磁盘写入操作。

自动间隔性保存

在Redis中,用户可以通过save选项设置多个保存条件,只要其中任意一个条件满足,服务器便执行BGSAVE命令

save 900 1

save 间隔时间(单位为秒) 修改次数

在源码底层的体现是,所有的save选项条件是通过一个saveparam结构保存的。

点击查看代码
struct saveparam {
time_t seconds;
int changes;
};

服务器状态维持了一个dirty计数器和lastsave属性,dirty计数器记录了距离上一次成功执行SAVE命令或者BGSAVE命令之后服务器对数据库状态进行修改的次数。lastsave是一个UNIX时间戳,记录了服务器上一次成功执行SAVE命令或者BGSAVE命令的时间。

然后Redis有一个服务器周期函数,用来周期检查是否满足save条件,如果满足则进行BGSAVE。

以上便是Redis自动进行间隔性数据保存的原理。

RDB文件结构

RDB文件分为五个部分:REDIS、db_version、databases、EOF、check_sum。

REDIS

REDIS部分的作用:标识该文件是一个RDB文件。

保存着“REDIS”五个字符。

db_version

db_version部分的作用:标识RDB文件的版本号。

databases

databases部分的作用:存储数据库信息。

databases部分包含零个或任意多个数据库,以及各个数据库的键值对。

若服务器的数据库状态为空,那么该部分也为空。否则存储各个数据库的信息。

每一个非空数据库在RDB文件中可以保存为SELECTDB、db_number、key_value_pairs三个部分。

SELECTDB长度为1字节,表示接下来读入的会是一个数据库号码。

db_number保存着一个数据库号码,根据号码不同,服务器使用SELECT命令进行数据库切换。

key_value_pairs部分保存数据库中所有键值对数据,包括如果有过期时间便带有过期时间。

key_value_pairs

key_value_pairs分为三个部分:TYPE,key,value。

TYPE记录的是value的类型,有以下几种常量:

  1. REDIS_RDB_TYPE_STRING
  2. REDIS_RDB_TYPE_LIST
  3. REDIS_RDB_TYPE_SET
  4. REDIS_RDB_TYPE_ZSET
  5. REDIS_RDB_TYPE_HASH
  6. REDIS_RDB_TYPE_LIST_ZIPLIST
  7. REDIS_RDB_TYPE_SET_INTSET
  8. REDIS_RDB_TYPE_ZSET_ZIPLIST
  9. REDIS_RDB_TYPE_HASH_ZIPLIST

带有过期时间的键值则在三个部分的前面在加上两个部分:EXPIRETIME_MS,ms。

前面的为标记是存在过期时间的,后面的为过期时间。

value的编码

value的编码中的编码与Redis底层数据类型有关,这里我们先写value的编码。

字符串对象

字符串对象是TYPE为REDIS_RDB_TYPE_STRING的对象。

字符串对象存在可以存储INT值的编码,如果为此种编码,那么在文件中的存储便是先存储编码,再存储值。

ENCODING | integer

字符串对象如果是存储字符串的编码,有压缩和不压缩两种方法保存字符串。

若字符串长度小于20字节,那么便会原样保存;若字符串长读大于20字节,那么便压缩之后再保存。

如果是无压缩的字符串,存储在RDB文件中便是先存储字符串长度,再存储值。

len | string

如果是压缩的字符串,那么存储在RDB中的格式如下:

REDIS_RDB_ENC_LZF(标识已被LZF算法压缩) | compressed_len(压缩后长度) | origin_len(字符串原长度) | compressed_string(压缩之后的字符串)

列表对象

列表对象的RDB文件存储格式如下:

list_length(列表长度) | item1 | item2 | itemN

集合对象

与列表对象类型,只是TYPE会不同。

set_size(列表长度) | elem1 | elem2 | elemN

哈希表对象

哈希表的RDB文件存储格式如下:

hash_size|key_value_pair1|……

有序集合对象

与集合对象只是TYPE不同。

INTSET对象

TYPE为REDIS_RDB_TYPE_SET_INTSET,然后将其转换为字符串对象。读取RDB文件时候,会将字符串对象转换为原来的INTSET对象。

ZIPLIST编码的列表、哈希表或者有序集合

value为一个压缩列表对象,读取时只是根据TYPE不同进行逆过程。

总结

RDB是Redis两种持久化方法之一。

RDB优点:

  1. 生成多个数据文件,每一个数据文件代表某一个时刻的redis的数据,适合冷备份。
  2. RDB对redis对外提供读写服务影响小,可以让redis保持高性能。
  3. 相较于AOF持久化机制而言更快。

RDB缺点:

  1. RDB是一个自动间隔性保存的机制,所以丢失数据量可能会比AOF多。
  2. 如果RDB文件过大,会导致对客户端提供的服务暂停一段时间。

Redis学习详解(一):Redis持久化机制之RDB的更多相关文章

  1. Redis学习——详解Redis配置文件(三)

    一.Redis脚本简介 在我们介绍Redis的配置文件之前,我们先来说一下Redis安装完成后生成的几个可执行文件: redis-server .redis-cli .redis-benchmark ...

  2. 【Redis】Redis事务详解,Redis事务支持回滚(不支持悲观锁)

    1.redis事物参考:https://baijiahao.baidu.com/s?id=1613631210471699441&wfr=spider&for=pc (php操作red ...

  3. Redis配置文件详解(redis.conf)

    # vi redis.conf   daemonize yes #是否以后台进程运行 pidfile /var/run/redis/redis-server.pid    #pid文件位置 port ...

  4. redis 数据类型详解 以及 redis适用场景场合

    1.  MySql+Memcached架构的问题 实际MySQL是适合进行海量数据存储的,通过Memcached将热点数据加载到cache,加速访问,很多公司都曾经使用过这样的架构,但随着业务数据量的 ...

  5. redis 数据类型详解 以及 redis适用场景场合(滴滴)

    滴滴的面试官问了个问题关于redis的: 我现在想服务器每分钟接收一个用户的请求小于60个,如何处理: 答:使用Redis 缓存服务器,可以设置key=用户ID value不停地加一到了60就停止,然 ...

  6. Redis原理详解

    Redis原理详解 数据类型 Redis最为常用的数据类型主要有以下五种: String Hash List Set Sorted set 在具体描述这几种数据类型之前,我们先通过一张图了解下Redi ...

  7. Python操作redis学习系列之(集合)set,redis set详解 (六)

    # -*- coding: utf-8 -*- import redis r = redis.Redis(host=") 1. Sadd 命令将一个或多个成员元素加入到集合中,已经存在于集合 ...

  8. 5种Redis数据结构详解

    本文主要和大家分享 5种Redis数据结构详解,希望文中的案例和代码,能帮助到大家. 转载链接:https://www.php.cn/php-weizijiaocheng-388126.html 2. ...

  9. redis配置详解

    ##redis配置详解 # Redis configuration file example. # # Note that in order to read the configuration fil ...

随机推荐

  1. 下载并搭建maven环境

    1.下载maven 1.在官网下载maven  http://maven.apache.org/download.cgi 2.将下载maven解压.复制路径. 2.搭建maven环境 1.新建M2_H ...

  2. Ubuntu18.04 内核升级

    查看当前版本  在终端输入以下命令并回车 uname -sr  可以发现当前内核为 Linux 4.15.0-88-generic 查看目前最新的稳定内核  访问 The Linux Kernel A ...

  3. 在pyqt5中展示pyecharts生成的图像

    技术背景 虽然现在很少有人用python去做一些图形化的界面,但是不得不说我们在日常大部分的软件使用中都还是有可视化与交互这样的需求的.因此pyqt5作为一个主流的python的GUI框架地位是非常重 ...

  4. Parallel.For实现

    static class MyParallel { //4.0及以上用Task, Task的背后的实现也是使用了线程池线程 //static List<Task> tasks = new ...

  5. 5.12-jsp分页功能学习

    1.分页功能相关资料查询 分页须知知识点: (1)JDBC2.0的可滚动结果集. (2)HTTP GET请求. 一.可滚动结果集   Connection con  = DriverManager.g ...

  6. 【C++】类-多态

    类-多态 目录 类-多态 1. 基本概念 2. 运算符重载 2.1 重载为类的成员函数 2.2 重载为非成员函数 3. 虚函数 4. 抽象类 5. override与final 1. 基本概念 多态性 ...

  7. jquery-qrcode客户端二维码生成类库扩展--融入自定义Logo图片

    年后换了部门,现在主要的职责就是在网上卖精油,似乎这个就是传说中的网络营销. 跟着公司的MM们也了解不了少关于网络营销的知识,间接的了解到马云和刘强东都是些怎样龌龊的人,尽管之前也这样认为. 淘宝就不 ...

  8. 白话linux操作系统原理

    虽然计算机相关专业,操作系统和计算机组成原理是必修课.但是大学时和真正从事相关专业工作之后,对于知识的认知自然会发生变化.还很有可能,一辈子呆在学校的老师们只是照本宣科,自己的理解也不深.所以今天我站 ...

  9. 使用 fail2ban 保护 frp 服务

    背景 我们一般会使用 fail2ban 来保护暴露到公网的提供密码登录的 ssh 连接等. 但使用 frp 穿透后所有的从外网访问都会变成 127.0.0.1 进入的,原本能用 fail2ban 保护 ...

  10. C# 同步 异步 回调 状态机 async await Demo

    源码 https://gitee.com/s0611163/AsyncAwaitDemo 为什么会研究这个? 我们项目的客户端和服务端通信用的是WCF,我就想,能不能用异步的方式调用WCF服务呢?或者 ...