# redis-主從復制和高可用
[TOC]
## 一、 主從復制
### 1. 主從復制簡介
redis的主從復制,使用的是異步復制,主服務器可以有多個從服務器,從服務器也可以再接從服務器。復制功能不會阻塞主服務器,如果在配置文件redis.conf中進行相應的設置,復制功能也不會阻塞從服務器。在從服務器刪除舊版本數據集并載入新版本數據集的那段時間內,連接請求會被阻塞。
復制功能可以單純地用于數據冗余,也可以通過讓多個從服務器處理只讀命令請求來做到讀寫分離。
可以通過復制功能來讓主服務器免于執行持久化操作:只要關閉主服務器的持久化功能,然后由從服務器去執行持久化操作即可。
### 2. 主從復制的安全性
當配置Redis復制功能時,強烈建議打開主服務器的持久化功能。否則的話要避免主服務器宕機后被自動拉起。
考一下以下會導致主從服務器數據全部丟失的例子:
1. 假設節點A為主服務器,并且關閉了持久化。并且節點B和節點C從節點A復制數據
2. 節點A崩潰,然后由自動拉起服務重啟了節點A.由于節點A的持久化被關閉了,所以重啟之后沒有任何數據
3. 節點B和節點C將從節點A復制數據,但是A的數據是空的,于是就把自身保存的數據副本刪除。
無論何時,數據安全都是極其重要的,所以應該禁止主服務器關閉持久化的同時自動拉起。
### 3. 主從復制的原理
1) 圖片說明


