持久化定义:
将数据从掉电易失的内存,放到永久存储的设备上
redis为什么需要持久化
因为redis服务中所有数据都在内存中,所以必须持久化处理
redis的两种持久化方式
RDB(默认开启)和 AOF
优先级关系:
默认是开启了rdb,aof是关闭的。若开启了aof,一般aof更新频率高,所以优先aof还原数据库。只有aof关闭时,才会使用rdb还原数据库。aof开启时,没有appendonly.aof文件或为空,redis重启还是执行aof,不会还原rdb,所以结果上没有持久化的效果
RDB持久化方式
redis的默认持久化方式,不管怎么样都是开启状态
RDB方式是通过快照完成的,当符合一定条件时Redis会自动将内存中的所有数据进行快照,并且存储到硬盘上。就像拍照一样,将这一瞬间的所有东西都保存下来。
特点:
1、保存真实的数据
2、将服务器包含的所有数据库数据以二进制文件的形式保存到硬盘里面
3、默认文件名 :/var/lib/redis/dump.rdb
创建rdb文件的两种方式:
方式一:服务器执行客户端发送的SAVE或者BGSAVE命令(一般不用,尤其是save命令)
127.0.0.1:6379> SAVE
OK
# 特点
1、执行SAVE命令过程中,redis服务器将被阻塞,无法处理客户端发送的命令请求,在SAVE命令执行完毕后,服务器才会重新开始处理客户端发送的命令请求
2、如果RDB文件已经存在,那么服务器将自动使用新的RDB文件代替旧的RDB文件
# 工作中定时持久化保存一个文件
127.0.0.1:6379> BGSAVE
Background saving started
# 执行过程如下
1、客户端 发送 BGSAVE 给服务器
2、服务器马上返回 Background saving started 给客户端
3、服务器 fork() 子进程做这件事情
4、服务器继续提供服务
5、子进程创建完RDB文件后再告知Redis服务器
# 配置文件相关操作
/etc/redis/redis.conf
263行: dir /var/lib/redis # 表示rdb文件存放路径
253行: dbfilename dump.rdb # 文件名
# 两个命令比较
SAVE比BGSAVE快,因为需要创建子进程,消耗额外的内存
# 补充:可以通过查看日志文件来查看redis都做了哪些操作
# 日志文件:配置文件中搜索 logfile
logfile /var/log/redis/redis-server.log
方式二:设置配置文件条件满足时自动保存(使用最多)
# 命令行示例
redis>save 300 10
表示如果距离上一次创建RDB文件已经过去了300秒,并且服务器的所有数据库总共已经发生了不少于10次修改,那么自动执行BGSAVE命令
redis>save 60 10000
表示如果距离上一次创建rdb文件已经过去60秒,并且服务器所有数据库总共已经发生了不少于10000次修改,那么执行bgsave命令
# redis配置文件默认
218行: save 900 1
219行: save 300 10
220行: save 60 10000
这是配置文件默认的策略,他们之间的关系是或,每隔900秒,在这期间变化了至少一个键值,做快照。或者每三百秒,变化了十个键值做快照。或者每六十秒,变化了至少一万个键值,做快照。
1、只要三个条件中的任意一个被满足时,服务器就会自动执行BGSAVE
2、每次创建RDB文件之后,服务器为实现自动持久化而设置的时间计数器和次数计数器就会被清零,并重新开始计数,所以多个保存条件的效果不会叠加
如何关闭rdb持久化
有些情况下,我们只想利用Redis的缓存功能,并不像使用 Redis 的持久化功能,那么这时候我们最好停掉 RDB 持久化。可以通过上面讲的在配置文件 redis.conf 中,可以注释掉所有的 save 行来停用保存功能或者直接一个空字符串来实现停用:save “”
也可以通过命令:redis-cli config set save " "
RDB优缺点
RDB的优点是:
1.RDB是一个非常紧凑(compact)的文件,它保存了redis 在某个时间点上的数据集。这种文件非常适合用于进行备份和灾难恢复(将持久化到硬盘中的文件恢复即可)。
2.生成RDB文件的时候,redis主进程会fork()一个子进程来处理所有保存工作,主进程不需要进行任何磁盘IO操作。
3.RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快。
RDB缺点:
1.如果你需要尽量避免在服务器故障时丢失数据,那么RDB 不适合你。 虽然Redis 允许你设置不同的保存点(save point)来控制保存 RDB 文件的频率, 但是, 因为RDB 文件需要保存整个数据集的状态, 所以它并不是一个轻松的操作。 因此你可能会至少 5 分钟才保存一次 RDB 文件。 在这种情况下, 一旦发生故障停机, 你就可能会丢失好几分钟的数据(最后一次的数据)。
2.每次保存 RDB 的时候,Redis 都要 fork() 出一个子进程,并由子进程来进行实际的持久化工作。 在数据集比较庞大时, fork() 可能会非常耗时,造成服务器在某某毫秒内停止处理客户端; 如果数据集非常巨大,并且 CPU 时间非常紧张的话,那么这种停止时间甚至可能会长达整整一秒。 虽然 AOF 重写也需要进行 fork() ,但无论 AOF 重写的执行间隔有多长,数据的耐久性都不会有任何损失。
AOF持久化方式
默认未开启,可通过修改文件将appendonly yes # 把 no 改为 yes,然后重启redis服务开启
aof特点
1、存储的是命令,而不是真实数据:
你所执行的每一条指令,都会被记录到appendonly.aof文件中。但事实上,并不会立即将命令写入到硬盘文件中,而是写入到硬盘缓存,在接下来的策略中,配置多久来从硬盘缓存写入到硬盘文件。所以在一定程度一定条件下,还是会有数据丢失,不过你可以大大减少数据损失。
配置策略默认是appendfsync everysec ,每秒持久化一次,最多丢失一秒的数据,一般选择该策略就行
#appendfsync always 是每次操作都会立即写入aof文件中,效率最低
#appendfsync no 不主动进行同步操作,是默认30s一次
aof相关问题解答
- aof文件会每一条命令都写一次,产生很多的冗余命令,导致aof文件非常大吗?
不会,为了让AOF文件的大小控制在合理范围,避免胡乱增长,redis提供了AOF重写功能,通过这个功能,服务器可以产生一个新的AOF文件
– 新的AOF文件记录的数据库数据和原由的AOF文件记录的数据库数据完全一样
– 新的AOF文件会使用尽可能少的命令来记录数据库数据,因此新的AOF文件的提及通常会小很多
– AOF重写期间,服务器不会被阻塞,可以正常处理客户端发送的命令请求
aof重写策略配置:
一般采用默认配置策略,无需修改:
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
解释:只有当AOF文件的增量大于100%时才进行重写,也就是大一倍的时候才触发
# 第一次重写新增:64M
# 第二次重写新增:128M
# 第三次重写新增:256M(新增128M)
AOF的优点:
(1)AOF可以更好的保护数据不丢失,一般AOF会以每隔1秒,通过后台的一个线程去执行一次fsync操作,如果redis进程挂掉,最多丢失1秒的数据。
(2)AOF以appen-only的模式写入,是一种顺序写的方式,所以没有任何磁盘寻址的开销,写入性能非常高。
(3)AOF日志文件的命令通过非常可读的方式进行记录,这个非常适合做灾难性的误删除紧急恢复,如果某人不小心用flushall命令清空了所有数据,只要这个时候还没有执行rewrite,那么就可以将日志文件中的flushall删除,进行恢复。
AOF的缺点
(1)对于同一份文件AOF文件比RDB数据快照要大。
(2)AOF开启后支持写的QPS会比RDB支持的写的QPS低,因为AOF一般会配置成每秒fsync操作,每秒的fsync操作还是很高的
(3)数据恢复比较慢,不适合做冷备。
总结
rdb持久化是通过快照直接保存真实数据
aof持久化是通过追加写的方式保存命令,再执行命令保存数据
redis默认开启rdb持久化,但生成rdb文件较大时耗时较长,可能丢失数据和引起服务暂停的问题。所以一般同时也开启aof持久化方式,rdb文件通常用于备份和灾难恢复。aof持久化用于服务重启等恢复数据,配置写入策略,同时有aof重写机制。
RDB和AOF到底如何选择
(1)不要仅仅使用RDB,这样会丢失很多数据。
(2)也不要仅仅使用AOF,因为这一会有两个问题,第一通过AOF做冷备没有RDB做冷备恢复的速度快;第二RDB每次简单粗暴生成数据快照,更加健壮。
(3)综合AOF和RDB两种持久化方式,用AOF来保证数据不丢失,作为恢复数据的第一选择;用RDB来做不同程度的冷备,在AOF文件都丢失或损坏不可用的时候,可以使用RDB进行快速的数据恢复。
相关参考资料:
你管这破玩意叫 RDB,Linux 写时复制机制原理