🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
2021-04-11 周天 ## 知识点 1. redis数据库的持久化。 因为Redis是内存型数据库,如果不将数据存到磁盘上,一旦程序退出或者断电,数据就会丢失。 2. redis模型和事件。 ## rdb rdb是redis提供的一种持久化方式,是将redis内存快照存到dump.rdb文件中,重启时可以从最新的快照文件恢复数据。 ### save和bgsave命令 * save命令会阻塞服务端进程,直至rdb文件生成结束。 * bgsave命令则是fork一个子进程去完成rdb文件的生成,不会阻塞服务端进程。 * save和bgsave在服务端不会同时执行。 * rdb文件在装载时,服务器会处于阻塞状态,直到装载完成,才对外提供服务。 1. 自动间歇性保持rdb ``` # save <seconds> <changes> # Will save the DB if both the given number of seconds and the given # In the example below the behaviour will be to save: # Note: you can disable saving completely by commenting out all "save" lines. # It is also possible to remove all the previously configured save # points by adding a save directive with a single empty string argument # save "" save 900 1 save 300 10 save 60 10000 ``` 只要满足3个条件中的一个,bgsave就会被执行。 save的保存条件会存在redisServer下的saveparams参数里。 ``` long long dirty; /* 记录数据库状态修改了多少次(rdb后会重置为0) */ long long dirty_before_bgsave; /* Used to restore dirty on failed BGSAVE */ time_t lastsave; /* save最后执行成功时间 */ time_t lastbgsave_try; /* bgsave最后执行成功时间 */ struct saveparam *saveparams; /* Save points array for RDB */ struct saveparam { time_t seconds; int changes; }; ``` 2. rdb文件结构 redis版本升级后,可能会对该结构做部分优化。(该结构是2.9版本) redis rdb是一个经过压缩的二进制文件,包含多个部分,结构如下图。对不不同类型的redis对象,会采取不同方式存储。 ![](https://img.kancloud.cn/60/88/608845237501698fc26d23065e0de066_1416x752.png) 3. rdb相关演示 在6.0版本下演示结果: 先保存空的rdb文件,查看格式;接着在10数据库里加入了一个kv,保存rdb文件后再次查看效果。 ``` shell [root@68df2d288502 6379]# od -c dump.rdb 0000000 R E D I S 0 0 0 9 372 \t r e d i s 0000020 - v e r 005 6 . 0 . 6 372 \n r e d i 0000040 s - b i t s 300 @ 372 005 c t i m e 302 0000060 321 342 w ` 372 \b u s e d - m e m 302 p 0000100 326 \r \0 372 \f a o f - p r e a m b l 0000120 e 300 \0 377 036 . 334 247 236 q > 277 0000134 [root@68df2d288502 6379]# redis-cli 127.0.0.1:6379> select 0 OK 127.0.0.1:6379> select 10 OK 127.0.0.1:6379[10]> DBSIZE (integer) 0 127.0.0.1:6379[10]> SADD KEY1 hello (integer) 1 127.0.0.1:6379[10]> DBSIZE (integer) 1 127.0.0.1:6379[10]> save OK 127.0.0.1:6379[10]> exit [root@68df2d288502 6379]# od -c dump.rdb 0000000 R E D I S 0 0 0 9 372 \t r e d i s 0000020 - v e r 005 6 . 0 . 6 372 \n r e d i 0000040 s - b i t s 300 @ 372 005 c t i m e 302 0000060 351 343 w ` 372 \b u s e d - m e m 302 ` 0000100 327 \r \0 372 \f a o f - p r e a m b l 0000120 e 300 \0 376 \n 373 001 \0 002 004 K E Y 1 001 005 0000140 h e l l o 377 200 354 } ] 214 345 * 0000156 ``` 4. 重点回顾 ![](https://img.kancloud.cn/4a/c6/4ac67c73d7928b3f203ae0a3b53f1502_1250x344.png) ## aof append only file,redis另外一种持久化方式,采取的是存储客户端执行命令来记录数据库状态的。 1. aof的文件写入及文件格式 ``` struct redisServer{ ... sds aof_buf; /* AOF buffer, written before entering the event loop */ ... } ``` 其中aof需要记录的命令都会先存储到aof_buf的sds数据结构中,等刷新到磁盘后清空掉已经写入的。 开启aof配置,并默认每秒刷新buf到磁盘策略。 ``` 1060 appendonly yes 1061 1062 # The name of the append only file (default: "appendonly.aof") 1063 1064 appendfilename "appendonly.aof" 1087 # If unsure, use "everysec". 1088 1089 # appendfsync always 1090 appendfsync everysec 1091 # appendfsync no ``` ![](https://img.kancloud.cn/ac/8e/ac8e17434d6c87659f9b2f6958fe8542_1280x1124.png) 2. aof文件的装载 ![](https://img.kancloud.cn/cb/8a/cb8af68a270aff568145476e104f4a48_636x602.png) 3. aof文件重写(瘦身) 随着时间推移,aof文件会越来越大,所以redis会为aof文件做重写处理。 比如重复执行新增k1和删除k1的命令,如果成对出现,可以将其删除掉,不影响最终数据库状态。 相关配置: ``` 1128 # Specify a percentage of zero in order to disable the automatic AOF 1129 # rewrite feature. 1130 1131 auto-aof-rewrite-percentage 100 1132 auto-aof-rewrite-min-size 64mb ``` 一旦满足如上条件,redis就会fork一个子进程去做aof重写。 或者通过命令`bgrewriteaof`来执行。 ***通过如下演示,得出结论,redis6.0.6里执行bgrewriteaof重写aof后,aof文件内存的是和rdb一样的二进制数据(不是分析原来的aof文件,而是直接rdb一次),后续的命令还是以文本方式追加。*** ``` shell [root@68df2d288502 6379]# cat appendonly.aof REDIS0009� redis-ver6.0.6� �edis-bits�@�ctime�,�w`used-mem�h4 aof-preamble�� � a key1xxxxx�(�%�iW[root@68df2d288502 6379]# [root@68df2d288502 6379]# [root@68df2d288502 6379]# ls appendonly.aof dump.rdb [root@68df2d288502 6379]# redis-cli 127.0.0.1:6379> DBSIZE (integer) 0 127.0.0.1:6379> select 10 OK 127.0.0.1:6379[10]> DBSIZE (integer) 2 127.0.0.1:6379[10]> set aaa 111 OK 127.0.0.1:6379[10]> get aaa "111" 127.0.0.1:6379[10]> INCR aaa (integer) 112 127.0.0.1:6379[10]> exit [root@68df2d288502 6379]# ll total 8 -rw-r--r-- 1 root root 202 Apr 15 08:46 appendonly.aof -rw-r--r-- 1 root root 124 Apr 15 08:38 dump.rdb [root@68df2d288502 6379]# cat appendonly.aof REDIS0009� redis-ver6.0.6� �edis-bits�@�ctime�,�w`used-mem�h4 aof-preamble�� � a key1xxxxx�(�%�iW*2 $6 SELECT $2 10 *3 $3 set $3 aaa $3 111 *2 $4 INCR $3 aaa [root@68df2d288502 6379]# redis-cli 127.0.0.1:6379> BGREWRITEAOF Background append only file rewriting started 127.0.0.1:6379> exit [root@68df2d288502 6379]# ll total 8 -rw-r--r-- 1 root root 131 Apr 15 08:47 appendonly.aof -rw-r--r-- 1 root root 124 Apr 15 08:38 dump.rdb [root@68df2d288502 6379]# cat appendonly.aof REDIS0009� redis-ver6.0.6� �edis-bits�@�ctime´�w`used-memˆ4 aof-preamble�� �aaa�p a key1xxxxx��'a����[root@68df2d288502 6379]# cat dump.rdb REDIS0009� redis-ver6.0.6� redis-bits�@�ctime…�w`used-mem�X� � aof-preamble�� � a key1xxxxx�8{A�\��g[root@68df2d288502 6379]# redis-cli 127.0.0.1:6379> save OK 127.0.0.1:6379> exit [root@68df2d288502 6379]# ll total 8 -rw-r--r-- 1 root root 131 Apr 15 08:47 appendonly.aof -rw-r--r-- 1 root root 131 Apr 15 08:48 dump.rdb [root@68df2d288502 6379]# ``` 4. 重点回顾 ![](https://img.kancloud.cn/d1/09/d1095b8728821f7e188f3805e4a578d8_1262x736.png) ## 事件 ![](https://img.kancloud.cn/b0/6f/b06f3e54314641794bc7b859a9df155b_1684x1250.png) * 重点回顾 ![](https://img.kancloud.cn/79/48/79487fa03d6b5676108ea20fd85adf50_1260x558.png)