分享博文《学会这15点,让你分分钟拿下Redis数据库》https://mp.weixin.qq.com/s/LUgwbgtbsciuZgExrTk3xA
精品博文《关于Redis持久化》https://www.cnblogs.com/chenpingzhao/p/5158791.html
Redis 持久化有两种方式:
- Snapshotting(SAVE快照):RDB持久化方式是在一个特定的间隔保存某个时间点的一个数据快照。
- Append-only file(AOF):AOF(Append only file)持久化方式则会记录每一个服务器收到的写操作。数据回复时,这些记录的操作会逐条执行从而重建出原来的数据。写操作命令记录的格式跟Redis协议一致,以追加的方式进行保存。
==Redis的持久化是可以禁用的,两种方式的持久化是可以同时存在的,但是当Redis重启时,AOF文件会被优先用于重建数据。==
一、RDB
总结:
- save操作是在主线程中保存快照的,由于redis是用一个主线程来处理所有 client的请求,这种方式会阻塞所有client请求,所以不推荐使用。
- 另一点需要注意的是,每次快照持久化都是将内存数据完整写入到磁盘一次,并不是增量的只同步脏数据。如果数据量大的话,而且写操作比较多,必然会引起大量的磁盘io操作,可能会严重影响性能。
1.RDB自动备份
1 2 3 4 5 6 7 8 9
| # rdb自动备份配置 save 900 1, # 900 秒内如果超过 1 个 Key 被修改,则启动快照保存。 save 300 10, # 300 秒内如果超过 10 个 Key 被修改,则启动快照保存。 save 60 10000, # 60 秒内如果超过 10000 个 Key 被修改,则启动快照保存。
# 其他rdb备份配置 stop-writes-on-bgsave-error yes # yes 备份失败停止接收数据 rdbcompression yes # 开启压缩 rdbchecksum yes # 开启数据校验
|
1 2 3
| config get save # 查看配置 config set save "" # 关闭rdb config set save "300 100" # 设置
|
2.SAVE,BGSAVE手动备份
SAVE
命令会使用同步的方式生成RDB快照文件,这意味着在这个过程中会阻塞所有其他客户端的请求。因此不建议在生产环境使用这个命令,除非因为某种原因需要去阻止Redis使用子进程进行后台生成快照(例如调用fork(2)出错)。
BGSAVE
命令使用后台的方式保存RDB文件,调用此命令后,会立刻返回OK返回码。Redis会产生一个子进程进行处理并立刻恢复对客户端的服务。在客户端我们可以使用LASTSAVE
命令查看操作是否成功。
1 2
| 127.0.0.1:6379>SAVE # SAVE 命令表示使用主进程将当前数据库快照到 dump 文件 127.0.0.1:6379>BGSAVE # BGSAVE 命令表示,主进程会 fork 一个子进程来进行快照备份
|
1 2 3 4 5 6
| 127.0.0.1:6312> lastsave (integer) 1543395804 # 查看最后一次备份的时间戳
info rdb_last_save_time:1543395804 rdb_last_bgsave_status:ok # 备份状态
|
3.RDB数据恢复
- 如果需要恢复数据,只需将备份文件 (dump.rdb) 移动到 redis 备份目录并重新启动服务即可
- 两种方式的持久化是可以同时存在的,但是当Redis重启时,AOF文件会被优先用于重建数据。
二、AOF
总结
RDB快照并不是很可靠。如果服务器突然Crash了,那么最新的数据就会丢失。而AOF文件则提供了一种更为可靠的持久化方式。每当Redis接受到会修改数据集的命令时,就会把命令追加到AOF文件里,当你重启Redis时,AOF里的命令会被重新执行一次,重建数据。
原理
- redis调用fork ,现在有父子两个进程
- 子进程根据内存中的数据库快照,往临时文件中写入重建数据库状态的命令
- 父进程继续处理client请求,除了把写命令写入到原来的aof文件中。同时把收到的写命令缓存起来。这样就能保证如果子进程重写失败的话并不会出问题
- 当子进程把快照内容写入已命令方式写到临时文件中后,子进程发信号通知父进程。然后父进程把缓存的写命令也写入到临时文件
- 现在父进程可以使用临时文件替换老的aof文件,并重命名,后面收到的写命令也开始往新的aof文件中追加
优点
- 比RDB可靠。你可以制定不同的fsync策略:不进行fsync、每秒fsync一次和每次查询进行fsync。默认是每秒fsync一次。这意味着你最多丢失一秒钟的数据。
- AOF日志文件是一个纯追加的文件。就算服务器突然Crash,也不会出现日志的定位或者损坏问题。甚至如果因为某些原因(例如磁盘满了)命令只写了一半到日志文件里,我们也可以用redis-check-aof这个工具很简单的进行修复。
- 当AOF文件太大时,Redis会自动在后台进行重写。重写很安全,因为重写是在一个新的文件上进行,同时Redis会继续往旧的文件追加数据。新文件上会写入能重建当前数据集的最小操作命令的集合。当新文件重写完,Redis会把新旧文件进行切换,然后开始把数据写到新文件上。
- AOF把操作命令以简单易懂的格式一条接一条的保存在文件里,很容易导出来用于恢复数据。例如我们不小心用FLUSHALL命令把所有数据刷掉了,只要文件没有被重写,我们可以把服务停掉,把最后那条命令删掉,然后重启服务,这样就能把被刷掉的数据恢复回来。
缺点
- 在相同的数据集下,AOF文件的大小一般会比RDB文件大。
- 在某些fsync策略下,AOF的速度会比RDB慢。通常fsync设置为每秒一次就能获得比较高的性能,而在禁止fsync的情况下速度可以达到RDB的水平。
- 在过去曾经发现一些很罕见的BUG导致使用AOF重建的数据跟原数据不一致的问题。
1.AOF 自动备份
1 2 3 4 5 6 7
| appendonly yes appendfsync everysec # 指定更新日志条件,共有3个可选值: # no:表示等操作系统进行数据缓存同步到磁盘(快) # always:表示每次更新操作后手动调用fsync()将数据写到磁盘(慢,安全) # everysec:表示每秒同步一次(折衷,默认值) appendfilename appendonly-6379.aof # aof持久化备份文件,指定更新日志文件名,默认为appendonly.aof
|
2.AOF bgrewriteaof
1 2 3
| no-appendfsync-on-rewrite yes # 设置为yes表示rewrite期间对新写操作不fsync,暂时存在内存中,等rewrite完成后再写入,默认为no,建议yes auto-aof-rewrite-percentage 100 # 如果当前的aof文件大小比起上一次rewrite的aof文件大小超过指定的百分比,则会触发重写。 auto-aof-rewrite-min-size 64mb # 同时需要设置一个文件大小最小值,只有大于这个值文件才会重写,以防文件很小,但是已经达到百分比的情况。
|
1
| auto-aof-rewrite-percentage 0
|
三、总结
1.AOF 与 RDB 加载顺序
服务读取文件的优先顺序不同,会按照以下优先级进行启动:
- 如果只配置 AOF,重启时加载 AOF 文件恢复数据
- 如果同时 配置了 RBD 和 AOF,启动是只加载 AOF 文件恢复数据
- 如果只配置 RBD,启动时将加载 dump 文件恢复数据
注意:只要配置了 AOF,但是没有 AOF 文件,这个时候启动的数据库会是空的。
2.注意:save会占用2倍的内存
- 上面说了RDB快照的持久化,在进行快照的时候
save
,fork
出来进行dump
操作的子进程会占用与父进程一样的内存,真正的copy-on-write
,对性能的影响和内存的耗用都是比较大的。
- 比如机器8G内存,Redis已经使用了6G内存,这时
save
的话会再生成6G,变成12G,大于系统的8G。这时候会发生交换;要是虚拟内存不够则会崩溃,导致数据丢失。所以在用redis的时候一定对系统内存做好容量规划。
3.主备架构
通常的设计思路是利用Replication机制来弥补aof、snapshot性能上的不足,达到了数据可持久化。
- 即Master上Snapshot和AOF都不做,来保证Master的读写性能
- 而Slave上则同时开启Snapshot和AOF来进行持久化,保证数据的安全性。