Redis持久化--RDB+AOF(转)
1、Redis两种持久化方式
- RDB
- 执行机制:快照,直接将databases中的key-value的二进制形式存储在了rdb文件中
- 优点:性能较高(因为是快照,且执行频率比aof低,而且rdb文件中直接存储的是key-values的二进制形式,对于恢复数据也快)
- 缺点:在save配置条件之间若发生宕机,此间的数据会丢失
- AOF
- 执行机制:将对数据的每一条修改命令追加到aof文件
- 优点:数据不容易丢失
- 缺点:性能较低(每一条修改操作都要追加到aof文件,执行频率较RDB要高,而且aof文件中存储的是命令,对于恢复数据来讲需要逐行执行命令,所以恢复慢)
2、RDB
实际中使用的配置(在redis.conf)
#发生以下三种的任何一种都会将数据库的缓存内容写入到rdb文件中去(写入的方式是bgsave)
#若将下述的三条命令都注释掉,则禁止使用rdb
save 900 1 #900s后至少有一个key发生了变化
save 300 10 #300s后至少有10个key发生了变化
save 60 10000 #60s后至少有10000个key发生了变化 #当后台RDB进程导出快照(一部分的key-value)到rdb文件这个过程出错时(即最后一次的后台保存失败时),
#redis主进程是否还接受向数据库写数据
#该种方式会让用户知道在数据持久化到硬盘时出错了(相当于一种监控);
#如果安装了很好的redis持久化监控,可设置为"no"
stop-writes-on-bgsave-error yes #使用LZF压缩字符串,然后写到rdb文件中去
#如果希望RDB进程节省一点CPU时间,设置为no,但是可能最后的rdb文件会很大
rdbcompression yes #在redis重启后,从rdb文件向内存写数据之前,是否先检测该rdb文件是否损坏(根据rdb文件中的校验和check_sum)
rdbchecksum yes #设置rdb文件名
dbfilename dump.rdb #设置rdb文件的存储目录
dir ./
说明:
- 具体每一项配置的详细说明看注释
注意:
- 对于save命令而言,配置了该命令,后台是以bgsave来执行的
- bgsave:Redis主进程进行数据读写操作,RDB子进程进行数据的持久化操作,在进行持久化操作时,不阻塞主进程的读写操作
- 以上三条save命令只要发生任一条,bgsave命令都会发生,这就有两个问题,假设60s内有10000个key发生了改变(写入、删除、更新),那么是否会立即进行持久化呢?在这次持久化之后,假设又过了240s,而在此期间没有任何的key的改变操作,此时是否要发生一次持久化(因为满足300s发生了10个key的改变,这里是改变了10000个key)?
- 不会立即进行持久化:redis默认每隔100ms使用serverCron函数检查一次save配置的条件是否满足,满足则进行bgsave,这样的话,如果在100ms内,我已经满足了bgsave的条件,那么我真正执行bgsave的时候也要等到serverCron执行过来的时候
- 不会再发生持久化:redis有两个参数dirty(记录上一次bgsave之后的key的修改数,上边的在240s内例子就是0)和lastsave(上一次成功执行bgsave命令的时间),配置中的每一个save配置的修改数指的就是dirty,而每一个时间段就是以lastsave为起点计算的。
- 注释掉所有的save命令,RDB将不起作用
- rdbcompression yes:配置成这样是不是每一个字符串在存储到rdb文件中时,都要进行一次压缩操作?
- 不是:设置为yes之后,只有当字符串的长度大于等于21个字节时,才会进行压缩
- rdbchecksum yes:这个校验和存储在哪里?为什么通过比对校验和可以判断文件是否损坏?
- 校验和(check_sum)存储在RDB文件的最后八个字节中(详细的RDB文件结构,查看《Redis这基于实现》"第10章 RDB持久化"),简单的RDB文件结构如下:
- RDB文件开头的前五个字节"REDIS"是判断一个文件是不是RDB文件的标准(类似于class文件中的"魔数")
- 接下来的4个字节:RDB文件版本号(db_version)
- databases(注意是复数):这里存放各个库redisDb中存储的key-value信息(是整个数据持久化和恢复的核心)
- EOF(1个字节):RDB文件正文的结束
- check_sum(8个字节):检验和,该值是根据前边四部分值算出来的,在持久化的时候将该值算出来并写入rdb文件的末尾;在根据rdb文件恢复数据的时候,再根据rdb文件中的前边四部分值计算出一个校验和,然后与当前rdb文件中的check_sum(即后八个字节)的内容进行比对,如果一样,说明没损坏,如果不一样,说明前四部分有数据损坏(即该文件损坏)
- 校验和(check_sum)存储在RDB文件的最后八个字节中(详细的RDB文件结构,查看《Redis这基于实现》"第10章 RDB持久化"),简单的RDB文件结构如下:
- 在Redis服务器启动时,redis会自动检测是否有rdb文件(前提是没有aof的时候),如果有,则根据rdb文件恢复数据,此时在恢复数据完成之前,会阻塞客户端对redis的读写操作
3、AOF
实际中使用的配置(在redis.conf)
# 是否打开aof日志功能(appendonly yes)
appendonly no # aof文件的存放路径与文件名称
# appendfilename appendonly.aof #每一个命令,都立即同步到aof文件中去(很安全,但是速度慢,因为每一个命令都会进行一次磁盘操作)
# appendfsync always
#每秒将数据写一次到aof文件
appendfsync everysec
#将写入工作交给操作系统,由操作系统来判断缓冲区大小,统一写到aof文件(速度快,但是同步频率低,容易丢数据)
# appendfsync no # 在RDB持久化数据的时候,此时的aof操作是否停止,若为yes则停止
# 在停止的这段时间内,执行的命令会写入内存队列,等RDB持久化完成后,统一将这些命令写入aof文件
# 该参数的配置是考虑到RDB持久化执行的频率低,但是执行的时间长,而AOF执行的频率高,执行的时间短,
# 若同时执行两个子进程(RDB子进程、AOF子进程)效率会低(两个子进程都是磁盘读写)
# 但是若改为yes可能造成的后果是,由于RDB持久化执行时间长,在这段时间内有很多命令写入了内存队列,
# 最后导致队列放不下,这样AOF写入到AOF文件中的命令可能就少了很多
# 在恢复数据的时候,根据aof文件恢复就会丢很多数据
# 所以,选择no就好
no-appendfsync-on-rewrite no # AOF重写:把内存中的数据逆化成命令,然后将这些命令重新写入aof文件
# 重写的目的:假设在我们在内存中对同一个key进行了100次操作,最后该key的value是100,
# 那么在aof中就会存在100条命令日志,这样的话,有两个缺点:
# 1)AOF文件过大,占据硬盘空间 2)根据AOF文件恢复数据极慢(需要执行100条命令)
# 如果我们将内存中的该key逆化成"set key 100",然后写入aof文件,
# 那么aof文件的大小会大幅度减少,而且根据aof文件恢复数据很快(只需要执行1条命令)
# 注意:下边两个约束都要满足的条件下,才会发生aof重写;
# 假设没有第二个,那么在aof的前期,只要稍微添加一些数据,就发生aof重写
# 当aof的增长的百分比是原来的100%(即是原来大小的2倍,例如原来是100m,下一次重写是当aof文件是200m的时候),AOF重写
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb #AOF重写仅发生在当aof文件大于64m时
说明:
- 具体每一项配置的详细说明看注释
注意:
- 每一个客户端命令在执行时都会直接将命令写入AOF缓冲区
- appendfsync always:每一个命令进入缓冲区后,都会立即再从缓冲区追加到AOF文件中
- appendfsync everysec:每一秒后将缓冲区中的所有命令追加到AOF文件中
- appendfsync no:每一个命令进入缓冲区后,由操作系统来判断什么时候(主要是缓冲区快满的时候)将缓冲区中的所有命令追加到AOF文件中
- aof重写需要满足配置文件中的两个条件
- aof重写采用后台子进程执行
- aof的重写会进行大量的写入操作,如果用单线程来做这个事儿,就会长时间阻塞主进程(redis是单线程),这个时候客户端的读写就会失效
- 采用aof后台重写进程造成的问题:
- 如果在后台进程重写期间,有新的命令对数据库进行了读写,新的aof文件就与数据库的存储内容不同了。(注意:在后台进程重写期间,对数据库的读写操作还会进入aof缓冲区,还是会执行aof文件的命令写入,但需要注意的是,虽然这个期间所有的命令还是写入aof文件了,但是这个aof文件会被重写后的新的aof文件所替换,新的aof文件可没有这些命令,那么如果在下次重写发生之前发生宕机,采用aof恢复数据库的时候,那就丢失了很多命令了)
- 解决方案:设置一个aof重写缓冲区,仅仅用于在后台进程重写期间,将发生的数据库读写命令写入到重写缓冲区中(当然,此时的服务器进程除了将发生的数据库读写命令写入到重写缓冲区中,还会写入到aof缓冲区,来保证正常的aof操作),之后当重写子进程完成重写后,向服务器主进程发送一个信号,此时服务器主进程将aof重写缓冲区中的命令追加到新的aof文件中去,用新的aof文件替换掉旧的aof文件。
- 注意:
- 在后台进程重写期间,将发生的数据库读写命令写入到重写缓冲区中时,为什么还要将这些命令写入到aof缓冲区(因为这些命令会写入旧的aof文件)?
- 如果能百分之百保证在最后的主进程用新的aof文件替换了旧的aof文件(就是在这之前不宕机),那么写入到aof缓冲区没用(因为会被覆盖),但是如果在这之前宕机,那么我们的aof文件还是旧的aof文件,这时候命令写入到aof缓冲区就可以保证该aof文件尽可能多的保存命令,将来用于恢复数据库最多丢失的也就是1s的数据。(appendfsync everysec)
- 在"服务器主进程将aof重写缓冲区中的命令追加到新的aof文件中去"这段操作期间,如果有新的客户端读写命令,都将被阻塞(因为是主进程在做上述操作)。这也是整个aof重写过程中唯一被阻塞的部分。
- 在后台进程重写期间,将发生的数据库读写命令写入到重写缓冲区中时,为什么还要将这些命令写入到aof缓冲区(因为这些命令会写入旧的aof文件)?
总结:
- 如果既配置了RDB,又配置了AOF,则在进行数据持久化的时候,都会进行,但是在根据文件恢复数据的时候,以AOF文件为准,RDB文件作废
- 需要注意:数据的恢复是阻塞操作(此间所到来的任何客户端读写请求都失效)
- bgsave和bgrewriteaof(后台aof重写)这两个命令不可以同时发生
- 如果bgsave在执行,此间到来的bgrewriteaof在bgsave执行之后,再执行
- 如果bgrewriteaof在执行,此间到来的bgsave丢弃
- RDB和AOF可以同时配置,但是最后还原数据库的时候是以aof文件来还原的
Redis持久化--RDB+AOF(转)的更多相关文章
- Redis持久化rdb&aof
Redis持久化rdb&aof 前言 持久化:即把数据存储于断电后不会丢失的设备中,通常是硬盘 常见的持久化方式: 主从:通过从服务器保持持久化,如mongoDB的replication se ...
- 第十章 Redis持久化--RDB+AOF
注:本文主要参考自<Redis设计与实现> 1.Redis两种持久化方式 RDB 执行机制:快照,直接将databases中的key-value的二进制形式存储在了rdb文件中 优点:性能 ...
- [动图演示]Redis 持久化 RDB/AOF 详解与实践
Redis 是一个开源( BSD 许可)的,内存中的数据结构存储系统,它可以用作数据库.缓存和消息中间件.它支持的数据类型很丰富,如字符串.链表.集 合.以及散列等,并且还支持多种排序功能. 什么叫持 ...
- [动图演示]Redis 持久化 RDB/AOF 详解与实践【华为云技术分享】
Redis 是一个开源( BSD 许可)的,内存中的数据结构存储系统,它可以用作数据库.缓存和消息中间件.它支持的数据类型很丰富,如字符串.链表.集 合.以及散列等,并且还支持多种排序功能. 什么叫持 ...
- 春招必问的redis持久化(RDB AOF),你能答上来么?
春招面试模拟,如同雷同,纯属巧合!!! 面试的大体流程: 第一步:一般会有笔试题,也可能没有.有笔试题就要好好答了,因为会重视笔试结果,为了节约面试官时间,HR可能先会看,不合格直接让你走人了. 第二 ...
- redis++:Redis持久化 rdb & aof 工作原理及流程图 (三)
RDB的原理: 在Redis中RDB持久化的触发分为两种:自己手动触发与Redis定时触发. 针对RDB方式的持久化,手动触发可以使用: 1):save:会阻塞当前Redis服务器,直到持久化完成,线 ...
- redis持久化RDB与AOF
redis持久化 Redis是一种内存型数据库,一旦服务器进程退出,数据库的数据就会丢失,为了解决这个问题,Redis提供了两种持久化的方案,将内存中的数据保存到磁盘中,避免数据的丢失. RDB持久化 ...
- Linux 安装redis 基本配置 发布订阅,安全配置,持久化 rdb ,aof
redis redis相关配置1.yum 源码 rpm yum 快速,间接,高效,解决依赖关系,(自动安装到某个路径,不可控),通过yum安装的软件查询命令 rpm -ql nginx yum源 ...
- redis的持久化(RDB&AOF的区别)
RDB 是什么? 在指定的时间间隔内将内存中的数据集快照写入磁盘, 也就是行话讲的Snapshot快照,它恢复时是将快照文件直接读到内存里. Redis会单独创建(fork)一个子进程来进行持久化,会 ...
随机推荐
- jackson实体转json时 为NULL不参加序列化的汇总
首先加入依赖 <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson ...
- Springboot+Mybatis批量导入多条数据
在Mapper.xml最下面填写 <!-- 批量插入生成的兑换码 --> <insert id ="insertCodeBatch" parameterType= ...
- edram install
Edraw安装 1● 下载Edraw 2● 安装步骤 断网
- .NetCore发布到Centos docker
将.netcore mvc项目发布到centos7的docker中.环境 vmware14+Centos7+docker-ce 1.使用vs将.netcoremvc项目发布到本地,修改发布后的目录 名 ...
- POJ 1840 Eqs 解方程式, 水题 难度:0
题目 http://poj.org/problem?id=1840 题意 给 与数组a[5],其中-50<=a[i]<=50,0<=i<5,求有多少组不同的x[5],使得a[0 ...
- MATLAB 图片折腾4
重新安排矩阵的x,y,z , 在二维中就相当于把x,y 对换,在三维中相当于可以把三个坐标的位置互换. 比如A = A(:,:,1)=repmat(1,3,3);A(:,:,2)=repmat(2,3 ...
- Linux搭建Hadoop集群---Jdk配置
三台虚拟机:master slave1 slave2 192.168.77.99 master 192.168.77.88 slave1 192.168.77.77 slave2 1.修改主机名: ...
- Oauth2.0:Access Token 与 Refresh Token
access token 是客户端访问资源服务器的令牌.拥有这个令牌代表着得到用户的授权.然而,这个授权应该是临时的,有一定有效期.这是因为,access token 在使用的过程中可能会泄露.给 a ...
- java项目性能测试过程记录
一 准备环境和指标 1.主机三台(linux,这里显示的都是伪主机地址):最好用干净的机子,做性能测试的时候别装其他东西在上面跑. 100.22.0.98 部署自己的项目服务 100.22.0.9 ...
- Eclipse界面简介
下载安装完成后,Eclipse的界面如下: (6)为eclipse的perspective(视图方案)由于安装的是for Java development的eclipse,故视图界面默认 为使用Jav ...