目录
Redis 持久化
Redis主要是工作在内存中。内存本身就不是一个持久化设备,断电后数据会清空。所以Redis在工作过程中,如果发生了意外停电事故,如何尽可能减少数据丢失。
即,
由于Redis工作在内存中,现在将内存中的数据存储到硬盘中,这个过程就是持久化。(redis的特性是远程的,内存中,非关系型)
Redis提供了两种不同级别的持久化的方式:RDB方式和AOF方式;其中RDB方式,能够在指定的时间间隔内对数据进行快照存储;AOF(Append-only-file)持久化方式每次对服务器写的操作,当服务器重启的时候回执行这些命令来回复原始数据,AOF命令以redis 协议追加保存每次写的操作到文件末尾。
RDB简介(时间段,数据集,快照)
RDB:在指定的时间间隔内将内存中的数据集快照写入磁盘,也就是行话讲的Snapshot快照,它恢复时是将快照文件直接读到内存里。工作机制:
每隔一段时间,就把内存中的数据保存到硬盘上的指定文件中。RDB是默认开启的!
Redis会单独创建(fork)一个子进程来进行持久化,会先将数据写入到一个临时文件中【xxx.rdb】,待持久化过程都结束了,再用这个临时文件替换上次持久化好的文件。整个过程中,主进程是不进行任何IO操作的,这就确保了极高的性能如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效。
RDB的缺点是最后一次持久化后的数据可能丢失。
RDB保存策略
save 900 1 900 秒内如果至少有 1 个 key 的值变化,则保存
save 300 10 300 秒内如果至少有 10 个 key 的值变化,则保存
save 60 10000 60 秒内如果至少有 10000 个 key 的值变化,则保存
save “” 就是禁用RDB模式;
查询如下:
[root@hadoop103 ~]# cd /usr/local/redis/
[root@hadoop103 redis]# cd bin
[root@hadoop103 bin]# ll
总用量 26400
-rw-r--r--. 1 root root 103 10月 22 18:40 dump.rdb
-rwxr-xr-x. 1 root root 5580327 10月 22 11:30 redis-benchmark
-rwxr-xr-x. 1 root root 22217 10月 22 11:30 redis-check-aof
-rwxr-xr-x. 1 root root 7829866 10月 22 11:30 redis-check-rdb
-rwxr-xr-x. 1 root root 5709195 10月 22 11:30 redis-cli
-rw-r--r--. 1 root root 46689 10月 22 16:02 redis.conf
lrwxrwxrwx. 1 root root 12 10月 22 11:30 redis-sentinel -> redis-server
-rwxr-xr-x. 1 root root 7829866 10月 22 11:30 redis-server
[root@hadoop103 bin]# vim redis.conf
# save ""
save 900 1
save 300 10
save 60 10000
# By default Redis will stop accepting writes if RDB snapshots are enabled
这里在命令模式下,定位到202行使用
202 shift + g
顶行使用 gg
末行 shift + g
属性 | 含义 | 备注 |
save | 保存策略 |
|
dbfilename | RDB快照文件名 |
|
dir | RDB快照保存的目录 | 必须是一个目录,不能是文件名。最好改为固定目录。默认为./代表执行redis-server命令时的当前目录! |
stop-writes-on-bgsave-error | 是否在备份出错时,继续接受写操作 | 如果用户开启了RDB快照功能,那么在redis持久化数据到磁盘时如果出现失败,默认情况下,redis会停止接受所有的写请求 |
rdbcompression | 对于存储到磁盘中的快照,可以设置是否进行压缩存储。 | 如果是的话,redis会采用LZF算法进行压缩。如果你不想消耗CPU来进行压缩的话, 可以设置为关闭此功能,但是存储在磁盘上的快照会比较大。 |
rdbchecksum | 是否进行数据校验 | 在存储快照后,我们还可以让redis使用CRC64算法来进行数据校验,但是这样做会增加大约10%的性能消耗, 如果希望获取到最大的性能提升,可以关闭此功能。 |
# The filename where to dump the DB
dbfilename dump.rdb
# The working directory.
#
# The DB will be written inside this directory, with the filename specified
# above using the 'dbfilename' configuration directive.
#
# The Append Only File will also be created inside this directory.
#
# Note that you must specify a directory here, not a file name.
dir ./
dir是快照保存的目录,快照保存了Redis写入的数据,该目录就保存在当前的目录下面,也就是和server服务端程序保存的目录是一致的。
# However if you have setup your proper monitoring of the Redis server
# and persistence, you may want to disable this feature so that Redis will
# continue to work as usual even if there are problems with disk,
# permissions, and so forth.
stop-writes-on-bgsave-error yes
如果设置为yes ,这表明当redis在持久化数据到磁盘的时候,如果失败的话,那么redis将会拒绝所有对redis本身的写操作。
# RDB files created with checksum disabled have a checksum of zero that will
# tell the loading code to skip the check.
rdbchecksum yes
如果将该参数设置为 yes 的话,则表明在将redis的数据持久化到磁盘的时候,进行数据校验。
RDB的触发
首先,我们查询一下在/usr/local/bin目录下是否有rdb文件,如有,删除该文件,并检查是否真的删除成功::
进入配置文件,为了测试方便,修改一下时间为,如果30秒内有至少5个key值变化,则保存rdb文件到当前的文件夹:
[root@hadoop103 bin]# vim redis.conf
save 900 1
save 30 5
save 60 10000
如果redis处于启动状态,然后重启(先kill 9 然后在执行可执行文件)。
可见,已经rdb‘的存储被触发,退出客户端,然后在进入客户端,在检查rdb中是否真的存储了数据:
[root@hadoop103 bin]# ./redis-cli
127.0.0.1:6379> keys *
1) "k5"
2) "k1"
3) "k2"
4) "k3"
5) "k4"
6) "k6"
127.0.0.1:6379>
接下来我们证明一下如果在客户端执行了flushdb的操作,那么代表这个所有的数据将会被清空!有上面的截图中我们可以看到dump.rdb 文件的大小为116字节,现在我连接客户端,执行flush操作,在连接客户端执行flushdb操作之前,先将dump.rdb备份一份。
首先dump.rdb的文件大小变为76字节,说明该文件默认的大小为76字节,接着,我们将备份的文件复原为dump.rdb 然后再查看redis能否读到之前写入的数据,具体的操作如下:
[root@hadoop103 bin]# ./redis-cli
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379>
[root@hadoop103 bin]# cp dump.rdb_backup dump.rdb
cp:是否覆盖"dump.rdb"? y
[root@hadoop103 bin]# ./redis-cli
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379>
[root@hadoop103 bin]# ps -ef|grep redis
root 3949 1 0 18:19 ? 00:00:01 ./redis-server *:6379
root 4006 3876 0 18:43 pts/0 00:00:00 grep redis
[root@hadoop103 bin]# kill -9 3949
[root@hadoop103 bin]# ./redis-server ./redis.conf
[root@hadoop103 bin]# ps -ef|grep redis
root 4008 1 0 18:43 ? 00:00:00 ./redis-server *:6379
root 4012 3876 3 18:43 pts/0 00:00:00 grep redis
[root@hadoop103 bin]# ./redis-cli
127.0.0.1:6379> keys *
1) "k4"
2) "k6"
3) "k2"
4) "k1"
5) "k3"
6) "k5"
127.0.0.1:6379>
。证明完毕。以上的实验可以的得到两个结论:
RDB的方式,只要保存的dump.rdb文件没有被破坏或者是保存,一旦redis服务器启动,客户端连接之后,就能读取到redis服务器中之前写入的数据;
执行了flush操作,会清空redis中添加的数据,其实就是清空了dump.rdb文件。
RDB的优缺点:
AOF简介(实时的,空间大,存命令)
- AOF是以日志的形式来记录每个写操作,将每一次对数据进行修改,都把新建、修改数据的命令保存到指定文件中。Redis重新启动时读取这个文件,重新执行新建、修改数据的命令恢复数据。
- 默认不开启,需要手动开启 593 行 appendonly yes
- AOF文件的保存路径,同RDB的路径一致。# dir ./
- AOF在保存命令的时候,只会保存对数据有修改的命令,也就是写操作!
- 当RDB和AOF存的不一致的情况下,按照AOF来恢复。因为AOF是对RDB的补充。备份周期更短,也就更可靠
appendfsync always:每次产生一条新的修改数据的命令都执行保存操作;效率低,但是安全!
appendfsync everysec:每秒执行一次保存操作。如果在未保存当前秒内操作时发生了断电,仍然会导致一部分数据丢失(即1秒钟的数据)。
appendfsync no:从不保存,将数据交给操作系统来处理。更快,也更不安全的选择。
推荐(并且也是默认)的措施为每秒 fsync 一次, 这种 fsync 策略可以兼顾速度和安全性。
属性 | 含义 | 备注 |
appendonly | 是否开启AOF功能 | 默认是关闭的 yes |
appendfilename | AOF文件名称 | appendonly.aof |
appendfsync | AOF保存策略 | 官方建议everysec |
no-appendfsync-on-rewrite | 在重写时,是否执行保存策略 | 执行重写,可以节省AOF文件的体积;而且在恢复的时候效率也更高。 |
auto-aof-rewrite-percentage | 重写的触发条件 | 当目前aof文件大小超过上一次重写的aof文件大小的百分之多少进行重写 |
auto-aof-rewrite-min-size | 设置允许重写的最小aof文件大小 | 避免了达到约定百分比但尺寸仍然很小的情况还要重写 |
在开启了AOF之后,bin下面会多出一个文件:
appendonly.conf
然后我们连接服务器:执行如下从操作,可知,一旦AOF开启,就会读取 aof 的配置文件。
[root@hadoop103 bin]# ./redis-cli
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379>
然后我们在redis中写入数据,然后查看appendonly.aof 的文件大小
127.0.0.1:6379> set k1 v1
OK
127.0.0.1:6379> set k2 v2
OK
127.0.0.1:6379> set k3 v3
OK
127.0.0.1:6379> set k4 v4
OK
127.0.0.1:6379> set k5 v5
OK
127.0.0.1:6379> shutdown
not connected>
[root@hadoop103 bin]# ll
总用量 26408
-rw-r--r--. 1 root root 168 10月 23 19:07 appendonly.aof
-rw-r--r--. 1 root root 116 10月 23 19:08 dump.rdb
-rw-r--r--. 1 root root 123 10月 23 18:36 dump.rdb_backup
-rwxr-xr-x. 1 root root 5580327 10月 22 11:30 redis-benchmark
-rwxr-xr-x. 1 root root 22217 10月 22 11:30 redis-check-aof
-rwxr-xr-x. 1 root root 7829866 10月 22 11:30 redis-check-rdb
-rwxr-xr-x. 1 root root 5709195 10月 22 11:30 redis-cli
-rw-r--r--. 1 root root 46688 10月 23 18:58 redis.conf
lrwxrwxrwx. 1 root root 12 10月 22 11:30 redis-sentinel -> redis-server
-rwxr-xr-x. 1 root root 7829866 10月 22 11:30 redis-server
然后,我们重启redis服务,并连接客户端,尽管,我们关闭了客户机,但是,我们依然能够读取到写入到aof中的命令,并通过这些命令我们能够读取到之前写入的数据。在我们验证能够读取到之前写入的数据之后,我们执行flushall操作之后,再次在bin目录下查看文件的大小变化,会发现dump.rdb文件再次恢复到76 ,而aof的文件依然保持自己的大小。
[root@hadoop103 bin]# ./redis-server ./redis.conf
[root@hadoop103 bin]# ./redis-cli
127.0.0.1:6379> keys *
1) "k2"
2) "k5"
3) "k1"
4) "k3"
5) "k4"
127.0.0.1:6379> flushall
OK
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379>
[root@hadoop103 bin]# ll
总用量 26408
-rw-r--r--. 1 root root 209 10月 23 19:10 appendonly.aof
-rw-r--r--. 1 root root 76 10月 23 19:10 dump.rdb
-rw-r--r--. 1 root root 123 10月 23 18:36 dump.rdb_backup
-rwxr-xr-x. 1 root root 5580327 10月 22 11:30 redis-benchmark
-rwxr-xr-x. 1 root root 22217 10月 22 11:30 redis-check-aof
-rwxr-xr-x. 1 root root 7829866 10月 22 11:30 redis-check-rdb
-rwxr-xr-x. 1 root root 5709195 10月 22 11:30 redis-cli
-rw-r--r--. 1 root root 46688 10月 23 18:58 redis.conf
lrwxrwxrwx. 1 root root 12 10月 22 11:30 redis-sentinel -> redis-server
-rwxr-xr-x. 1 root root 7829866 10月 22 11:30 redis-server
然后,我们重新连接客户端,是不能读取到之前的入写入的数据,那么我们修改appendonly.aof 文件,将最后一个flushall的命令删除之后保存退出,在重启服务器,连接上客户端之后,我们发现能够读取到之前写入的数据。
[root@hadoop103 bin]# vim appendonly.aof
[root@hadoop103 bin]# ./redis-cli
127.0.0.1:6379> shutdown
not connected>
[root@hadoop103 bin]# ./redis-server ./redis.conf
[root@hadoop103 bin]# ./redis-cli
127.0.0.1:6379> keys *
1) "k1"
2) "k2"
3) "k4"
4) "k3"
5) "k5"
127.0.0.1:6379>
此时,有可能在我们的aof文件中,如果出现了非法的命令,那么可以执行
./redis-check-aop --fix **.aof
来修复该文件。