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-mem4
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)
- Redis来回摩擦
- redis的数据结构SDS和DICT
- redis的持久化和事件模型
- Java
- 从何而来之Java IO
- 发布Jar包到公共Maven仓库
- Java本地方法调用
- 面试突击
- Linux
- Nginx
- SpringBoot
- Springboot集成Actuator和SpringbootAdminServer监控
- SpringCloud
- Spring Cloud初识
- Spring Cloud的5大核心组件
- Spring Cloud的注册中心
- Spring Cloud注册中心之Eureka
- Spring Cloud注册中心之Consul
- Spring Cloud注册中心之Nacos
- Spring Cloud的负载均衡之Ribbon
- Spring Cloud的服务调用之Feign
- Spring Cloud的熔断器
- Spring Cloud熔断器之Hystrix
- Spring Cloud的熔断器监控
- Spring Cloud的网关
- Spring Cloud的网关之Zuul
- Spring Cloud的配置中心
- Spring Cloud配置中心之Config Server
- Spring Cloud Config配置刷新
- Spring Cloud的链路跟踪
- Spring Cloud的链路监控之Sleuth
- Spring Cloud的链路监控之Zipkin
- Spring Cloud集成Admin Server
- Docker
- docker日常基本使用
- docker-machine的基本使用
- Kubernetes
- kubernetes初识
- kubeadm安装k8s集群
- minikube安装k8s集群
- k8s的命令行管理工具
- k8s的web管理工具
- k8s的相关发行版
- k3s初识及安装
- rancher的安装及使用
- RaspberryPi
- 运维
- 域名证书更新
- 腾讯云主机组建内网
- IDEA插件开发
- 第一个IDEA插件hello ide开发
- 千呼万唤始出来的IDEA笔记插件mdNote
- 大刚学算法
- 待整理
- 一些概念和知识点
- 位运算
- 数据结构
- 字符串和数组
- LC242-有效的字母异位词
- 链表
- LC25-K个一组翻转链表
- LC83-删除有序单链表重复的元素
- 栈
- LC20-有效的括号
- 队列
- 双端队列
- 优先队列
- 树
- 二叉树
- 二叉树的遍历
- 二叉树的递归序
- 二叉树的前序遍历(递归)
- 二叉树的前序遍历(非递归)
- 二叉树的中序遍历(递归)
- 二叉树的中序遍历(非递归)
- 二叉树的后序遍历(递归)
- 二叉树的后序遍历(非递归)
- 二叉树的广度优先遍历(BFS)
- 平衡二叉树
- 二叉搜索树
- 满二叉树
- 完全二叉树
- 二叉树的打印(二维数组)
- 树的序列化和反序列化
- 前缀树
- 堆
- Java系统堆优先队列
- 集合数组实现堆
- 图
- 图的定义
- 图的存储方式
- 图的Java数据结构(邻接表)
- 图的表达方式及对应场景创建
- 图的遍历
- 图的拓扑排序
- 图的最小生成树之Prim算法
- 图的最小生成树之Kruskal算法
- 图的最小单元路径之Dijkstra算法
- 位图
- Java实现位图
- 并查集
- Java实现并查集
- 滑动窗口
- 单调栈
- 排序
- 冒泡排序BubbleSort
- 选择排序SelectSort
- 插入排序InsertSort
- 插入排序InsertXSort
- 归并排序MergeSort
- 快速排序QuickSort
- 快速排序优化版QuickFastSort
- 堆排序HeapSort
- 哈希Hash
- 哈希函数
- guava中的hash函数
- hutool中的hash函数
- 哈希表实现
- Java之HashMap的实现
- Java之HashSet的实现
- 一致性哈希算法
- 经典问题
- 荷兰国旗问题
- KMP算法
- Manacher算法
- Go