文章目录
一、简介
1、什么是数据的持久化
我们知道redis的数据是被存放在内存中的,这是redis的优点,同时也是redis的缺点。一方面,在内存存储数据会使得数据的读取非常的高效;另一方面,内存的特点是断电即失。
针对上述的为题,redis的数据还需要持久化的,保证当突然断电或者redis宕机后不至于是的所有的数据都丢失。redis有有一个快照机制,redis把数据快照存放在磁盘上的二进制文件中,文件名为dump.rdb。你可以配置redis的持久化策略,例如数据集中每N秒钟有超过M次更新,就将数据写入磁盘;或者你可以手工调用命令save或bgsave。
2、实现持久化的方式
在redis中实现持久化的方式有2种,一种是通过RDB(redis database)实现数据持久化;另一种是用过AOF(append only file)实现数据的持久化。
保存数据的方式也有两种,一种是save,另一种是bgsave。
save 保存是阻塞主进程,客户端无法连接redis,等save完成后,主进程才开始工作,客户端可以连接。
bgsave 是fork一个save的子进程,在执行save过程中,不影响主进程,客户端可以正常链接redis,等子进程fork执行save完成后,通知主进程,子进程关闭。很明显bgsave 方式比较适合线上的维护操作,两种方式的使用一定要了解清楚在谨慎选择。
redis Save 命令基本语法如下:
redis 127.0.0.1:6379> SAVE
OK
redis BGSave 命令基本语法如下:
redis 127.0.0.1:6379> BGSAVE
Background saving started
二、RDB实现数据持久化
RDB(Redis Database)因为在redis中的save方式是持久化数据使用的比较少,所以我们使用的是bgsave方式,bgsave的流程图如下:
我们可以看到,当我们使用bgsave的时候,父进程会创建一个子进行来实现生成RDB文件的工作。这样就不会堵塞主进程,从而使得用户体验更佳。
1、数据的持久化操作
在持久化之前不存在dump.rdb文件。
127.0.0.1:6379> flushdb # 清空数据
OK
127.0.0.1:6379> set k1 v1 # 设置k1
OK
127.0.0.1:6379> set k2 v2 # 设置k2
OK
127.0.0.1:6379> set k3 v3 # 设置k3
OK
127.0.0.1:6379> bgsave # 进行持久化
Background saving started
127.0.0.1:6379>
持久化之后存在dump.rdb文件。
当然,你也可以设置实现自动持久化,使用save创建持久化策略。
# Unless specified otherwise, by default Redis will save the DB:
# * After 3600 seconds (an hour) if at least 1 key changed
# * After 300 seconds (5 minutes) if at least 100 keys changed
# * After 60 seconds if at least 10000 keys changed
#
# You can set these explicitly by uncommenting the three following lines.
#
# save 3600 1
# save 300 100
# save 60 10000
查看持久化文件存放的位置。
127.0.0.1:6379> config get dir
1) "dir"
2) "/usr/local/bin"
至于redis中的数据恢复,只要在/usr/local/bin
中存在dump.rdb文件,那么当redis启动的时候就会恢复redis持久化的数据。
2、触发redis持久化的机制
- 执行gbsave命令后
- 执行flushall命令后
- 满足save的规则时
- 退出redis时
3、RDB方式持久化的优缺点
优点
-
RDB会生成多个数据文件,每个数据文件都代表了某一个时刻中redis的数据,这种多个数据文件的方式,非常适合做冷备,可以将这种完整的数据文件发送到一些远程的安全存储上去,比如说Amazon的S3云服务上去,在国内可以是阿里云的ODPS分布式存储上,以预定好的备份策略来定期备份redis中的数据
RDB也可以做冷备,生产多个文件,每个文件都代表某一时刻的完整数据快照 -
RDB对redis对外提供的读写服务,影响非常小,可以让redis保持高性能
-
相对于AOF持久化机制来说,直接基于RDB数据文件来重启和恢复redis进程,更加快速
缺点
- 如果想要在redis故障时,尽可能少的丢失数据,那么RDB没有AOF好。一般来说,RDB数据快照文件,都是每隔5分钟,或者更长时间生成一次,这个时候就得接受一旦redis进程宕机,那么会丢失最近5分钟的数据。这个问题也是RDB最大的缺点,就是不适合做第一优先的恢复方案,如果依赖RDB做第一优先恢复方案,会导致数据丢失的比较多
- RDB每次在fork子进程来执行RDB快照数据文件生成的时候,如果数据文件特别大,可能会导致对客户端提供的服务暂停数毫秒,或者甚至数秒
一般不要让RDB间隔时间太长,否则每次生成的RDB文件太大,对Redis本身的性能会有影响
三、AOF实现数据持久化
AOF(Append Only File)。Redis 默认不开启。它的出现是为了弥补RDB的不足(数据的不一致性),所以它采用日志的形式来记录每个写操作,并追加到文件中。Redis 重启的会根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作。
如果AOF和RDB同时开启,那么在启动redis时默认会优先使用AOF进行数据恢复。
1、redis.config中AOF的配置
1246 # AOF and RDB persistence can be enabled at the same time without problems.
1247 # If the AOF is enabled on startup Redis will load the AOF, that is the file
1248 # with the better durability guarantees.
1249 #
1250 # Please check https://redis.io/topics/persistence for more information.
1251
1252 appendonly no // no表示AOF默认是不开启的
1253
1254 # The name of the append only file (default: "appendonly.aof")
1255
1256 appendfilename "appendonly.aof" // AOF进行写操作的时候的目标文件名
...
1279 # If unsure, use "everysec".
1280
1281 # appendfsync always //同步持久化,每次发生数据变化会立刻写入到磁盘中。性能较差当数据完整性比较好(慢,安全)
1282 appendfsync everysec //出厂默认推荐,每秒异步记录一次(默认值)
1283 # appendfsync no //不同步,效率最高
...
1304 no-appendfsync-on-rewrite no
...
//当AOF文件大小是上次rewrite后大小的一倍且文件大于64M时触发。一般都设置为3G,64M太小了。
1323 auto-aof-rewrite-percentage 100
1324 auto-aof-rewrite-min-size 64mb
2、数据的持久化操作
通过AOF实现数据的持久化操作,我们只需要开启appendonly
就可以。当然你也可以根据上述的操作,进行个性化定制。
开启appendonly
我们可以发现,在开启AOF之前,bin(启动目录)下是不存在appendonly.aof
文件的
将appendonly
设为yes
即为开启AOF
进行测试
[root@localhost bin]# redis-server myconfig/redis.conf //来气redis
[root@localhost bin]# redis-cli -p 6379 //连接客户端
127.0.0.1:6379> ping // 连接成功
PONG
127.0.0.1:6379> SHUTDOWN //关闭redis服务
not connected> exit //退出
[root@localhost bin]# redis-server myconfig/redis.conf //重新启动redisServer
[root@localhost bin]# redis-cli -p 6379 // 重新连接客户端
127.0.0.1:6379> ping
PONG
127.0.0.1:6379> set name tiger // 进行写操作
OK
127.0.0.1:6379> set age 18 //进行写操作
OK
127.0.0.1:6379>
我们经过测试可知,当开启AOF后重启redis后再bin(启动目录)下自动创建appendonly.aof
文件。
查看appendonly.aof
文件,发现里面是我在redis中进行写操作的历史记录。
3、appendonly.aof文件的修复
因为在启动redis时,redis先去读取appendonly.aof 中的数据,进行数据恢复。如果appendonly.aof文件有误那么redis将会启动失败
我们进行一些认为操作破坏appendonly.aof文件中的内容
重启redis,发现无法连接
在redis的启动目录中有一个名为redis-check-aof
的文件,其作用就是修复appendonly.aof
文件
我们可以使用 redis-check-aof --fix appendonly.aof
对aof文件进行修复。修复过程中是将appendonly.aof中错误的记录进行删除
[root@localhost bin]# redis-check-aof --fix appendonly.aof
0x 4f: Expected prefix '$', got: 'd'
AOF analyzed: size=139, ok_up_to=57, ok_up_to_line=18, diff=82
This will shrink the AOF from 139 bytes, with 82 bytes, to 57 bytes
Continue? [y/N]: y
Successfully truncated AOF //修复成功
[root@localhost bin]#
重启redis
[root@localhost bin]# redis-server myconfig/redis.conf
[root@localhost bin]# redis-cli -p 6379
127.0.0.1:6379> ping
PONG //启动成功
127.0.0.1:6379> get name //获取name,成功
"tiger"
127.0.0.1:6379> get age //获取age,失败(因为age对应的appendonly.aof中的数据是错误的,在进行修复的时候被删除了)
(nil)
127.0.0.1:6379>
4、AOF方式持久化的优缺点
优点:数据的完整性和一致性更高。
缺点:因为AOF记录的内容多,文件会越来越大,数据恢复也会越来越慢。
四、总结
1、Redis 默认开启RDB持久化方式,在指定的时间间隔内,执行指定次数的写操作,则将内存中的数据写入到磁盘中。
2、RDB 持久化适合大规模的数据恢复但它的数据一致性和完整性较差。
3、Redis 需要手动开启AOF持久化方式,默认是每秒将写操作日志追加到AOF文件中。
4、AOF 的数据完整性比RDB高,但记录内容多了,会影响数据恢复的效率。
5、Redis 针对 AOF文件大的问题,提供重写的瘦身机制。
6、若只打算用Redis 做缓存,可以关闭持久化。
7、若打算使用Redis 的持久化。建议RDB和AOF都开启。其实RDB更适合做数据的备份,留一后手。AOF出问题了,还有RDB。
学无止境 …