一、持久化的作用
1.1、什么是持久化
redis所的数据是保存在内存中,对数据的更新将异步地保存到磁盘上。
1.2、持久化的实现方式
1、快照---mysql的Dump、Redis的RDB
2、写日志---Mysql的Binlog、Hbase的Hlog、Redis的AOF
二、RDB
2.1、什么是RDB

2.2、触发机制–主要三种方式
(1)、save(同步):会造成阻塞,O(n),会替换掉旧的.rdb文件;
(2)、bgsave(异步):会fork一个子进程进行持久化操作,在fork的过程中依然可能造成阻塞,O(n),会替换旧的.rdb文件;
(3)、自动:
900秒内1次改变,
300秒内10次改变,
60秒内10000次改变,会自动生成(bgsave)RDB文件
redis.conf的几个参数说明:
dbfilename:rdb文件名
dir ./:生成的rdb文件存放的位置;
stop-writes-on-gbsave-error yes:bgsave发生错误是否停止写入;
rdbcompression yes:rdb文件是否采用压缩的格式;
rdbchecksum yes:是否对rdb文件进行一个校验和的检验;
2.3、触发机制–不容忽略方式
1、全量复制
2、debug reload
3、shutdown
2,4、实验
修改redis.conf如下几个配置
1 | ################################ GENERAL ##################################### |
其他配置保持默认
执行如下操作:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15127.0.0.1:6379> dbsize
(integer) 0
127.0.0.1:6379> set k1 1
OK
127.0.0.1:6379> set k2 2
OK
127.0.0.1:6379> set k3 2
OK
127.0.0.1:6379> set k4 2
OK
127.0.0.1:6379> set k5 2
OK
127.0.0.1:6379> save
OK
127.0.0.1:6379>
查看后台:1
2
3
4
5
6-rw-r--r--. 1 root root 2298 Jun 7 09:32 6379.log
-rw-r--r--. 1 root root 4753 Jun 7 09:24 6382.log
-rw-r--r--. 1 root root 50 Jun 7 09:32 dump-6379.rdb
[root@promote data]# pwd
/root/redis/data
[root@promote data]#
说明:
(1)、若在redis中的数据较大,比如400多M,当执行save命令进行持久化时,同时有另外的客户端在执行get操作,此时的get操作会被阻塞,知道save命令执行完成。
(2)、但是如果是在执行bgsave后,立即执行get操作,则不会阻塞get操作,因为此时主进程会fork一个子进程进行save,主进程执行get操作。
(3)、执行save或者bgsave都会生成一个临时的rdb文件,然后替换旧的rdb文件;
总结
1、rdb时redis内存到硬盘的快照,用于持久化;
2、save通常会阻塞redis;
3、bgsave不会阻塞redis,但是会fork新进程;
4、save自动配置满足任一就会被执行;
5、有些触发机制不容忽视;
三、AOF
3.1、RDB现存的一些问题
RDB的缺点:
(1)、耗时,耗性能
耗时:O(n),fork:消耗内存,
DiskI/O:IO性能
(2)、不可控,丢失数据
会丢失最后一次的写数据
3.2、什么是AOF
AOF类似于日志,会将对数据的写操作写入AOF文件;
3.3、AOF三种策略
always:
每条命令fsync到硬盘;
everysec:
每秒把缓冲区fsync到硬盘
会丢失一秒的数据
no:
OS决定fsync
三者的比较:
always everysec no
优点 不丢失数据 每秒一次sync 不用管
丢一秒数据
缺点 IO开销大,一般 丢一秒数据 不可控
的sata盘只有几百
TPS
3.4、AOF重写

重写的作用:减少磁盘占用量;加速恢复速度
AOF重写实现的两种方式:
1、命令:bgrewriteaof
AOF重写配置:
2、配置: 配置名 含义
auto_aof_rewrite_min_size AOF文件重写需要的尺寸
auto_aof_rewrite_percentage AOF文件增长率
统计 统计名 含义
aof_current_size AOF当前尺寸
aof_base_size AOF上次启动和重写的
尺寸(单位:字节)
AOF自动触发时机需同时满足一下两个条件:
aof_current_size > auto_aof_rewrite_min_size
aof_current_size - aof_base_size/aof_base_szie > auto_aof_rewrite_percentage
配置说明:
appendonly yes :开启AOF持久化策略
appendfilename "appendonly-${port}.aof"
appendfsync everysec
dir /bigdiskpath
no-appendfsync-on-rewrite yes:关闭aof的append
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

aof重写流程说明:
1、首先,在执行bgrewriteaof命令后,主进程(父进程)会fork一个子进程进行重写aof操作,如图中父进程--->fork--->子进程
2、子进程从内存中回溯重写aof文件如图步骤4,但是若此时主机依然在进行读写怎么办?
3、主进程会进行3-1和3-2操作,即将主进程的写操作写入aof_buf和aof_rewrite_buf中,aof_buf中的操作会继续写入旧的AOF文件中,
而aof_rewrite_buf中的数据会在重写完成以后再将缓存中的数据追加到新的AOF文件中,如5-2
3、子进程重写AOF文件完成后,会将新生成的AOF文件替换旧的AOF文件,如5-3;
AOF后台Rewrite存在的问题:
aof_rewrite_buf是个不限大小的buffer,但用户写入的数据量较多时会出现以下两个问题:
1、占用过多内存,浪费资源;
2、主进程将aof_rewrite_buf数据写入到新AOF文件中时会阻塞工作线程,即步骤5-2,用户正常请求的延时会变高,严重情况下会超时,
主备同步也会出问题,断开重连,重新同步等
AOF后台Rewrite解决方案:
(1)、官方解决方案:主要思路是AOF重写期间,主进程跟子进程通过管道通信,主进程实时将新写入的数据发送给子进程,子进程
从管道读出数据缓存在buffer中,子进程等待存量数据全部写入AOF文件后,将缓存数据追加到AOF文件中,此方案只是解决阻塞工作线程问题,但占用内存过多问题并没有解决。
(2)、新解决方案:主要思路是AOF重写期间,主进程创建一个新的aof_buf,新的AOF文件用于接收新写入的命令,sync策略保持不
变,在AOF重写期间,系统需要向两个aof_buf,两个AOF文件同时追加新写入的命令。当主进程收到子进程重写AOF文件完成后,停
止向老的aof_buf,AOF文件追加命令,然后删除旧的AOF文件(流程跟原来保持一致);将将子进程新生成的AOF文件重命名为appendon
ly.aof.last,具体流程如下:
停止向旧的aof_buf,AOF文件追加命令;
删除旧的的appendonly.aof.last文件;
交换两个aof_buf,AOF文件指针;
回收旧的aof_buf,AOF文件;
重命令子进程生成的AOF文件为appendonly.aof.last;
3.5、AOF相关功能的演示
(1)、aof相关配置文件:
1 | appendonly no |
(2)、动态设置:
1 | 127.0.0.1:6379> config get appendonly |
(3)、可以查看,已经生成了appendonly.aof文件
1 | [root@promote config]# cd ../data/ |
1 | [root@promote data]# more appendonly.aof |
(4)、开启 BGREWRITEAOF
1 | 127.0.0.1:6379> BGREWRITEAOF |
(5)、查看aof文件
1 | [root@promote data]# cat appendonly.aof |
四、RDB和AOF的抉择
4.1、RDB和AOF比较
