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對象,會采取不同方式存儲。

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. 重點回顧

## 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
```

2. aof文件的裝載

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. 重點回顧

## 事件

* 重點回顧

- 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