认识Redis持久化
一:为什么需要持久化
因为Redis是一个完全使用内存来存储数据的数据库,如果机器突然断电、服务器重启或进程挂掉了等等原因,那么存储在Redis中的数据就会丢失,从而引起业务的损失。为了保证存储在内存中的数据安全,Redis引入了持久化这个功能。
二:Redis持久化分类
在Redis中,分别为我们提供了 RDB 和 AOF 两种持久化模式。在4.0及以后版本中,提供了一种混合持久化的功能,就是RDB和AOF结合的持久化模式。
1、分类
1.1、RDB
RDB持久化方式是通过快照完成的。RDB程序将当前内存中的数据快照保存到磁盘中,在Redis重启时,RDB程序可以通过载入RDB文件来还原数据库的状态。
1.2、AOF
AOF(append only file),是以独立日志的方式记录每次的写命令,重启时在执行文件中的命令来达到恢复数据的目的。
1.3、混合模式
混合模式就是同时结合了RDB持久化和AOF持久化混合写入AOF文件。这样就可以结合2者的优点了,快速的加载持久化文件,同时避免数据丢失过多。
2、三者的优缺点
优点 | 缺点 | |
---|---|---|
RDB | 1:RDB的持久化文件是一个二进制文件,而且是经过压缩的,代表Redis在某个时间点的数据快照。非常适合备份,全量复制等场景。可以执行bgsave备份,并把RDB文件拷贝到远程机器中,用于灾难恢复 2:因为数据文件小,所以恢复比AOF快很多 |
1:RDB不能及时的备份,不能实时持久化。所以如果Redis意外down掉,就会丢失最后一次快照后的所有数据
2:RDB是特定的二进制文件格式,Redis的版本兼容很差,也就是说老的RDB无法兼容新的Redis服务器 |
AOF | 1:AOF持久化可以进行秒级备份, 可以尽量减少数据丢失的问题,对比RDB不能实时备份 | 1:因为AOF是以日志形式记录每次写操作,所以它的文件比较大,备份恢复时间相比较RDB来说时间要长 |
混合 | 1:混合模式结合了RDB和AOF的优缺点,快速加载备份文件同时避免过多的数据丢失 | 当然缺点也是有的:就是AOF里面的RDB部分是压缩格式,不是AOF格式,可读性差,当然这个我们一般情况下可以忽略 |
三:RDB的使用
1、RDB持久化配置
################################ SNAPSHOTTING ################################
#
# Save the DB on disk:
#
# save <seconds> <changes>
# 配置触发RDB快照的规则
#
# Will save the DB if both the given number of seconds and the given
# number of write operations against the DB occurred.
#
# In the example below the behaviour will be to save:
# after 900 sec (15 min) if at least 1 key changed //900秒内至少有1个key被改变则做一次快照
# after 300 sec (5 min) if at least 10 keys changed //300秒内至少有300个key被改变则做一次快照
# after 60 sec if at least 10000 keys changed //60秒内至少有10000个key被改变则做一次快照
#
# save 900 1
# save 300 10
# save 60 10000
#
# Note: you can disable saving completely by commenting out all "save" lines.
#
# It is also possible to remove all the previously configured save
# points by adding a save directive with a single empty string argument
# like in the following example:
#
# save "" //关闭触发RDB快照的规则
# The filename where to dump the DB
dbfilename dump.rdb //RDB持久化数据库文件名,默认dump.rdb
stop-writes-on-bgsave-error yes //yes:代表当使用bgsave命令持久化出错时候停止写RDB快照文件,no:表明忽略错误继续写文件。
rdbcompression yes //是否开启RDB文件压缩,yes默认开启压缩,no不开启
rdbchecksum yes //在写入文件和读取文件时是否开启rdb文件检查,检查是否有无损坏,如果在启动是检查发现损坏,则停止启动
dir ./ //数据文件存放目录,rdb快照文件和aof文件都会存放至该目录,请确保有写权限
2、什么时候触发RDB快照
RDB生成快照可以自动触发,也可以用命令手动触发
- 客户端执行命令 save 和 bgsave 会生成快照;
- 根据配置文件 save m n 规则进行自动快照;
- 主从复制时,从库全量复制同步主库数据,此时主库会执行bgsave命令进行快照;
- 客户端执行数据库清空命令FLUSHALL时候,触发快照;
- 客户端执行shutdown关闭redis时,触发快照;
save命令
在客户端执行save命令,这个命令强制Redis执行快照,并且会阻塞Redis,此时Reids不会响应任何请求,知道RDB快照执行完毕,所以一般要慎用
bgsave命令
bgsave就是后台执行的命令,执行这个命令时,Redis会fork出一个子进程来执行快照的生成,(注意:fork出子进程这段时间Reids是阻塞的,不会响应客户端的请求),当子进程创建完成后Redis响应客户端请求。
Redis的自动快照也是用这个命令完成的
配置文件save命令
save m n: 指定在m秒内,redis中有n个键发送改变,则自动触发bgsave命令。 就是上面的 RDB 持久化配置redis.conf 里面的
FLUSHALL触发
flushall命令用于清空数据库,请慎用,当我们使用了则表明我们需要对数据进行清空,那redis当然需要对快照文件也进行清空,所以会触发bgsave。
shutdown触发
shutdown命令触发就不用说了,redis在关闭前处于安全角度将所有数据全部保存下来,以便下次启动会恢复
主从复制触发
在redis主从复制中,从节点执行全量复制操作,主节点会执行bgsave命令,并将rdb文件发送给从节点
3、RDB格式规范
----------------------------# RDB is a binary format. There are no new lines or spaces in the file.
52 45 44 49 53 # Magic String "REDIS"
00 00 00 03 # RDB Version Number in big endian. In this case, version = 0003 = 3
----------------------------
FE 00 # FE = code that indicates database selector. db number = 00
----------------------------# Key-Value pair starts
FD $unsigned int # FD indicates "expiry time in seconds". After that, expiry time is read as a 4 byte unsigned int
$value-type # 1 byte flag indicating the type of value - set, map, sorted set etc.
$string-encoded-key # The key, encoded as a redis string
$encoded-value # The value. Encoding depends on $value-type
----------------------------
FC $unsigned long # FC indicates "expiry time in ms". After that, expiry time is read as a 8 byte unsigned long
$value-type # 1 byte flag indicating the type of value - set, map, sorted set etc.
$string-encoded-key # The key, encoded as a redis string
$encoded-value # The value. Encoding depends on $value-type
----------------------------
$value-type # This key value pair doesn't have an expiry. $value_type guaranteed != to FD, FC, FE and FF
$string-encoded-key
$encoded-value
----------------------------
FE $length-encoding # Previous db ends, next db starts. Database number read using length encoding.
----------------------------
... # Key value pairs for this database, additonal database
FF ## End of RDB file indicator
8 byte checksum ## CRC 64 checksum of the entire file.
https://ningyu1.github.io/site/post/34-redis-rdb/ 这里是一个中文版RDB格式规范的翻译
4、数据恢复
当Redis关闭后,在启动时候,并且AOF持久化也没有开启,那么将使用RDB快照文件恢复数据。
模拟操作:停掉Redis,然后重新启动 Redis, 看看Redis的启动日志
四:AOF的使用
1、AOF配置
appendonly no # yes:开启AOF, no: 关闭AOF
appendfilename "appendonly.aof" # 指定AOF的文件名
appendfsync everysec
#everysec:数据将使用调用操作系统write写入文件,并使用fsync每秒一次从内核刷新到磁盘。
# 这是折中的方案,兼顾性能和数据安全,所以redis默认推荐使用该配置。
#always:表示每次有写操作都调用fsync方法强制内核将数据写入到aof文件。
# 这种情况下由于每次写命令都写到了文件中, 虽然数据比较安全,但是因为每次写操作都会同步到AOF文件中,
# 所以在性能上会有影响,同时由于频繁的IO操作,硬盘的使用寿命会降低
#no :不使用fsync方法同步,而是交给操作系统write函数去执行同步操作,在linux操作系统中大约每30秒刷一次缓冲。
# 这种情况下,缓冲区数据同步不可控,并且在大量的写操作下,aof_buf缓冲区会堆积会越来越严重,
# 一旦redis出现故障,数据丢失
auto-aof-rewrite-percentage 100
#当前AOF文件大小和最后一次重写后的大小之间的比率等于或者等于指定的增长百分比,
#如100代表当前AOF文件是上次重写的两倍时候才重写。
auto-aof-rewrite-min-size 64mb
#AOF文件最小重写大小,只有当AOF文件大小大于该值时候才可能重写,4.0默认配置64mb。
aof-load-truncated yes
#当redis突然运行崩溃时,会出现aof文件被截断的情况,Redis可以在发生这种情况时退出并加载错误,以下选项控制此行为。
#如果aof-load-truncated设置为yes,则加载截断的AOF文件,Redis服务器启动发出日志以通知用户该事件。
#如果该选项设置为no,则服务将中止并显示错误并停止启动。当该选项设置为no时,用户需要在重启之前使用“redis-check-aof”实用程序修复AOF文件在进行启动。
2、AOF在服务端的执行
当AOF的持久化功能打开时,服务器在执行完一个命令后,会以协议格式将被执行的命令追加到服务器状态的 aof_buf 缓冲区的末尾:
//redis.h
struct redisServer {
//...
sds aof_buf; /* AOF buffer, written before entering the event loop */
//...
}
比如,你在客户端执行下面的命令:
redis > SET KEY VALUE
OK
那么服务器在执行这个 SET 命令之后, 会将以下redis协议内容追加到 aof_buf
缓冲区的末尾:
*3\r\n$3\r\nSET\r\n$3\r\nKEY\r\n$5\r\nVALUE\r\n
redis协议解释
首先Redis是以行来划分,每行以\r\n行结束。每一行都有一个消息头,消息头共分为5种分别如下:
(+) 表示一个正确的状态信息,具体信息是当前行+后面的字符。
(-) 表示一个错误信息,具体信息是当前行-后面的字符。
(*) 表示消息体总共有多少行,不包括当前行,*后面是具体的行数。
($) 表示下一行数据长度,不包括换行符长度\r\n,$后面则是对应的长度的数据。
(:) 表示返回一个数值,:后面是相应的数字节符。
3、AOF持久化的过程
3.1、追加写入
就是上面介绍的在服务端的执行,将每一条命令以redis的协议写入到aof_buf缓冲区,暂存在这里,然后根据策略一次性写入到硬盘
3.2、同步写入硬盘
我们在上面AOF配置里面有一个配置选项:appendfsync ,里面有no,always,everysec 3个选项
当写命令写入到aof_buf 缓冲区后,Redis会根据这3种策略,同步缓冲区数据到硬盘,详细说明见 AOF配置
3.3、文件重写bgrewriteaof
为什么要重写AOF文件?
因为在Redis的运行过程中,AOF的文件越来越大,导致恢复的时候所需要的时间越来越长,所以要对AOF文件进行优化。
重写策略:
- 重复或无效的命令不写入文件
- 过期的数据不再写入文件
- 多条命令合并写入(当多个命令能合并一条命令时候会对其优化合并作为一个命令写入,例如"RPUSH list1 a RPUSH list1 b" 合并为"RPUSH list1 a b" )
什么时候重写呢?
每次当serverCron(服务器周期性操作函数)函数执行时,它会检查以下条件是否全部满足,如果全部满足的话,就触发自动的AOF重写操作:
- 没有BGSAVE命令(RDB持久化)/AOF持久化在执行;
- 没有BGREWRITEAOF在进行;
- 当前AOF文件大小要大于server.aof_rewrite_min_size的值;
- 当前AOF文件大小和最后一次重写后的大小之间的比率等于或者大于指定的增长百分比(auto-aof-rewrite-percentage参数)
4、AOF触发条件
4.1、手动触发命令
bgrewriteaof
127.0.0.1:6379> bgrewriteaof
Background append only file rewriting started
4.2、自动触发
配置文件里的2个选项
- auto-aof-rewrite-min-size: AOF文件最小重写大小,只有当AOF文件大小大于该值时候才可能重写,4.0默认配置64mb。
- auto-aof-rewrite-percentage:当前AOF文件大小和最后一次重写后的大小之间的比率等于或者等于指定的增长百分比,如100代表当前AOF文件是上次重写的两倍时候才重写。
5、数据恢复
Redis的数据恢复,它优先使用AOF来恢复,我们可以停掉Redis来模拟Redis故障,然后重启Redis进行数据恢复。
查看Reids的日志,看看是不是恢复成功了
五:混合持久化
这个是Redis4.0 推出的一个新功能,包含了RDB和AOF 2者的优点
- RDB 持久化能够快速地储存和恢复数据, 但是在服务器停机时却会丢失大量数据;
- AOF 持久化能够有效地提高数据的安全性, 但是在储存和恢复数据方面却要耗费大量的时间。
这种持久化能够通过 AOF 重写操作创建出一个同时包含 RDB 数据和 AOF 数据的 AOF 文件, 其中 RDB 数据位于 AOF 文件的开头, 它们储存了服务器开始执行重写操作时的数据库状态; 至于那些在重写操作执行之后执行的 Redis 命令, 则会继续以 AOF 格式追加到 AOF 文件的末尾, 也即是 RDB 数据之后。
1、配置
# 我们可以在appendonly yes命令 下面加上以下的配置,然后重启Reids
aof-use-rdb-preamble yes
2、混合持久化过程
混合持久化同样也是通过bgrewriteaof完成的,不同的是当开启混合持久化时,fork出的子进程先将共享的内存副本全量的以RDB方式写入aof文件,然后在将重写缓冲区的增量命令以AOF方式写入到文件,写入完成后通知主进程更新统计信息,并将新的含有RDB格式和AOF格式的AOF文件替换旧的的AOF文件。
简单的说:新的AOF文件前半段是RDB格式的全量数据后半段是AOF格式的增量数据,
3、实践操作
首先开启混合持久化的配置, 然后在客户端使用bgrewriteaof命令
127.0.0.1:6379> bgrewriteaof
Background append only file rewriting started
然后可以看看日志,发生了什么
六:其他一些命令
查看Redis状态信息
info stats
rdb 文件检查
redis-check-rdb /etc/redis/dump.rdb
aof 文件检查
redis-check-aof /etc/redis/appendonly.aof
查看持久化信息
info Persistence
七:参考
https://github.com/antirez/redis
http://blog.huangz.me/2017/redis-rdb-aof-mixed-persistence.html 混合存储
https://redis.io/topics/persistence 持久化
https://github.com/sripathikrishnan/redis-rdb-tools/wiki/Redis-RDB-Dump-File-Format RDB格式规范
https://blog.csdn.net/weixin_39040059/article/details/79120416
https://blog.csdn.net/weixin_39040059/article/details/79120444
认识Redis持久化的更多相关文章
- redis持久化RDB和AOF
Redis 持久化: 提供了多种不同级别的持久化方式:一种是RDB,另一种是AOF. RDB 持久化可以在指定的时间间隔内生成数据集的时间点快照(point-in-time snapshot). AO ...
- Redis持久化
Redis持久化 快照(默认) 将内存中的数据以快照的方式写入到二进制文件中,默认文件名是dump.rdb. 配置自动化做快照持久化(如redis在n秒内如果超过m个key被修改就自动做快照) sav ...
- redis——持久化篇
众所周知,redis是内存数据库,它把数据存储在内存中,这样在加快读取速度的同时也对数据安全性产生了新的问题,即当redis所在服务器发生宕机后,redis数据库里的所有数据将会全部丢失. 为了解决这 ...
- redis持久化机制
redis持久化 redis的数据存在内存中,所以存取性能好.但是存在内存中的数据存在一个问题,一旦机器重启,内存数据消失.为了解决这个问题,redis支持持久化.持久化就是为了解决内存数据丢失时恢复 ...
- Redis-cluster集群【第二篇】:redis持久化
Redis持久化原理: Redis支持两种持久化:RDB和AOF模式 一.名词解释: RDB:持久化可以在指定的时间间隔内生成数据集的时间点快照(point-in-time snapshot).AOF ...
- Redis持久化实践及灾难恢复模拟
参考资料: Redis Persistence http://redis.io/topics/persistence Google Groups https://groups.google.com/f ...
- Redis持久化-数据丢失及解决(转载)
本文转载自 Redis持久化-数据丢失及解决 感谢原作者 Redis的数据回写机制 Redis的数据回写机制分同步和异步两种, 同步回写即SAVE命令,主进程直接向磁盘回写数据.在数据 ...
- Redis持久化-数据丢失及解决
Redis的数据回写机制 Redis的数据回写机制分同步和异步两种, 同步回写即SAVE命令,主进程直接向磁盘回写数据.在数据大的情况下会导致系统假死很长时间,所以一般不是推荐的. 异步回写即BGSA ...
- 关于Redis持久化
Redis有两种持久化的方式:快照(RDB文件)和追加式文件(AOF文件) RDB持久化方式是在一个特定的间隔保存某个时间点的一个数据快照. AOF(Append only file)持久化方式则会记 ...
- 解密Redis持久化
原文 http://blog.nosqlfan.com/html/3813.html 本文内容来源于Redis作者博文,Redis作者说,他看到的所有针对Redis的讨论中,对Redis持久化的误解是 ...
随机推荐
- JAVA bean为何要实现序列化
简而言之:序列化,就是为了在不同时间或不同平台的JVM之间共享实例对象.即序列化出于两个原因:①.用于持久化到磁盘上:②.用于作为数据流在网络上传输. 所谓的Serializable,就是java提供 ...
- 谷歌插件学习笔记:把iframe干掉……
好久不写博客了,感觉自己变得越来越懒了,是没有时间吗?不是,是自己变得越来越懒了,好多东西不愿意去总结了,可能也是学的不精总结不出来什么玩意儿.不过,一切都是借口.还是坚持学习,坚持写博客吧,虽然写的 ...
- es聚合学习笔记
聚合可以做什么? count avg filter and count 每月新增 top 是否存在不正常或不符合规则的数据 关键概念 Buckets group by 将数据按某种标准划分成不同集合 ...
- ssh远程连接centos7故障排除
导致故障的原因在两个方面 1.网络问题---物理链路就不通可以通过在客户端 telnet目标主机地址,例如:telnet 192.168.1.107 22 千万别忘了端口号!!!,如果通了还连不上则按 ...
- Mybatis Generator-自动化生成代码步骤
链接:https://blog.csdn.net/guo_xl/article/details/86004068 文档:http://mybatis.org/generator/configrefer ...
- ThreadPoolTaskExecutor使用详解(转)
当并发或者异步操作,都会用到ThreadPoolTaskExecutor.现在对线程池稍作理解. /*** *@Auth dzb *@Date 22:29 2018/8/29 *@Descriptio ...
- k8s知识2
kubernetes到底有多难?看下面的白话: service 网络通信原理service 由k8s外面的服务作为访问端 内部里面其实是pod————————————————————————————— ...
- [bx]和loop
1.关于[bx] 1)[bx]用来表示取寄存器bx中的值作为偏移地址: 段地址保存在段寄存器ds中: 例如:将 2000:1000 处的数据保存到寄存器ax mov ax,2000 mov ds,ax ...
- 获取网卡速率,cpu使用率
];//获取网卡名称 PerformanceCounter NetworkR = new PerformanceCounter("Network Interface", " ...
- 【CUDA 基础】2.3 组织并行线程
title: [CUDA 基础]2.3 组织并行线程 categories: CUDA Freshman tags: Thread Block Grid toc: true date: 2018-03 ...