redis 深入理解redis 主從複製原理
阿新 • • 發佈:2020-06-13
## redis 主從複製
![](https://img2020.cnblogs.com/blog/1440828/202006/1440828-20200613013105577-976452031.png)
`master` 節點提供資料,也就是寫。`slave` 節點負責讀。
不是說master 分支不能讀資料,也能只是我們希望將讀寫進行分離。
slave 是不能寫資料的,只能處理讀請求
## 主從實現
客戶端 `127.0.0.1:6379` 伺服器 `212.64.89.173:6379`
### 方式一
客戶端傳送請求同步命令
`slaveof masterip masterport`
```redis
slaveof 212.64.89.173 6379
```
### 方式二
客戶端啟動伺服器引數
`redis-server --slaveof masterip masterport`
```redis
redis-server --slaveof 212.64.89.173 6379
```
### 方式三
在客戶端的配置檔案中寫入 `slaveof` 資訊
```C
redis.conf
slaveof 212.64.89.173 6379
```
**注意 斷開主從連結方式:** 客戶端執行 `slaveof no one`
### 設定連結密碼
#### server 端
服務啟動後設置
```redis
config set requierpass
```
配置檔案新增密碼
```redis
# redis.conf
requirepass
```
#### client 端
命令設定密碼
```redis
auth
```
配置檔案設定密碼
```redis
masterauth
```
啟動客戶端設定密碼
```redis
redis-cli -a
```
## 建立連線
建立連結的過程就是希望 `master `和 `slave `都保有對方的 `IP` 和 `Port`。
![](https://img2020.cnblogs.com/blog/1440828/202006/1440828-20200613013143479-721802553.png)
## 資料同步
資料的同步分兩部分,全量同步和增量同步,在增量同步結束後,master 應當儲存Slave 同步資料的位置。
![](https://img2020.cnblogs.com/blog/1440828/202006/1440828-20200613013156405-1650153045.png)
### 複製(積壓)緩衝區
它有兩部分組成 `偏移量` + `位元組值`
#### 結構
![](https://img2020.cnblogs.com/blog/1440828/202006/1440828-20200613013215314-1831547129.png)
#### 建立
1 當啟動`AOF` 時就會建立 複製積壓緩衝區
2 當被選為 `master` 節點,必須建立積壓緩衝區
#### 作用
儲存所有的對資料修改或資料庫修改的指令,查詢指令不會被記錄。
#### 資料來源
所有的進入`master` 的對資料修改或資料庫修改的指令都會被填充到積壓緩衝區中。
#### 偏移量
1 `Master` 和 `Slave` 都會記錄 `offset` 值, 每次複製都會對比`offset` 是否一致。如果一致,`Master`直接從 `offset` 處開始傳緩衝區資料,如果不一致,那麼`Master`將遵循 `Slave` 的`offset` 來傳。當然會保證命令是完整的。
2 `Master` 儲存有多個 `offset` 而 `Slave` 僅儲存自己的。
3 `Master`傳送一次,記錄一次, `Slave` 接受一次記錄一次。
#### 關於Master注意
1如果master 資料量過大,應該避免業務高峰期進行資料同步。避免造成 `master 阻塞`
2 **資料緩衝區滿**, 此時將會丟棄最早的記錄(FIFO),如果全量複製的時間開銷過大,則可能在開增量複製時候已經存在資料丟失,這會導致Master 和 Slave 資料不一致,為了保證一致性,必須開始新一輪的全量複製,完成後緩衝區又被填滿並存在丟棄,則會讓Slave進入死迴圈。
因此資料緩衝區要設定的大小合適(依具體情況而定)。
```redis
repl-backlog-size 1mb # 預設的大小為 1MB
```
3 `master` 單機記憶體不應該佔用主機記憶體過多。一般的 50 ~ 70% 預留下 30% ~ 50%來進行`bgsave` 、 `建立複製緩衝區`、執行其他業務等。
#### 關於Slave注意
1 為避免`slave`進行全量複製、部分複製時伺服器響應阻塞或資料不同步,建議關閉此期間的對外服務。
```redis
slave-server-stale-data yes|no
```
2 資料同步階段,`master `傳送給 `slave` 資訊可以理解 `master `是 `slave` 的一個客戶端,主動向slave傳送命令。
3 多個`slave`同時對`master`請求資料同步,`master`傳送的`RDB`檔案增多,會對頻寬造成巨大沖擊,如果`master`寬頻不足,因此資料同步需要根據業務需求,適量錯峰。
4 `slave`過多時,應該對拓撲結構進行調整,由一主多從結構變為樹狀結構,中間結點即是master,也是slave。但是使用樹狀結構時,因為層級越深,資料同步時延越大,因此將強一致性的資料放在頂層節點,一致性稍弱的資料放在靠底層的節點。
## 命令傳播
當`master`資料庫狀態被修改後,導致主從伺服器資料庫狀態不一致,此時需要讓主從資料同步到一致的狀態,同步的動作成為命令傳播
`master`將接受到的資料變更命令傳送給`slave`,`slave`接受命令後執行命令。
網路閃斷閃連 忽略
短時間網路中斷 部分複製
長時間網路中斷 全量複製
### 伺服器執行ID(runid)
每臺伺服器每次執行都會產生的身份識別碼,同一個伺服器多次執行產生的`runid`是不一樣的。
形式:runid 由 40 個字元組成 一般是16進位制的字串
```redis
info server
run_id:409b6e9ea2e5c32958de8f365711598c98489f13
```
### 心跳機制
**master**
指令 **PING**
週期 `repl-ping-slave-period` 預設是 10s
作用 判斷 `slave` 是否線上
查詢 INFO replication 獲取最後一次 `slave` 連線時間間隔 lag = 0 / 1 屬於正常
**slave**
指令 **REPLCONF{offset}**
週期: 1s
作用1: 彙報自己的複製偏移量 獲取最新的資料變更指令
作用2: 判斷 `master` 是否存活
### 心跳注意事項
當 salve多數掉線 或者網路延時過高時,master 會拒絕所有的同步資訊。
```redis
min-slaves-to-write 2 # 最小的 slave 數量
min-slaves-max-lag 8 # 最長的
```
當 slave 的數量小於2 ,或者所有的時延都大於等於 8 時,會強 關閉 `master` 的血功能來停止資料同步。
Slave 的數量和延時由`REPLCONF{offset}` 命令確認。
## 完整的主從複製流程
![](https://img2020.cnblogs.com/blog/1440828/202006/1440828-20200613013359570-784519716.png)
### 讀寫分離
在redis主從架構中,Master節點負責處理寫請求,Slave節點只處理讀請求。對於寫請求少,讀請求多的場景,例如電商詳情頁,通過這種讀寫分離的操作可以大幅提高併發量,通過增加redis從節點的數量可以使得redis的QPS達到10W+。
### 負載均衡
基於主從結構,配合讀寫分離,由slave分擔master負載,並根據需求的變化,改變slave的數量,通過多個從節點分擔資料讀取負載,大大提高Redis伺服器併發量與資料吞吐量
### 故障恢復
當master出現問題時,由slave提供服務,實現快速的故障恢復
### 資料冗餘
實現資料熱備份,時持久化之外的一種資料冗餘方式
### 高可用基石
基於主從複製,構建哨兵模式與叢集,實現redis 的高可用