十五、Redis进阶-Redis两种持久化方式记录
什么是Redis持久化
Redis持久化是将存储在内存中的数据永久保存在硬盘中。
Redis为什么需要持久化
Redis的强大性能很大程度上是因为将所有数据都存储中了内存当中,当Redis重启之后,所有存储中内存中的数据就会丢失。在某些情况下,希望Redis重启之后数据不丢失,这就需要用到持久化了。如下面的情况就需要持久化:
1)将Redis作为数据库使用时;
2)将Redis作为缓存服务器,由于缓存被穿透后会对性能造成较大的影响,所有缓存同时失效会导致缓存雪崩,从而使服务器无法响应。
因此,需要将内存中的数据以某种形式同步到硬盘中,使得重启之后可以根据硬盘中的记录恢复数据。
Redis持久化方式
**Redis支持RDB和AOF两种方式的持久化。**RDB持久化根据指定的规则“定时”将内存中的数据存储到硬盘上;AOF则是在每次执行命令之后将命令本身记录下来。
两种持久化方式可以单独使用其中一种,更多的是将2种结合使用。
方式一、RDB方式实现持久化
RBD方式的持久化是通过快照(snapshotting)完成的,当符合一定条件时Redis会自动将内存中的所有数据生成一份副本并存储在硬盘上,这个过程就是“快照”。
【理解快照】什么是快照?类型VM中的快照,使用系统时,可以使用VM中的快照功能对当前系统进行拍照,拍完照之后使用系统时,系统发生了故障,就可以通过快照对系统系统恢复。
如下几种情况时,Redis会对数据进行快照:
- 根据配置规则进行自动快照
- 用户执行SAVE或BGSAVE命令
- 执行FLUSHALL命令
- 执行复制(replication)时
1)根据配置规则进行自动快照
对配置文件进行save配置,即配置自动进行快照功能。Redis配置文件已经默认了3条不同条件的配置,如下
# 900秒后,有一个或一个以上的键被更改,则进行快照
save 900 1
# 300后,至少有10键被修改,则进行快照
save 300 10
# 60秒内,至少有10000键被修改,则进行快照
save 60 10000
如上可以看到:每条快照以save开头,且每条快照条件独占一行。可以同时存在多个条件,条件之间是“或”关系。
实现
a)注释默认的配置文件并设置新快照条件
#save 900 1
#save 300 10
#save 60 10000
# 60秒后如果修改3次,则进行快照
save 60 3
b)删除dump.rdb文件
c)设置值,并等待60秒后查看是否有dump文件生成
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
d)60秒已经生成dump文件,重启虚拟机,强制退出redis,假设突然断电
e)重新启动redis,查看数据是否恢复
127.0.0.1:6379> get k1
"v1"
可以看到数据已经恢复了。没错,这就是自动执行快照。
2)用户执行save或bgsave命令
除了自动快照之外,还可以进行手动快照。当服务重启、手动迁移以及备份时,可以使用手动进行快照操作。
save命令
当执行save指令时,Redis同步进行快照操作,在快照执行的过程中会阻塞所有来自客户端的请求。当数据过多时,save会导致Redis长时间不响应。
127.0.0.1:6379> set k6 v6
OK
127.0.0.1:6379> save
OK
127.0.0.1:6379> set k7 v7
OK
bgsave命令
手动执行快照,推荐使用bgsave。bgsave命令可以在后台异步进行快照操作,快照的同时服务可以继续响应来自客户端的请求。执行bgsave后,Redis会立即返回OK,表示开始执行快照操作。通过lastsave命令查看最近一次成功执行快照的时间。
3)执行flushall命令
当执行flushall命令时,Redis清除数据库中的所有数据。无论清空数据库的过程中是否触发了自动快照条件,只要自动快照条件不为空,Redis就会执行一次快照操作。
4)执行复制时
当设置了主从模式时,Redis会在复制初始化时进行自动快照。
快照原理
Redis默认会将快照文件存储在Redis当前进程的工作目录中的dump.rdb文件中。通过配置dir和dbfilename两个参数分别指定快照文件的存储路径和文件名。
快照执行过程如下:
1)Redis使用fork函数复制一份当前进程(父进程)的副本(子进程);
2)父进程继续接收并处理客户端发来的命令,而子进程开始将内存中的数据写入硬盘中的临时文件;
3)当子进程写入完所有数据后会用该临时文件替换旧的RDB文件,至此一次快照操作完成。
方式二、AOF方式实现
当使用Redis存储非临时数据时,一般需要打开AOF持久化来降低进程中止导致的数据丢失。
1)开启AOF
Redis默认不开启AOF(append only file)方式持久化,通过修改配置文件appendonly参数启用:
appendonly yes
appendfsync always
2)写入命令
127.0.0.1:6379> set name wangwu
OK
3)查看appenonly.aof文件
-rw-r--r--. 1 root root 58 Sep 4 06:50 appendonly.aof
这样AOF就实现了。
AOF重写
为什么需要重写?有些命令是冗余的,也会被记录。随着命令不断写入,AOF文件越来越大,这时希望对该文件进行优化,针对冗余命令,可以进行删除,保留一条。
手动后台重写 bgrewriteaof
127.0.0.1:6379> bgrewriteaof
Background append only file rewriting started
[root@192 bin]# ll
total 45668
-rw-r--r--. 1 root root 58 Sep 4 06:50 appendonly.aof
[root@192 bin]# ll
total 45668
-rw-r--r--. 1 root root 110 Sep 4 07:05 appendonly.aof
可以清楚的看到,aof文件变小了
自动重写
auto-aof-rewrite-percentage spercentage
# 如:auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size size
# 如:auto-aof-rewrite-min-size 64mb
重写的作用
1)降低磁盘占用量,提高磁盘利用率
2)提高持久化效率,降低持久化写时间,提高O/I性能
3)降低数据恢复用时,提高数据恢复效率
同步硬盘数据
虽然每次执行命令,aof都会将命令记录在aof文件中,而实际上,由于操作系统缓存机制,数据并没有真正写入硬盘,而是进入了系统的硬盘缓存。默认情况下系统每30秒会执行一次同步操作,这时才是真正写入硬盘。
如果在这30秒的过程中,系统异常退出,则会导致硬盘缓存中的数据丢失,这是aof持久化无法容忍的损失。可以通过appendfsync
参数设置同步时机:
appendfsync always/everysec/no
always表示每次执行写入都会执行同步
no表示不主动进行同步操作
everysec表示每秒进行同步