Redis学习详解(一):Redis持久化机制之RDB

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

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

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部分的作用:标识该文件是一个RDB文件。
保存着”REDIS”五个字符。

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

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

databases部分包含零个或任意多个数据库,以及各个数据库的键值对。
若服务器的数据库状态为空,那么该部分也为空。否则存储各个数据库的信息。

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

SELECTDB长度为1字节,表示接下来读入的会是一个数据库号码。
db_number保存着一个数据库号码,根据号码不同,服务器使用SELECT命令进行数据库切换。
key_value_pairs部分保存数据库中所有键值对数据,包括如果有过期时间便带有过期时间。

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

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

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

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

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

如果是无压缩的字符串,存储在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不同。

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

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

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

RDB缺点:

Original: https://www.cnblogs.com/hyx-hasaki/p/15897868.html
Author: Huangzzzzz
Title: Redis学习详解(一):Redis持久化机制之RDB

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/579080/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • JS 常用语法

    工具 JS在线编辑器,可以临时验证一些想法,非常方便https://jsrun.net/new 常用方法 时间格式排序 var arr=["2022-5-11"…

    Java 2023年6月8日
    045
  • java 多线程

    *线程的状态:New、Runnable、Blocked、Waiting、Timed waiting、Terminated new Thread()——> New、 start…

    Java 2023年6月16日
    079
  • 原来我还有网络天赋

    问题 如下图,之前公司有10多台服务器,都设置成了静态IP,因为现在更换成了类似IP为192.168.1.X 的1网段,看着下面的服务器,修改IP简单,但想想服务器里面还有许多配置…

    Java 2023年6月8日
    067
  • mybatisPlus

    如果有lombok的话,@Date代表getSetToStringHashCodeEquals有参无参方法 基本的CURD 常用注解 Original: https://www.c…

    Java 2023年6月13日
    057
  • 【源码】按照自己的思路研究Spring AOP源码 ②

    问题的提出 哪一步导致了顺序的改变 AbstractAdvisorAutoProxyCreator.sortAdvisors()方法 总结 问题的提出 按照自己的思路研究Sprin…

    Java 2023年6月8日
    0148
  • canal 基于Mysql数据库增量日志解析

    canal 基于Mysql数据库增量日志解析 1.前言 最近太多事情 工作的事情,以及终身大事等等 耽误更新,由于最近做项目需要同步监听 未来电视 mysql的变更了解到公司会用c…

    Java 2023年6月9日
    0104
  • dom4j解析xml时报出文件提前结束

    在写javaweb小项目的时候,用dom4j解析xml报出如下错误: org.dom4j.DocumentException:Error ……. Neste…

    Java 2023年6月13日
    0108
  • Java线程池中线程的状态简介

    首先明确一下线程在JVM中的各个状态(JavaCore文件中) 1.死锁,Deadlock(重点关注) 2.执行中,Runnable(重点关注) 3.等待资源,Waiting on…

    Java 2023年6月15日
    062
  • 【每日一题】leetcode4寻找两个正序数组的中位数

    题目描述 给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。 算法的时间复杂度应该为 O(log (m+…

    Java 2023年6月9日
    0104
  • JVM-堆

    堆 JAVA技术交流群:737698533 堆核心概述 此内存区域的唯一目的就是存放对象实例 一个JVM实例只存在一个堆内存,堆也是Java内存管理的核心区域。 Java堆区在JV…

    Java 2023年6月6日
    067
  • npm 添加淘宝代理

    设置仓库npm config set registry https:# 查看代理结果npm config get registry# 解除网络代理npm config set pr…

    Java 2023年6月13日
    0110
  • mybatis-plus报错解决Invalid bound statement (not found)错误

    mybatis-plus报错解决Invalid bound statement (not found)错误 org.apache.ibatis.binding.BindingExc…

    Java 2023年5月30日
    095
  • Java String Pool–String s = new String(“a”) 到底创建了几个对象?

    本篇重点(tips): String Pool 是以Java 中 String 对象是不可变的这一特性为基础的 String Pool是Heap(堆)中的一块特殊空间(JDK 1….

    Java 2023年6月16日
    0100
  • ArrayList这篇就够了

    提起ArrayList,相信很多小伙伴都用过,而且还不少用。但在几年之前,我在一场面试中,面试官要求说出ArrayList的扩容机制。很显然,那个时候的我并没有关注这些,从而错过了…

    Java 2023年6月8日
    062
  • Class.getResource(“/”)之为什么需要”/”

    Class.getResource(“/”)之为什么需要”/” 结论 Class.getResource真正调用ClassLoade…

    Java 2023年6月7日
    063
  • “崩溃了?不可能,我全 Catch 住了” | Java 异常处理

    前言 今天我们来讨论一下,程序中的错误处理。 在任何一个稳定的程序中,都会有大量的代码在处理错误,有一些业务错误,我们可以通过主动检查判断来规避,可对于一些不能主动判断的错误,例如…

    Java 2023年5月29日
    092
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球