1. 程式人生 > 其它 >為什麼系統的Swap變高了?(二)

為什麼系統的Swap變高了?(二)

Redis 搭建叢集

我在這裡只記錄點基本內容,不會寫太深入的內容

問題

容量不夠,redis 如何進行擴容?

增加 redis 伺服器,通過叢集解決容量不夠的問題

併發寫操作,redis 如何分攤?

使用叢集負擔寫操作的壓力

主從模式、薪火相傳、主機宕機,都可能導致 ip 地址發生變化,應用程式中配置需要修改對應的主機地址、埠等資訊?

redis 3.0 之前使用代理主機來解決,redis 3.0 中提供瞭解決方案,就是無中心化叢集配置

代理主機方式:
客戶端通過代理伺服器去訪問服務,比如使用者、商品、訂單等服務,每個服務都有從伺服器,代理主機也有從伺服器

無中心化叢集:
每個服務都有從伺服器,但是任何伺服器都可以作為叢集的入口,將服務直接轉移給另外的服務

概念

redis 叢集實現了對 redis 的水平擴容,即啟動 N 個 redis 節點,將整個資料庫分佈儲存在這 N 個節點中,每個節點儲存總資料的 1/N
redis 叢集通過分割槽(partition)來提供一定長度的可用性(availability),即使叢集中有一部分節點失效或者無法進行通訊,叢集也可以繼續處理命令請求

搭建 redis 叢集

我們使用六臺伺服器搭建 redis 叢集,當然,肯定是用一臺機器的不同埠來模擬

步驟:

  1. 在 redis/bin 目錄建立一個資料夾,例如 cluster
  2. 我們需要六個 redis 配置,埠號分別為:6379、6380、6381、6389、6390、6391,6379、6380、6381
    是主伺服器,6389、6390、6391是從伺服器
  3. 配置基本資訊,配置檔名都是 redis_埠號.conf
  • include cluster/redis.conf:這是基本的redis配置檔案
  • pidfile /var/run/redis_埠號.pid
  • port 埠號
  • dbfilename "dump_埠號.rdb"
  • cluster-enabled yes:開啟叢集模式
  • cluster-config-file nodes_埠號.conf:設定節點配置檔名
  • cluster-node-timeout 15000:設定節點失聯時間,超過該時間(毫秒),叢集自動進行主從切換
  1. 啟動六個 redis 服務:開啟三個終端,到 redis/bin 目錄,啟動三臺 redis 伺服器(你也可以給這個命令配置一個環境變數)
  • ./redis-server cluster/redis_6379.conf
  • ./redis-server cluster/redis_6380.conf
  • ./redis-server cluster/redis_6381.conf
  • ./redis-server cluster/redis_6389.conf
  • ./redis-server cluster/redis_6390.conf
  • ./redis-server cluster/redis_6391.conf
  1. 將六個節點合成一個叢集,組合之前,確保所有 redis 例項啟動後,nodes_埠號.conf 檔案都生成正常(這個 node 檔案在 redis 的 data 目錄下)
  • 舊版本的 redis 版本中,需要 ruby 環境
  • 比較新的 redis 版本中,不需要額外工具,控制檯進入 redis 原始碼的 src 目錄下,執行命令redis-cli --cluster create --cluster-replicas 1 ip地址:埠號 ip地址:埠號 ...--replicas 1表示採用最簡單的方式配置叢集,一臺主伺服器,一臺從伺服器。如果有密碼,在後面加-a 密碼,或者寫配置檔案masterauth 密碼
  1. 連線要採用叢集策略連線,命令是./redis-cli -c -h ip地址 -p 埠號,設定資料會自動切換到相應的主伺服器,連線任意一個伺服器都可以
  2. 通過 cluster nodes 命令檢視叢集資訊

啟動六個 redis 伺服器

配置叢集,這裡顯示了叢集策略,顯示了哪些伺服器被分配到主伺服器,哪些被分配到從伺服器

輸入 yes 之後就開始建立叢集了,注意,我這裡分配的主從沒有對齊,變成了 6379--6390、6380--6391、6381--6389,不過這都無所謂,我們繼續

叢集操作

redis cluster 如何分配這六個節點?
一個叢集至少要有三個主節點
選項 --cluster-replicas 1 表示我們希望為叢集中的每個主節點建立一個從節點
分配原則儘量保證每個主資料庫執行在不同的ip地址,每個從資料庫和主資料庫不在一個ip地址上

再看一下 slots

[OK] All 16384 slots covered,什麼是 slots?

一個 redis 叢集包含 16384 個插槽(hash slot),資料庫中的每個鍵都屬於這 16384 個插槽的其中一個
叢集使用公式 CRC16(key) % 16384 來計算鍵key屬於哪個槽,其中 CRC16(key) 語句用於計算鍵key的 CRC16 校驗和
叢集中的每個節點負責處理一部分插槽,舉個例子,如果一個叢集可以有主節點,其中:

  • 節點 A 負責處理 0 號至 5460 號插槽
  • 節點 B 負責處理 5461 號至 10922 號插槽
  • 節點 C 負責處理 10923 號至 16383 號插槽
    但是叢集中任意一臺伺服器都可以作為叢集的入口,所以能互相訪問到自己負責的插槽之外的資料,會直接切換到插槽對應的伺服器

首先我們先用六個 redis-cli 連線對應埠的 redis 服務,一定要用叢集模式連線
三個主伺服器

三個從伺服器

插入資料示例

set name zhangsan

插入資料會自動切換到資料插槽對應的伺服器

查詢資料也會切換到對應的伺服器

從伺服器讀取或寫入資料也會切換過去

但是不能同時使用多條 set 命令,因為插槽算不出來,比如底下這條命令

mset name zhangsan age 20 id 0001

結果會報錯

需要分組,這樣就根據了組的名字去計算插槽的值

mset name{user} zhangsan age{user} 20 id{user} 0001

結果正確

查詢叢集中的值

  • cluster keyslot <key>:查詢 key 對應的插槽值
  • cluster countkeysinslot <slot>:查詢 slot 的值的數量,沒有就是 0 ,只能查詢當前伺服器負責的插槽
  • cluster getkeysinslot <slot> <count>:返回 count 個 slot 中的 key

故障恢復

如果主節點宕機,從節點自動升為主節點
宕機的主節點重啟之後,這個宕機的主節點會自動變成從節點
如果主從節點都宕機了,根據 redis.conf 的配置,cluster-require-full-coverage 為 yes ,這是預設值,那麼,整個叢集都宕機;而cluster-require-full-coverage 為 no ,那麼該插槽的資料全部都不能使用,也無法儲存

比如我們 shutdown 一個主伺服器,6380 對應的從伺服器是 6391

再去檢視它的從伺服器 6391,變成了主伺服器,沒有問題

再啟動 6380,變成了從伺服器

叢集的優勢

  • 實現擴容
  • 分攤壓力
  • 無中心配置相對簡單

叢集的缺陷

  • 多鍵操作是不被支援的
  • 多鍵的 redis 事務是不被支援的,lua 指令碼不被支援
  • 由於叢集方案出現較晚,很多公司已經採用了其它的叢集方案,而代理或者客戶端分片的方案想要遷移至 redis cluster,需要整體遷移而不是逐步過渡,複雜度較大

Redis 搭建叢集 結束