1.概述:
主從切換技術的方法是:當主服務器宕機后,需要手動把一台服務器切換為主服務器,這就需要人工干預,費時費力,還會造成一段時間內服務器不可用。這不是一種推薦方式,更多時候,我們優先考慮哨兵模式,Redis從2.8開始正式提供了Sentinel(哨兵)架構來解決這個問題。
謀朝篡位的自動版,能夠后台監控主機是否故障,如果故障了根據投票數自動將庫轉換為主庫(采取投票的模式)。
哨兵有兩個作用
-
通過發送命令,讓Redis服務器返回監控其運行狀態,包括主服務器和從服務器
-
當哨兵監測到master宕機,會自動將slave切換成master,然后通過發布訂閱模式通知其他的從服務器,修改配置文件,讓他們切換主機
然而一個哨兵進程對Redis服務器進行監控,可能會出現問題,為此,我們可以使用多個哨兵進行監控。各個哨兵之間還會進行監控,這樣就形成了多哨兵模式。
假設主服務器宕機,哨兵1先檢測到這個結果,系統並不會馬上進行failover過程,僅僅是哨兵1主觀的認為主服務器不可用,這個現象成為主觀下線。當后面的哨兵也檢測到主服務器不可用,並且數量達到一定值時,那么哨兵之間就會進行一次投票,投票的結果由一個哨兵發起,進行failover[故障轉移]操作。切換成功后,就會通過發布訂閱模式,讓各個哨兵把自己監控的從服務器實現切換主機,這個過程稱為客觀下線。
2.實際操作
這個就是哨兵
我們目前的狀態是一主二從
2.1 創建並配置一個哨兵conf
vim sentinel.conf
這句話代表 哨兵 監控 這個監控動作的名稱 主機號 端口號 1代表只要有一個哨兵認為主機掛了,主機就掛了 ,就會開始重新選舉主機
2.2 啟動哨兵
如果master結點斷開了,這個時候就會從從機中隨機選擇一個服務器,這里面有一個投票算法(就是比如這里79掛了,我們不需要做任何動作,哨兵會自動給我們選舉一個新的主機)
哨兵日志
優點:
-
哨兵模式,基於主從復制模式,所有主從配置的優點它都有
-
主從可以切換,故障可以轉移,系統的可用性就會更好
-
哨兵模式就是主從模式的升級,手動到自動,更加健壯
缺點:
-
Redis不好在線擴容,集群容量一旦達到上限,在線擴容就十分麻煩
-
實現哨兵模式的配置是非常麻煩的,里面有很多選擇
4.哨兵模式全部配置
# Example sentinel.conf # 哨兵sentinel實例運行的端口 默認26379,多個哨兵要配置多個哨兵端口,就是開啟多個conf port 26379 # 哨兵sentinel的工作目錄 dir /tmp # 哨兵sentinel監控的redis主節點的 ip port # master-name 可以自己命名的主節點名字 只能由字母A-z、數字0-9 、這三個字符".-_"組成。 # quorum 當這些quorum個數sentinel哨兵認為master主節點失聯 那么這時 客觀上認為主節點失聯了 # sentinel monitor <master-name> <ip> <redis-port> <quorum> sentinel monitor mymaster 127.0.0.1 6379 1 # 當在Redis實例中開啟了requirepass foobared 授權密碼 這樣所有連接Redis實例的客戶端都要提供密碼 # 設置哨兵sentinel 連接主從的密碼 注意必須為主從設置一樣的驗證密碼 # sentinel auth-pass <master-name> <password> sentinel auth-pass mymaster MySUPER--secret-0123passw0rd # 指定多少毫秒之后 主節點沒有應答哨兵sentinel 此時 哨兵主觀上認為主節點下線 默認30秒 # sentinel down-after-milliseconds <master-name> <milliseconds> sentinel down-after-milliseconds mymaster 30000 # 這個配置項指定了在發生failover主備切換時最多可以有多少個slave同時對新的master進行 同步, 這個數字越小,完成failover所需的時間就越長, 但是如果這個數字越大,就意味着越 多的slave因為replication而不可用。 可以通過將這個值設為 1 來保證每次只有一個slave 處於不能處理命令請求的狀態。 # sentinel parallel-syncs <master-name> <numslaves> sentinel parallel-syncs mymaster 1 # 故障轉移的超時時間 failover-timeout 可以用在以下這些方面: #1. 同一個sentinel對同一個master兩次failover之間的間隔時間。 #2. 當一個slave從一個錯誤的master那里同步數據開始計算時間。直到slave被糾正為向正確的master那里同步數據時。 #3.當想要取消一個正在進行的failover所需要的時間。 #4.當進行failover時,配置所有slaves指向新的master所需的最大時間。不過,即使過了這個超時,slaves依然會被正確配置為指向master,但是就不按parallel-syncs所配置的規則來了 # 默認三分鍾 # sentinel failover-timeout <master-name> <milliseconds> sentinel failover-timeout mymaster 180000 # SCRIPTS EXECUTION #配置當某一事件發生時所需要執行的腳本,可以通過腳本來通知管理員,例如當系統運行不正常時發郵件通知相關人員。 #對於腳本的運行結果有以下規則: #若腳本執行后返回1,那么該腳本稍后將會被再次執行,重復次數目前默認為10 #若腳本執行后返回2,或者比2更高的一個返回值,腳本將不會重復執行。 #如果腳本在執行過程中由於收到系統中斷信號被終止了,則同返回值為1時的行為相同。 #一個腳本的最大執行時間為60s,如果超過這個時間,腳本將會被一個SIGKILL信號終止,之后重新執行。 #通知型腳本:當sentinel有任何警告級別的事件發生時(比如說redis實例的主觀失效和客觀失效等等),將會去調用這個腳本, #這時這個腳本應該通過郵件,SMS等方式去通知系統管理員關於系統不正常運行的信息。調用該腳本時,將傳給腳本兩個參數, #一個是事件的類型, #一個是事件的描述。 #如果sentinel.conf配置文件中配置了這個腳本路徑,那么必須保證這個腳本存在於這個路徑,並且是可執行的,否則sentinel無法正常啟動成功。 #通知腳本 # sentinel notification-script <master-name> <script-path> sentinel notification-script mymaster /var/redis/notify.sh # 客戶端重新配置主節點參數腳本 # 當一個master由於failover而發生改變時,這個腳本將會被調用,通知相關的客戶端關於master地址已經發生改變的信息。 # 以下參數將會在調用腳本時傳給腳本: # <master-name> <role> <state> <from-ip> <from-port> <to-ip> <to-port> # 目前<state>總是“failover”, # <role>是“leader”或者“observer”中的一個。 # 參數 from-ip, from-port, to-ip, to-port是用來和舊的master和新的master(即舊的slave)通信的 # 這個腳本應該是通用的,能被多次調用,不是針對性的。 # sentinel client-reconfig-script <master-name> <script-path> sentinel client-reconfig-script mymaster /var/redis/reconfig.sh
不會詳細分析解決方案的底層(專題)
緩存穿透(查不到)
概念
緩存穿透的概念很簡單,用戶想要查詢一個數據,發現redis內存數據庫沒有,也就是緩存沒有命中,於是向持久層數據庫查詢。發現也沒有,於是本次查詢失敗。當用戶很多的時候,緩存都沒有命中(秒殺!),於是都去請求了持久層數據庫。這會給持久層數據庫造成很大的壓力,這時候就相當於出現了緩存穿透。
解決方案
布隆過濾器
布隆過濾器是一種數據結構,對所有可能查詢的參數以hash形式存儲,在控制層先進行校驗,不符合則丟棄,從而避免了對底層存儲系統的查詢壓力﹔
緩存空對象
當存儲層不命中后,即使返回的空對象也將其緩存起來,同時會設置一個過期時間,之后再訪問這個數據將會從緩存中獲取,保護了后端數據源;
但是這種方法會存在兩個問題: 1、如果空值能夠被緩存起來,這就意味着緩存需要更多的空間存儲更多的鍵,因為這當中可能會有很多的空值的鍵; 2、即使對空值設置了過期時間,還是會存在緩存層和存儲層的數據會有一段時間窗口的不一致,這對於需要保持一致性的業務會有影響。
緩存擊穿(查的太多,量大,緩存過期)
微博服務器宕機(60 60.1 0.1)
概述:
這里需要注意和緩存擊穿的區別,緩存擊穿,是指一個key非常熱點,在不停的扛着大並發,大並發集中對這一個點進行訪問,當這個key在失效的瞬間,持續的大並發就穿破緩存,直接請求數據庫,就像在一個屏障上鑿開了一個洞。 當某個key在過期的瞬間,有大量的請求並發訪問,這類數據一般是熱點數據,由於緩存過期,會同時訪問數據庫來查詢最新數據,並且回寫緩存,會導使數據庫瞬間壓力過大。
解決方案
設置熱點數據永不過期
從緩存層面來看,沒有設置過期時間,所以不會出現熱點key過期后產生的問題
加互斥鎖
分布式鎖:使用分布式鎖,保證對於每個key同時只有一個線程去查詢后端服務,其他線程沒有獲得分布式鎖的權限,因此只需要等待即可。這種方式將高並發的壓力轉移到了分布式鎖,因此對分布式鎖考驗很大
緩存雪崩
概念
緩存雪崩,是指在某一個時間段,緩存集中過期失效。Redis宕機 產生雪崩的原因之一,比如在寫本文的時候,馬上就要到雙十二零點,很快就會迎來一波搶購,這波商品時間比較集中的放入了緩存,假設緩存一個小時。那么到了凌晨一點鍾的時候,這批商品的緩存就都過期了。而對這批商品的訪問查詢,都落到了數據庫上,對於數據庫而言,就會產生周期性的壓力波峰。於是所有的請求都會達到存儲層,存儲層的調用量會暴增,造成存儲層也會掛掉的情況。
解決方案
Redis高可用
這個思想的含義是,既然redis有可能掛掉,那我多增設幾台redis,這樣一台掛掉之后其他的還可以繼續工作,其實就是搭建的集群。(異地多活)
限流降級(在SpringCloud中有)
這個解決方案的思想是,在緩存失效后,通過加鎖或者隊列來控制讀數據庫寫緩存的線程數量。比如對某個key只允許一個線程查詢數據和寫緩存,其他線程等待。
數據預熱
數據加熱的含義就是在正式部署之前,我先把可能的數據先預先訪問一遍,這樣部分可能大量訪問的數據就會加載到緩存中。在即將發生大並發訪問前手動觸發加載緩存不同的key,設置不同的過期時間,讓緩存失效的時間點盡量均勻