日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

redis 主从 哨兵 集群 及原理

發(fā)布時間:2023/12/20 编程问答 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 redis 主从 哨兵 集群 及原理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1.主從哨兵

1.主從哨兵架構圖:

此圖為最常見的一主兩從結構,一個master主機,兩個slave主機。每臺主機上都運行著兩個進程:

  • redis-server 服務,處理redis正常的數據操作與響應。master服務可讀寫,slave服務為只讀,當master服務接受到數據修改或寫入的命令時,會異步將命令發(fā)送到slave上,以此保持master與slave上數據的一致性。
  • redis-sentinel 哨兵服務,此服務會監(jiān)控master和slave服務是否正常運行,當超過半數的哨兵認定master服務掛掉時,會進行選舉,將slave服務選舉設置為master服務,并恢復集群訪問,當舊master節(jié)點恢復正常后,可以作為新的slave節(jié)點重新加入集群。
  • ?

    主從哨兵集群的優(yōu)缺點:

    • 優(yōu)點:實現了數據備份,讀負載均衡,自動化故障恢復,高可用。
    • 缺點:沒有伸縮性,數據存儲的限制受到單機內存大小的限制,沒發(fā)通過增加主機來增加存儲空間。

    所以,此主從哨兵在中小系統(tǒng)中廣受使用,因為其簡單好用的特性,在數據量不大的情況下,可以很好的提供服務,但是隨著互聯(lián)網企業(yè)的不斷發(fā)展,數據量越來越大,單機存儲已經無法滿足需求,于是redis官方至3.0版本后推出了新一代的集群方案,redis cluster分布式集群,此集群則在高可用的基礎上,解決了伸縮性的問題。

    2.環(huán)境搭建:

    由于哨兵的高可用和確保不是因為哨兵故障導致的master狀態(tài)誤判,所以集群的數量為單數最好,最低集群配置則為1主兩從,3哨兵。

    即需要3臺服務器,每臺服務器上運行一個redis-server,一個redis-sentinel

    1.master配置

    # 允許任意用戶連接 bind 0.0.0.0 # 關閉保護模式 protected-mode no # 開啟守護進程 daemonize yes # 如果是作為緩存服務器,需要注釋掉三個數據持久化的選項 # save 900 1 # save 300 10 # save 60 10000 # 設置redis密碼,如果要設置密碼,則主從的密碼要統(tǒng)一一致,這樣在故障時切換master才能正常連接,如果不設密碼則都不設密碼 requirepass 123456 # 設置最大內存限制,避免內存過大造成服務器宕機 maxmemory 2gb

    2.salve配置

    # 允許任意用戶連接 bind 0.0.0.0 # 關閉保護模式 protected-mode no # 開啟守護進程 daemonize yes # 如果是作為緩存服務器,需要注釋掉三個數據持久化的選項 # save 900 1 # save 300 10 # save 60 10000 # 設置redis密碼,如果要設置密碼,則主從的密碼要統(tǒng)一一致,這樣在故障時切換master才能正常連接,如果不設密碼則都不設密碼 requirepass 123456 # 設置最大內存限制,避免內存過大造成服務器宕機 maxmemory 2gb # 指定matser機的IP和端口 slaveof 192.168.0.1 6379 # master上redis的密碼,如果沒有設置密碼則不需要配置 masterauth 123456

    3.哨兵配置

    修改sentinel.conf

    # 設為后臺啟動 daemonize yes # 設置log文件路徑,方便出故障時進行排查 logfile "/var/log/redis/sentinel.log" # 關閉保護模式 protected-mode no # 設置監(jiān)控master主機,只需要配置上master的ip和端口 # 后面的2,表示有兩臺或以上哨兵認定master掛掉了,則認為master掛掉,進行選舉切換master sentinel monitor mymaster 192.168.0.1 6379 2 # 指定master和slave的統(tǒng)一密碼 sentinel auth-pass mymaster 123456

    3.實現原理

    1)主從 master-slave

    redis主從模式(master-slave,為保政治正確,已改名master-replica),提供了除持久化外另一種數據的熱備功能,也為讀寫分離提供了途徑;

    redis主從模式通過復制功能實現,redis提供了SLAVEOF(REPLICAOF),讓一個服務器(slave)去復制另一個服務器(master);

    復制功能的開啟: 通過客戶端向服務器發(fā)送指令:slaveof(replicaof) host port?,或者在slave配置文件中配置?replicaof選項;

    注:?slaveof(replicaof) host port?是異步命令,當服務器收到該命令后,會先將host/port保存到服務器狀態(tài)(redisServer)的masterhost及masterport屬性里,然后回復 OK,再開始執(zhí)行真正的復制操作;

    redis的復制功能的實現,包括?同步(SYNC/PSYNC)?和?命令傳播(command propagate)?兩個操作:

  • 在剛開啟主從同步功能或者斷線重連時,使用同步命令讓slave的數據狀態(tài)跟master保持一致;
  • 同步后,若master執(zhí)行寫命令,狀態(tài)又將不一致,通過命令傳播讓slave執(zhí)行同樣的命令,使狀態(tài)保持一致;
  • 同步

  • SYNC命令:redis2.8之前使用,slave向master發(fā)送sync命令,master會執(zhí)行bgsave命令生成rdb文件,然后把rdb文件發(fā)送給slave,slave通過rdb恢復數據,達到與master一致的狀態(tài);
  • PSYNC命令:因為SYNC命令只能執(zhí)行全量同步,對于slave斷線重連后只需要執(zhí)行部分重同步就可以達到一致的情況,仍使用SYNC命令有很大的浪費,因為在redis2.8中,提供了?PSYNC?命令來取代?SYNC?命令
  • PSYNC

    PSYNC提供了全量同步和部分同步兩種模式,全量同步跟?SYNC?命令類似

    • 為實現數據的部分重同步,redis使用了一些定義
      • ?復制偏移量:master和slave都會維護一個復制偏移量
        • master 每發(fā)送一個字節(jié),將偏移量+1
        • slave 每收到一個字節(jié),將偏移量+1
      • 復制積壓緩沖區(qū)
        • master維護的一個?固定長度?的FIFO隊列,默認1M;存放了一部分最近傳播的寫命令,并且為每個字節(jié)記錄了相應的復制偏移量;
      • 服務器支行ID: 每個redis服務器,不論主從,都有自己的支行ID,在啟動服務時生成,由40個隨機的16進制字符串組成?
    • 有了以上三個定義,就可以實現部分同步功能了:
      • slave 向 master 發(fā)送命令?PSYNC <runid> <offset>,其中 runid 表示上次復制的 master 的運行ID,offset 則是slave保存的復制偏移量;如果是第一次同步,則用??和?-1表示:PSYNC ? -1;
      • master 收到命令后,查檢是第首次同步、收到的runid是否是自身的runid、根據偏移量檢查缺失的數據是否全部在復制積壓緩沖區(qū)中,然后會回復:
        • +FULLRESYNC <runid> <offset>?表示將執(zhí)行全量同步;
        • +CONTINUE?表示將執(zhí)行增量同步,slave 只需等待 master 繼續(xù)將增量數據發(fā)過來即可;注:當runid相同且缺失和數據都仍在復制積壓緩沖區(qū)時才會執(zhí)行部分同步;
        • -ERR?表示 master 版本低于2.8,不能識別?PSYNC命令;

    心跳檢測

    在命令傳播階段,slave 會定時向 master 發(fā)送心跳信息,默認每秒一次,命令格式:?REPLCONF ACK <offset>

    作用

  • 檢測網絡通信狀態(tài);
  • 輔助實現 min-slave 選項;
  • 檢測命令丟失: 心跳信息會帶有slave的offset,master收到心跳后,可以與自己保存的offset對比,大與收到的offset,說明有命令傳播失敗;
  • 步驟

  • slave 收到?SLAVEOF <host> <port>命令,設置 master 的地址端口信息,然后回復OK;
  • 向 master 建立套接字連接;
  • 發(fā)送 PING 命令;
  • 身份驗證,如果 slave 有?masterauth?配置;
  • slave 發(fā)送自身端口信息;
  • 進行同步;
  • 命令傳播;
  • 注:master 和 slave 需要互為對方的客戶端,因為彼此都要向對方發(fā)送命令;

    2)哨兵 Sentinel

    master-slave方案解決了數據的復制問題,但是 當 master 宕機時,slave 并不會自動切換為新的 master,以繼續(xù)提供服務,于是,Sentinel System 有了用武之地;

    由一個或多個 Sentinel 實例組成的 Sentinel System,可以監(jiān)視任意多個 master 及其 slave,并行使以下職責:

  • 監(jiān)視各服務器運行狀態(tài);
  • 發(fā)現異常進行通知;
  • master 下線后從其 slave 中選舉新 master,進行故障轉移;
  • 下線的 master 上線后,將其降級成新 master 的 slave;
  • 先進行哨兵功能的總結

  • 每個 Sentinel 可監(jiān)視任意多個服務器,每個服務器也可被任意多個 Sentinel 監(jiān)視;
  • 多個監(jiān)視同一主服務器的 Sentinel 視為一個集群,在被監(jiān)視主服務器下線后,該集群將選舉出一個 Sentinel Leader,由該 leader 對其進行故障轉移;
  • 故障轉移

  • 選舉?Sentinel leader,用于執(zhí)行故障轉移;
  • 由?Sentinel leader?從故障主服務器的所有從服務器中選一個做新的主服務器;
  • 向選出的新 master 發(fā)送?slaveof no one命令,然后一次次的發(fā)送INFO命令查看服務器的role角色,當變成 master 說明升級成功;
  • 向其它slave服務器發(fā)送slaveof命令,讓它們復制新的服務器;
  • 若下線的主服務器上線,則發(fā)送slaveof命令,讓其降級為從服務器,復制新的主服務器;
  • Sentinel節(jié)點感知

  • Sentinel 會向被監(jiān)視服務器發(fā)起兩條連接,一條命令連接,一條訂閱連接;
  • 建立訂閱頻道后,會在被監(jiān)視服務器上訂閱?—sentinel—:hello頻道,并以?2S?一次的頻率,向該頻道發(fā)送消息,以向其它監(jiān)視該服務器的Sentinel宣示自己的存在;
  • Sentinel 通過接收訂閱消息并分析,獲知與自己監(jiān)視同一服務器的其它 Sentinel,并在被監(jiān)視主服務器下線時,與其它 Sentinel 進行選舉選出leader,進行故障轉移;
  • 判斷下線(主觀下線、客觀下線)

  • Sentinel 以每秒一次的頻率向其它實例(包括主、從、其它Sentinel)發(fā)送PING,并根據回復判斷服務器是否在線,當一個實例在指定的次數中不能返回有效回復時,會將這個服務器判斷為?主觀下線
  • 判斷一個主服務器進入主觀下線后,向同樣監(jiān)視這個主服務器的其它Sentinel詢問,看是否同意這個主服務器進入主觀下線狀態(tài);
  • 當足夠多的 Sentinel 判斷主服務器進入主觀下線后,將這個主服務器判斷為?客觀下線
  • 發(fā)現主服務器進入客觀下線狀態(tài)后,發(fā)起一次故障轉移操作;
  • 選舉哨兵頭領 Sentinel Leader

  • 所有節(jié)點都會廣播一條設置信息,要求所有節(jié)點調自己為局部leader;
  • 收到廣播的節(jié)點,若尚未設置自己的局部leader,則按廣播設置其為自己的局部leader,并回復OK,否則回復失敗;
  • 廣播的節(jié)點按收到的回復,比對是否同一紀元,統(tǒng)計回復OK的數量,若超過半數,則成為全局Leader;
  • 若一紀元沒有一個節(jié)點獲得半數以上,則休眠一個隨機時間,紀元加一,再次選舉,直到選出全局leader;
  • 選出新的主服務器

  • 排除下線或者斷線的從服務器;
  • 排除最近5秒沒有回復過 leader Sentinel 的 INFO 命令的從服務器;
  • 排除與已下線服務器連接斷開超過?down-after-millinseconds * 10的從服務器;
  • 根據從服務器優(yōu)先級,對剩余從服務器排序,選出優(yōu)先級最高的;
  • 若優(yōu)先級最高的有多個,選出其中復制偏移量最大的;
  • 若優(yōu)先級最高的、偏移量最大的,仍有多個,則按?runid?,選最小的;
  • 4.集群搭建

    1.集群架構圖

    2.集群配置

    # 集群開關,默認是不開啟集群模式 # cluster-enabled yes#集群配置文件的名稱,每個節(jié)點都有一個集群相關的配置文件,持久化保存集群的信息。這個文件并不需要手動 配置,這個配置文件有Redis生成并更新,每個Redis集群節(jié)點需要一個單獨的配置文件,請確保與實例運行的系 統(tǒng)中配置文件名稱不沖突 # cluster-config-file nodes-6379.conf#節(jié)點互連超時的閥值。集群節(jié)點超時毫秒數 # cluster-node-timeout 15000#在進行故障轉移的時候,全部slave都會請求申請為master,但是有些slave可能與master斷開連接一段時間 了,導致數據過于陳舊,這樣的slave不應該被提升為master。該參數就是用來判斷slave節(jié)點與master斷線的時 間是否過長。判斷方法是: #比較slave斷開連接的時間和(node-timeout * slave-validity-factor) + repl-ping-slave-period #如果節(jié)點超時時間為三十秒, 并且slave-validity-factor為10,假設默認的repl-ping-slave-period是10 秒,即如果超過310秒slave將不會嘗試進行故障轉移 # cluster-replica-validity-factor 10# master的slave數量大于該值,slave才能遷移到其他孤立master上,如這個參數若被設為2,那么只有當一 個主節(jié)點擁有2 個可工作的從節(jié)點時,它的一個從節(jié)點會嘗試遷移 # cluster-migration-barrier 1#默認情況下,集群全部的slot有節(jié)點負責,集群狀態(tài)才為ok,才能提供服務。設置為no,可以在slot沒有全 部分配的時候提供服務。不建議打開該配置,這樣會造成分區(qū)的時候,小分區(qū)的master一直在接受寫請求,而 造成很長時間數據不一致 # cluster-require-full-coverage yes

    3.實現原理

    通過主從與哨兵,redis即可實現高可用,然額,仍然存在一個問題,單臺服務器的內存是有限的,不夠用怎么辦?redis有緩存淘汰機制,可以解決一部分問題,但業(yè)務需求是無限的,當不能過期與淘汰的數據大到一臺主機不夠用時,怎么辦呢?SO,跟所有其它分布式系統(tǒng)一樣,還需要橫向擴展能力,幸好,自redis3.0開始,開始提供集群功能;

    啟動集群:?當redis 服務器以集群模式啟動時,即成為一個?節(jié)點?,默認運行在一個只包含自己的集群中,使用cluster meet <host> <port>?命令,可以讓服務器把指定的節(jié)點加入到自己所在的集群中,假設向服務器 A 發(fā)送命令:cluster meet 127.0.0.1 12345,假設監(jiān)聽端口12345 的服務器為B,那么節(jié)點A和節(jié)點B將首先進行?握手?:

  • A 為B 創(chuàng)建一個clusterNode結構,并添加到自己的clusterState.nodes字典中;
  • A 根據?cluster meet?命令指定的地址和端口,向節(jié)點B發(fā)送meet消息;
  • B 節(jié)點收到 A 的消息,為節(jié)點A創(chuàng)建一個clusterNode結構,并添加到自己的clusterState.nodes結構中,然后向 A 回復一條?PONG?消息;
  • A 收到?PONG消息可知 B 已收到自己的握手消息,再次發(fā)一條確認消息?PING;
  • B 收到 A 發(fā)送的?PING消息,握手完成;
  • 完成握手后,A 會通過Gossip協(xié)議向集群內的其它節(jié)點發(fā)送節(jié)點B的消息,其它服務器也會與B進行握手,最終,集群內所有服務器都將感知其它服務器,保存有其它服務的clusterNode結構,并與之建立通信;
  • 槽指派: redis 集群內部,通過分片的方式來保存鍵值數據,每個分片稱之為一個槽(slot),共有0-16383共計16384個槽(2048 * 8); 集群建立后,處于未上線狀態(tài),需要進行槽指派后,才上線并開始提供服務;

    集群命令執(zhí)行: 集群中因為數據分片存儲,執(zhí)行命令的過程稍微有一點差異:收到命令后,先對key進行hash映射取得該Key的槽號,然后判斷該槽是否歸自己處理,若是則執(zhí)行命令,否則取得負責該槽的節(jié)點,返回一個MOVED錯誤,并把該節(jié)點信息返回,引導客戶端向正確的節(jié)點請求服務;

    • 該槽歸自己處理,進行處理;
    • 該槽不歸自己處理,返回一個MOVED錯誤,并把負責處理該槽的節(jié)點信息返回,引導客戶端向正確的節(jié)點請求服務;
    • 該槽數據目前正在遷移:
      • 首先在自己的庫中查找該鍵,若存在,處理;
      • 若不存在,返回ASK錯誤,并給出新節(jié)點信息,引導客戶端向新節(jié)點請求服務;客戶端需要先向新節(jié)點發(fā)送asking命令,再發(fā)送正式的命令,否則將會收到一個moved錯誤

    注:正在被導入的槽和數據,不算,只有導入完成后,才會集群內廣播

    關于集群的內部結構

    • clusterNode: 表示一個節(jié)點
    • clusterLink: 表示一個節(jié)點的連接信息
    • clusterState: 每個節(jié)點都保存著一個clusterState,記錄了以當前節(jié)點為視角,集群目前所處的狀態(tài),如是否在線、包含多少節(jié)點、當前配置紀元等等;其中兩個屬性記錄了所有槽指派信息:
      • clusterState.slots: char數組,長度2048(16384/8),用每一個二進制位表示一個槽是否歸當前節(jié)點處理,為0表示不歸我管;
      • clusterState.numslots:當前節(jié)點負責處理的槽的數量,即slots數組中位的值為1的數量;
      • clusterState.nodes:clusterNode結構數組,長度16384

    為什么是16384個槽?由記錄槽指派信息的結構可知,其實是2048,redis節(jié)點維護一個長度2048的char數組,用數組元素中的每一位表示一個槽,而char的長度為8位,于是共可以存儲2048*8=16384個槽;

    ?

    參考地址:https://my.oschina.net/u/2407208/blog/3009249

    總結

    以上是生活随笔為你收集整理的redis 主从 哨兵 集群 及原理的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。