Redis 單機模式很簡單,相關測試水文看這裏html
Redis5 壓力測試結果反饋報告redis
必須的,今天接着寫水文,寫一寫如今redis 支持的三種集羣,主從模式,哨兵模式,Cluster模式,今天先搞主從模式算法
主從模式是最簡單的集羣模式,其實就是複製基本只能解決讀寫分離問題,主機服務器一旦宕機基本完蛋,不具有高可用。數據庫
基本上redis的性能瓶勁主要在於網絡IO和內存主頻上面,單機版Redis在不考慮高可用的狀況下基本知足80%的項目須要,由於單機版Redis能夠實現10W/S的請求,除非緩存K-V值過大,經過讀寫分離緩存網卡的壓力,不然這個併發處理能力能夠應對大部分項目。緩存
幾乎全部的主從模式都是從服務器只提供只讀不寫的功能,不然會出現數據不一致的狀況,如今不管那種數據庫都不支持雙向同步。服務器
屁話少說,上配置代碼,主服務器不須要配置,只需簡單一句代碼配置從服務器便可,聲明主服務器是誰,餘下的redis會自行交流。網絡
slaveof 192.168.3.143 6379
一主多從架構
主服務器:192.168.3.143 從服務器:192.168.3.144 從服務器:192.168.3.145 從服務器 redis.conf 配置文件加入 slaveof 192.168.3.143 6379
一主多從(鏈式結構),所謂鏈式結構就是能夠從服務器同步從服務器併發
主服務器:192.168.3.143 從服務器:192.168.3.144 從服務器:192.168.3.145 從服務器 redis.conf 配置文件加入 slaveof 192.168.3.143 6379
從服務器:192.168.3.147
從服務器 redis.conf 配置文件加入
slaveof 192.168.3.144 6379
嘗試一下程序上來實現讀寫分離,Net Core 使用StackExchange.Redis 進行訪問Redis集羣,其它組件本身研究吧框架
//聲明服務器地址,StackExchange會本身認別那個是主從關係 ConfigurationOptions option = new ConfigurationOptions(); option.EndPoints.Add("192.168.3.143", 6379); option.EndPoints.Add("192.168.3.144", 6379); option.EndPoints.Add("192.168.3.145", 6379); option.EndPoints.Add("192.168.3.147", 6379); ConnectionMultiplexer redis = ConnectionMultiplexer.Connect(option); IDatabase db = redis.GetDatabase(); db.StringSet("test", "testvalue", flags: CommandFlags.DemandMaster);//CommandFlags.DemandMaster 標明主服務器寫入 string value = db.StringGet("test", flags: CommandFlags.DemandReplica);//CommandFlags.DemandReplica 標明從服務器讀取 Console.WriteLine(value);
代碼行得通,己經分別從主/從服務器讀取到數據,接下來將是要測試,主服務器倒下來了,會是怎麼樣?如圖:成功報錯,恭喜某程序猿喜提系統異常一次
接下三張圖片將展現依次關閉從服務器:192.168.3.147,192.168.3.145 ,192.168.3.144 最後一張圖將意味着己關閉全部從服務器,全部從服務器己關閉,程序運行成功報錯
接着測試一下,StackExchange.Redis 框架問題,而對三個從服務器是否能分流從不一樣的從服務器取值,從而減輕從服務器的壓力
從監控的圖片來,三張從服務器的圖標顯示,StackExchange.Redis的確平均的分流的請求的流量。
哨兵模式基本就是主從模式的升級版,主要解決高可用問題,實現自動容錯和恢復。
簡單理解就是主從模式一旦主機服務器宕機須要人工處理,這樣一來你或者運維,得有一個睡不着,Redis引進哨兵模式的做用就是監控Redis服務是否正常運做,主服務器出現故障將自動將從服務器轉換爲主服務器。
理想狀態下的配置架構以下:哨兵監控主從服務器,哨兵之間相互監控,組成哨兵組推薦三個哨兵以上而且最好獨立部署,惟一能節省成本的好消息就是他們能夠監控多個主服務器。
工做原理:
注意:每一個哨兵配置不同,每一個哨兵根據本身的配置超時時間來判斷主服務器是否主觀下線只有符合就標爲主觀下線,每一個哨兵根據本身設定的「確定數量」來判斷主服務器是否客觀下線,只要有一個哨兵的配置達到客觀下線該哨兵就會執行故障遷移操做。
從服務器選舉原理:
配置:只須要配置主數據庫便可,哨兵會自動發現全部從數據庫並進行監控,哨兵之間能夠相互發現,只要確保端口放行就能夠了,簡單版配置簡單到只有一句話
sentinel monitor <master-group-name> <ip> <port> <quorum> sentinel monitor mymaster 127.0.0.1 6379 2 //示例 //監控一個叫作mymaster的主節點,地址是 127.0.0.1 端口號是6379,判斷客觀下線須要2個哨兵「確定」 //固然還有一些其它較爲重要的配置,能夠手動設定 sentinel down-after-milliseconds mymaster 60000 //設定檢查超時時間,超過這個時間將認定爲主觀下線,默認30秒
下面進一些場景測試以驗證觀點,雖然支持採用默認配置的方式來進行啓動,咱們仍是使用配置文件的方式進行啓動
//主服務器 bind 0.0.0.0 port 6379 daemonize yes //從服務器 bind 0.0.0.0 port 6379 daemonize yes slaveof 192.168.3.40 6379
測試場景一:簡單版測試,一主一從一哨兵,主服務器故障,可否自動將從服務器轉換爲主服務器
sentinel monitor mymaster 192.168.3.40 6379 1 sentinel down-after-milliseconds mymaster 5000//內網配置五秒就足夠了 daemonize yes
成功運行
編寫檢查代碼
class Program { static void Main(string[] args) { //聲明服務器地址,StackExchange會本身認別那個是主從關係 ConfigurationOptions option = new ConfigurationOptions(); option.EndPoints.Add("192.168.3.40", 6379); option.EndPoints.Add("192.168.3.167", 6379); ConnectionMultiplexer redis = ConnectionMultiplexer.Connect(option); IDatabase db = redis.GetDatabase(); db.StringSet("test", "testvalue"); DateTime exStartTime = DateTime.Now; DateTime exEndTime; bool isEX = false; while (true) { try { var value = db.StringGet("test"); Console.WriteLine(value); if (!value.HasValue && isEX!) Console.WriteLine(value); if (isEX && value.HasValue == true) { exEndTime = DateTime.Now; Console.WriteLine($"鏈接成功,獲取的值是:{value}"); break; } } catch (Exception e) { if (isEX == false) { Console.WriteLine($"鏈接失敗!{e.Message}"); exStartTime = DateTime.Now; isEX = true; } } } Console.WriteLine($"鏈接異常時間{exStartTime},故障遷移成功時間{exEndTime},花費{(exEndTime - exStartTime).TotalSeconds}秒"); } }
悄悄打開ESXI 把虛擬機的網線拔掉
果真成功報錯,而且進行故障轉移
這個時候,從新把網絡設置回來,而且查看兩個redis.conf的配置文件內容,發現配置己被改動,192.168.3.40 己由主服務器轉變成從服務器,哨兵的配置也相應做了改變
測試場景二:一主三從一哨兵
//主服務器(192.168.3.40) bind 0.0.0.0 port 6379 daemonize yes //從服務器(192.168.3.167) bind 0.0.0.0 port 6379 daemonize yes slaveof 192.168.3.40 6379 //從服務器(192.168.3.168) bind 0.0.0.0 port 6379 daemonize yes slaveof 192.168.3.40 6379 //從服務器(192.168.3.169) bind 0.0.0.0 port 6379 daemonize yes slaveof 192.168.3.40 6379
哨兵的配置依舊不變
//哨兵服務器(192.168.3.171) sentinel monitor mymaster 192.168.3.40 6379 1 sentinel down-after-milliseconds mymaster 5000//內網配置五秒就足夠了 daemonize yes
一頓操做猛如虎,斷掉網絡
成功切換,看看這四臺服務器的配置都發現了什麼變化吧
測試場景三:一主三從三哨兵
主從服務器的配置不變,哨兵的配置稍有變化,哨兵的服務器由一臺增長到三臺,分別是192.168.3.171,192.168.3.172,192.168.3.170,哨兵能相互發現和相互監控
sentinel monitor mymaster 192.168.3.40 6379 2 //裁仲服務器由1臺變成2臺 sentinel down-after-milliseconds mymaster 5000//內網配置五秒就足夠了 daemonize yes
好了,準備就緒,故技重演,斷網
查看一下四臺Redis服務器配置發生什麼變化
查看一下,三臺哨兵的配置發生什麼變化
就測到這裏吧,下班了,明天大夥要是有興趣,再搗鼓一下,Cluster模式,就是分佈式集羣,不知道有沒有人看這些水文