Redis5.0 主從模式和高可用 搭建和測試報告

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服務是否正常運做,主服務器出現故障將自動將從服務器轉換爲主服務器。

理想狀態下的配置架構以下:哨兵監控主從服務器,哨兵之間相互監控,組成哨兵組推薦三個哨兵以上而且最好獨立部署,惟一能節省成本的好消息就是他們能夠監控多個主服務器。

工做原理:

  1. 每一個哨兵都會監控主/從服務器及其它哨兵。
  2. 當有一個哨兵檢查主服務器下線(沒有規定時間回覆ping請求),會將主服務器標識爲主觀下線
  3. 當主服務器被標爲主觀下線,其它哨兵會立刻檢查主服務在線狀態。
  4. 當足夠的哨兵(超過配置數量)將它標識爲主觀下線,主服務器會變成客觀下線,若是數量不夠則主觀下線狀態會除移。
  5. 主服務器客觀下線以後哨兵會從「從服務器」中選中一臺服務器當主服務器。
  6. 哨兵將修改其它從服務器以及被修復舊主服務器的配置,將統一修改成從服務器而且修改它們的主服務器地址。

注意:每一個哨兵配置不同,每一個哨兵根據本身的配置超時時間來判斷主服務器是否主觀下線只有符合就標爲主觀下線,每一個哨兵根據本身設定的「確定數量」來判斷主服務器是否客觀下線,只要有一個哨兵的配置達到客觀下線該哨兵就會執行故障遷移操做。

從服務器選舉原理:

  1. 首先發現客觀下線的哨兵會發起一個選舉請求,根據Raft算法,通常會成爲領頭哨頭。
  2. 根據與主服務器的斷開的時間判斷
  3. 根據從服務器配置文件的權重(slave-priority)選舉爲主服務器
  4. 複製偏移,從主節點收到更多的新數據的節點會被選擇
  5. 在全部條件相同的狀況,選擇runid最小的爲主服務器

配置:只須要配置主數據庫便可,哨兵會自動發現全部從數據庫並進行監控,哨兵之間能夠相互發現,只要確保端口放行就能夠了,簡單版配置簡單到只有一句話

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模式,就是分佈式集羣,不知道有沒有人看這些水文

相關文章
相關標籤/搜索