2) 文件說明
1. 第一步:無論是初次連接還是重新連接,當建立一個從服務器時,從服務器都將向主服務器發送一個SYNC命令。
2. 第二步:接到SYNC命令的主服務器將開始執行BGSAVE創建rdb文件,并在保存操作執行期間,將所有新執行的寫入命令都保存到一個緩沖區里面。
3. 第三步:當BGSAVE執行完畢后,主服務器將執行保存操作所得的.rdb文件發送給從服務器,從服務器接收這個.rdb文件,并將文件中的數據載入到內存中。
4. 第四步:之后主服務器會以Redis命令協議的格式,將寫命令緩沖區中積累的所有內容都發送給從服務器。
3) 多從和重連
即使有多個從服務器同時向主服務器發送SYNC,主服務器也只需執行一次BGSAVE命令,就可以處理所有這些從服務器的同步請求。
從服務器可以在主從服務器之間的連接斷開時進行自動重連,從服務器可以根據主服務器的情況來選擇執行完整重同步[2.8以前]還是部分重同步[2.8以后]
### 4. 主從數據一致性保證
```sh
min-slaves-to-write 1
min-slaves-max-lag 2
```
* 運作原理:
從服務器以每秒一次的頻率 PING 主服務器一次, 并報告復制流的處理情況。主服務器會記錄各個從服務器最后一次向它發送 PING 的時間。
用戶可以通過配置, 指定網絡延遲的最大值 min-slaves-max-lag ,以及執行寫操作所需的至少從服務器數量 min-slaves-to-write 。
如果至少有 min-slaves-to-write 個從服務器,并且這些服務器的延遲值都少于 min-slaves-max-lag秒,那么主服務器就會執行客戶端請求的寫操作。
可以將這個特性看作 CAP 理論中的 C 的條件放寬版本: 盡管不能保證寫操作的持久性,但起碼丟失數據的窗口會被嚴格限制在指定的秒數中。
另一方面, 如果條件達不到 min-slaves-to-write 和 min-slaves-max-lag 所指定的條件,那么寫操作就不會被執行,主服務器會向請求執行寫操作的客戶端返回一個錯誤。
### 5. 主從復制的實現
準備兩個或兩個以上redis實例
```sh
mkdir /data/redis_m/638{0..2}
```
1) 配置文件示例
6380
```sh
cat >/data/redis_m/6380/redis.conf <<'EOF'
port 6380
daemonize yes
pidfile /data/redis_m/6380/redis.pid
loglevel notice
logfile "/data/redis_m/6380/redis.log"
dbfilename dump.rdb
dir /data/redis_m/6380
protected-mode no
EOF
```
6381
```sh
cat >/data/redis_m/6381/redis.conf <<'EOF'
port 6381
daemonize yes
pidfile /data/redis_m/6381/redis.pid
loglevel notice
logfile "/data/redis_m/6381/redis.log"
dbfilename dump.rdb
dir /data/redis_m/6381
protected-mode no
EOF
```
6382
```
cat >/data/redis_m/6382/redis.conf <<'EOF'
port 6382
daemonize yes
pidfile /data/redis_m/6382/redis.pid
loglevel notice
logfile "/data/redis_m/6382/redis.log"
dbfilename dump.rdb
dir /data/redis_m/6382
protected-mode no
EOF
```
2) 啟動
```sh
redis-server /data/redis_m/6380/redis.conf
redis-server /data/redis_m/6381/redis.conf
redis-server /data/redis_m/6382/redis.conf
```
3) 開啟主從
redis主從只需要在從節點設置主庫信息即可
6381
```sh
redis-cli -p 6381
SLAVEOF 127.0.0.1 6380
```
6382
```sh
redis-cli -p 6382
SLAVEOF 127.0.0.1 6380
```
4) 主從狀態查詢
```sh
127.0.0.1:6382> info replication
```
### 6. 手動切換主從
1) 模擬主庫故障
```sh
redis-cli -p 6380
shutdown
```
2) 啟用6381為主
```sh
redis-cli -p 6381
info replication
slaveof no one
```
3) 6382連接新主
```sh
redis-cli -p 6382
127.0.0.1:6382> SLAVEOF no one
127.0.0.1:6382> SLAVEOF 127.0.0.1 6381
```
## 二、redis高可用[redis-sentinel哨兵]
### 1. redis-sentinel簡介
Redis-Sentinel是Redis官方推薦的高可用性(HA)解決方案,當用Redis做Master-slave的高可用方案時,假如master宕機了,Redis本身(包括它的很多客戶端)都沒有實現自動進行主備切換,而Redis-sentinel本身也是一個獨立運行的進程,它能監控多個master-slave集群,發現master宕機后能進行自動切換。
### 2. 主要功能
1. 監控(Monitoring):
Sentinel 會不斷地檢查你的主服務器和從服務器是否運作正常。
2. 提醒(Notification):
當被監控的某個 Redis 服務器出現問題時, Sentinel 可以通過 API 向管理員或者其他應用程序發送3. 自動故障遷移(Automatic failover):
當一個主服務器不能正常工作時, Sentinel 會開始一次自動故障遷移操作, 它會將失效主服務器的其中一個從服務器升級為新的主服務器, 并讓失效主服務器的其他從服務器改為復制新的主服務器; 當客戶端試圖連接失效的主服務器時, 集群也會向客戶端返回新主服務器的地址, 使得集群可以使用新主服務器代替失效服務器。
### 3. 實現原理
1. 發現主服務器
Sentinel 通過用戶給定的配置文件來發現主服務器,并與主服務器創建連個網絡連接,命令連接用于向主服務器發送命令,訂閱連接用于訂閱指定的頻道.
2. 發現從服務
Sentinel 通過向主服務器發送 INFO 命令來自動獲得所有從服務器的地址,并與每個被發現的從服務器創建命令連接和訂閱連接。
3. 發現其他serntinel
Sentinel 會通過命令連接向被監視的主從服務器發送 “HELLO” 信息[IP、端口號、ID 等],以此來向其他 Sentinel 宣告自己的存在。并通過訂閱連接接收其他 Sentinel 的“HELLO” 信息,以此來發現監視同一個主服務器的其他 Sentinel
Sentinel 之間只會互相創建命令連接,用于進行通信。因為已經有主從服務器作為發送和接收 HELLO 信息的中介,所以 Sentinel之間不會創建訂閱連接
4. 檢測實例狀態
Sentinel 使用 PING 命令來檢測實例的狀態:如果實例在指定的時間內沒有返回回復,或者返回錯誤的回復,那么該實例會被 Sentinel 判斷為主觀下線。
如果多個sentinel交流后判斷這個服務器下線了,這個時候才是真正的下線,也叫客觀下線.所以生成環境一般使用的是奇數個sentinel,實例被多數哨兵認為判斷才會真的下線
### 4. 故障轉移步驟
* 發現主服務器已經進入客觀下線狀態。
* 基于Raft leader election協議 ,進行投票選舉
如果選舉失敗,那么在設定的故障遷移超時時間的兩倍之后,重新嘗試選舉。 如果選舉成功, 那么執行以下步驟。
* 選出一個從服務器,并將它升級為主服務器。
* 向被選中的從服務器發送 SLAVEOF NO ONE 命令,讓它轉變為主服務器。
* 通過發布與訂閱功能, 將更新后的配置傳播給所有其他 Sentinel ,其他 Sentinel 對它們自己的配置進行更新。
* 向已下線主服務器的從服務器發送 SLAVEOF 命令,讓它們去復制新的主服務器。
* 當所有從服務器都已經開始復制新的主服務器時, leader Sentinel 終止這次故障遷移操作。
### 5. 高可用哨兵搭建
這里只安裝一個哨兵,但實際環境中,一般都會用到3個哨兵共同協作,防止腦裂和單機網絡故障導致切換
1) 創建目錄
```sh
mkdir /data/redis_m/26380
cd /data/redis_m/26380
```
2) 創建配置文件
```sh
cat >>sentinel.conf <<'EOF'
port 26380
dir "/data/redis_m/26380"
sentinel monitor mymaster 127.0.0.1 6380 1
sentinel down-after-milliseconds mymaster 5000
sentinel config-epoch mymaster 0
EOF
```
3) 啟動哨兵
```sh
redis-sentinel /data/redis_m/26380/sentinel.conf &
```
4) 故障轉移演練
```sh
# 停主庫測試:
[root@db01 ~]# redis-cli -p 6380
shutdown
# 查看新主庫信息
[root@db01 ~]# redis-cli -p 6381
info replication
# 啟動源主庫[6380]看狀態。
原主庫會自動被加入到主從環境做從庫
```
### 6. 參數解釋和常用命令
1)配置文件參數
```
sh
# 指定監控master
sentinel monitor mymaster 127.0.0.1 6370 2
{2表示多少個sentinel同意}
# 安全信息
sentinel auth-pass mymaster root
# 超過多久后認為主機宕機
sentinel down-after-milliseconds mymaster 15000
# 當主從切換多久后認為主從切換失敗
sentinel failover-timeout mymaster 900000
# 同時最多2個slave可更新配置
sentinel leader-epoch mymaster 2
# 確認mymater SDOWN時長
sentinel config-epoch mymaster 1
```
2)sentinel命令
```sh
PING
# 返回 PONG 。
SENTINEL masters
# 列出所有被監視的主服務器
SENTINEL slaves <master name>
# 列出指定從庫
SENTINEL get-master-addr-by-name <master name>
# 返回給定名字的主服務器的 IP 地址和端口號。
SENTINEL reset <pattern>
# 重置所有名字和給定模式 pattern 相匹配的主服務器。
SENTINEL failover <master name>
# 當主服務器失效時,在不詢問其他 Sentinel 意見的情況下, 強制開始一次自動故障遷移。
```
- shell編程
- 變量1-規范-環境變量-普通變量
- 變量2-位置-狀態-特殊變量
- 變量3-變量子串
- 變量4-變量賦值三種方法
- 變量5-數組相關
- 計算1-數值計算命令和案例
- 計算2-expr命令舉例
- 計算3-條件表達式和各種操作符
- 計算4-條件表達式和操作符案例
- 循環1-函數的概念與作用
- 循環2-if與case語法
- 循環3-while語法
- 循環4-for循環
- 其他1-判斷傳入的參數為0或整數的多種思路
- 其他2-while+read按行讀取文件
- 其他3-給輸出內容加顏色
- 其他4-shell腳本后臺運行知識
- 其他5-6種產生隨機數的方法
- 其他6-break,continue,exit,return區別
- if語法案例
- case語法案例
- 函數語法案例
- WEB服務軟件
- nginx相關
- 01-簡介與對比
- 02-日志說明
- 03-配置文件和虛擬主機
- 04-location模塊和訪問控制
- 05-status狀態模塊
- 06-rewrite重寫模塊
- 07-負載均衡和反向代理
- 08-反向代理監控虛擬IP地址
- nginx與https自簽發證書
- php-nginx-mysql聯動
- Nginx編譯安裝[1.12.2]
- 案例
- 不同客戶端顯示不同信息
- 上傳和訪問資源池分離
- 配置文件
- nginx轉發解決跨域問題
- 反向代理典型配置
- php相關
- C6編譯安裝php.5.5.32
- C7編譯php5
- C6/7yum安裝PHP指定版本
- tomcxat相關
- 01-jkd與tomcat部署
- 02-目錄-日志-配置文件介紹
- 03-tomcat配置文件詳解
- 04-tomcat多實例和集群
- 05-tomcat監控和調優
- 06-Tomcat安全管理規范
- show-busy-java-threads腳本
- LVS與keepalived
- keepalived
- keepalived介紹和部署
- keepalived腦裂控制
- keepalived與nginx聯動-監控
- keepalived與nginx聯動-雙主
- LVS負載均衡
- 01-LVS相關概念
- 02-LVS部署實踐-ipvsadm
- 03-LVS+keepalived部署實踐
- 04-LVS的一些問題和思路
- mysql數據庫
- 配置和腳本
- 5.6基礎my.cnf
- 5.7基礎my.cnf
- 多種安裝方式
- 詳細用法和命令
- 高可用和讀寫分離
- 優化和壓測
- docker與k8s
- docker容器技術
- 1-容器和docker基礎知識
- 2-docker軟件部署
- 3-docker基礎操作命令
- 4-數據的持久化和共享互連
- 5-docker鏡像構建
- 6-docker鏡像倉庫和標簽tag
- 7-docker容器的網絡通信
- 9-企業級私有倉庫harbor
- docker單機編排技術
- 1-docker-compose快速入門
- 2-compose命令和yaml模板
- 3-docker-compose命令
- 4-compose/stack/swarm集群
- 5-命令補全和資源限制
- k8s容器編排工具
- mvn的dockerfile打包插件
- openstack與KVM
- kvm虛擬化
- 1-KVM基礎與快速部署
- 2-KVM日常管理命令
- 3-磁盤格式-快照和克隆
- 4-橋接網絡-熱添加與熱遷移
- openstack云平臺
- 1-openstack基礎知識
- 2-搭建環境準備
- 3-keystone認證服務部署
- 4-glance鏡像服務部署
- 5-nova計算服務部署
- 6-neutron網絡服務部署
- 7-horizon儀表盤服務部署
- 8-啟動openstack實例
- 9-添加計算節點流程
- 10-遷移glance鏡像服務
- 11-cinder塊存儲服務部署
- 12-cinder服務支持NFS存儲
- 13-新增一個網絡類型
- 14-云主機冷遷移前提設置
- 15-VXALN網絡類型配置
- 未分類雜項
- 部署環境準備
- 監控
- https證書
- python3.6編譯安裝
- 編譯安裝curl[7.59.0]
- 修改Redhat7默認yum源為阿里云
- 升級glibc至2.17
- rabbitmq安裝和啟動
- rabbitmq多實例部署[命令方式]
- mysql5.6基礎my.cnf
- centos6[upstart]/7[systemd]創建守護進程
- Java啟動參數詳解
- 權限控制方案
- app發包倉庫
- 版本發布流程
- elk日志系統
- rsyslog日志統一收集系統
- ELK系統介紹及YUM源
- 快速安裝部署ELK
- Filebeat模塊講解
- logstash的in/output模塊
- logstash的filter模塊
- Elasticsearch相關操作
- ES6.X集群及head插件
- elk收集nginx日志(json格式)
- kibana說明-漢化-安全
- ES安裝IK分詞器
- zabbix監控
- zabbix自動注冊模板實現監控項自動注冊
- hadoop大數據集群
- hadoop部署
- https證書
- certbot網站
- jenkins與CI/CD
- 01-Jenkins部署和初始化
- 02-Jenkins三種插件安裝方式
- 03-Jenkins目錄說明和備份
- 04-git與gitlab項目準備
- 05-構建自由風格項目和相關知識
- 06-構建html靜態網頁項目
- 07-gitlab自動觸發項目構建
- 08-pipelinel流水線構建項目
- 09-用maven構建java項目
- iptables
- 01-知識概念
- 02-常規命令實戰
- 03-企業應用模板
- 04-企業應用模板[1鍵腳本]
- 05-企業案例-共享上網和端口映射
- SSH與VPN
- 常用VPN
- VPN概念和常用軟件
- VPN之PPTP部署[6.x][7.x]
- 使用docker部署softether vpn
- softEther-vpn靜態路由表推送
- SSH服務
- SSH介紹和部署
- SSH批量分發腳本
- 開啟sftp日志并限制sftp訪問目錄
- sftp賬號權限分離-開發平臺
- ssh配置文件最佳實踐
- git-github-gitlab
- git安裝部署
- git詳細用法
- github使用說明
- gitlab部署和使用
- 緩存數據庫
- zookeeper草稿
- mongodb數據庫系列
- mongodb基本使用
- mongodb常用命令
- MongoDB配置文件詳解
- mongodb用戶認證管理
- mongodb備份與恢復
- mongodb復制集群
- mongodb分片集群
- docker部署mongodb
- memcached
- memcached基本概念
- memcached部署[6.x][7.x]
- memcached參數和命令
- memcached狀態和監控
- 會話共享和集群-優化-持久化
- memcached客戶端-web端
- PHP測試代碼
- redis
- 1安裝和使用
- 2持久化-事務-鎖
- 3數據類型和發布訂閱
- 4主從復制和高可用
- 5redis集群
- 6工具-安全-pythonl連接
- redis配置文件詳解
- 磁盤管理和存儲
- Glusterfs分布式存儲
- GlusterFS 4.1 版本選擇和部署
- Glusterfs常用命令整理
- GlusterFS 4.1 深入使用
- NFS文件存儲
- NFS操作和部署
- NFS文件系統-掛載和優化
- sersync與inotify
- rsync同步服務
- rsyncd.conf
- rsync操作和部署文檔
- rsync常見錯誤處理
- inotify+sersync同步服務
- inotify安裝部署
- inotify最佳腳本
- sersync安裝部署
- 時間服務ntp和chrony
- 時間服務器部署
- 修改utc時間為cst時間
- 批量操作與自動化
- cobbler與kickstart
- KS+COBBLER文件
- cobbler部署[7.x]
- kickstart部署[7.x]
- kickstar-KS文件和語法解析
- kickstart-PXE配置文件解析
- 自動化之ansible
- ansible部署和實踐
- ansible劇本編寫規范
- 配置文件示例
- 內網DNS服務
- 壓力測試
- 壓測工具-qpefr測試帶寬和延時