Redis(五)主從複製、集羣

第一章 Redis 主從複製

1.1 主從複製是什麼

主機數據更新後根據配置和策略, 自動同步到備機的master/slaver機制,Master以寫爲主,Slave以讀爲主

1.2 主從複製能幹嘛

  • 讀寫分離,性能擴展
  • 容災快速恢復

img

1.3 怎麼玩:主從複製

拷貝多個redis.conf(redis配置文件)文件include(寫絕對路徑)

開啓daemonize yes

Pid文件名字pidfile

指定端口port

Log文件名字

dump.rdb名字dbfilename

Appendonly 關掉或者換名字

新建redis6379.conf

填寫以下內容

include /myredis/redis.conf
pidfile /var/run/redis_6379.pid
port 6379
dbfilename dump6379.rdb

img

新建redis6380.conf

填寫以下內容

img

新建redis6381.conf

填寫以下內容

img

slave-priority 10

設置從機的優先級,值越小,優先級越高,用於選舉主機時使用。默認100

啓動三臺redis服務器

img

查看系統進程,看看三臺服務器是否啓動

img

查看三臺主機運行情況

info replication #查看運行情況

打印主從複製的相關信息

img

配從(庫)不配主(庫)

slaveof  <ip><port>

成爲某個實例的從服務器

1、在6380和6381上執行: slaveof 127.0.0.1 6379

img

2、在主機上寫,在從機上可以讀取數據

在從機上寫數據報錯

img

3、主機掛掉,重啓就行,一切如初

4、從機重啓需重設:slaveof 127.0.0.1 6379

可以將配置增加到文件中。永久生效。

img

1.4 常用3招

一主二僕

切入點問題?slave1、slave2是從頭開始複製還是從切入點開始複製?比如從k4進來,那之前的k1,k2,k3是否也可以複製?

從頭複製

從機是否可以寫?set可否?

不可以

主機shutdown後情況如何?從機是上位還是原地待命?

原地待命

主機又回來了後,主機新增記錄,從機還能否順利複製?

可以

其中一臺從機down後情況如何?依照原有它能跟上大部隊嗎?

需要重新配置主機,能跟上

img

薪火相傳

上一個Slave可以是下一個slave的Master,Slave同樣可以接收其他 slaves的連接和同步請求,那麼該slave作爲了鏈條中下一個的master, 可以有效減輕master的寫壓力,去中心化降低風險。

slaveof  <ip><port>

中途變更轉向:會清除之前的數據,重新建立拷貝最新的

  • 風險是一旦某個slave宕機,後面的slave都沒法備份
  • 主機掛了,從機還是從機,無法寫數據了

img

img

反客爲主

當一個master宕機後,後面的slave可以立刻升爲master,其後面的slave不用做任何修改。

slaveof  no one

將從機變爲主機。

img

缺點:手動完成,想要自動完成需要哨兵模式

1.5 複製原理

  1. Slave啓動成功連接到master後會發送一個sync命令
  2. Master接到命令啓動後臺的存盤進程,同時收集所有接收到的用於修改數據集命令, 在後臺進程執行完畢之後,master將傳送整個數據文件(rdb)到slave,Slave拿到rdb進行讀取
  3. 每次Master進行寫操作之後,和slave進行數據同步

全量複製:而slave服務在接收到數據庫文件數據後,將其存盤並加載到內存中。

增量複製:Master繼續將新的所有收集到的修改命令依次傳給slave,完成同步

但是隻要是重新連接master,一次完全同步(全量複製)將被自動執行

img

1.6 哨兵模式(sentinel)

哨兵模式是什麼?

反客爲主的自動版,能夠後臺監控主機是否故障,如果故障了根據投票數自動將從庫轉換爲主庫

img

哨兵模式使用步驟

調整爲一主二僕模式

6379帶着6380、6381

img

自定義的/myredis目錄下新建sentinel.conf文件,名字絕不能錯

配置哨兵,填寫內容

sentinel monitor mymaster 127.0.0.1 6379 1

其中mymaster爲監控對象起的服務器名稱, 1 爲至少有多少個哨兵同意遷移的數量(這裏爲了測試,設置爲1)。

啓動哨兵

/usr/local/bin

redis做壓測可以用自帶的redis-benchmark工具

執行

redis-sentinel  /myredis/sentinel.conf 

img

哨兵默認26379端口

當主機掛掉,從機選舉中產生新的主機

(大概10秒左右可以看到哨兵窗口日誌,切換了新的主機)

哪個從機會被選舉爲主機呢?根據優先級別:slave-priority

原主機重啓後會變爲從機。

img

複製延時

由於所有的寫操作都是先在Master上操作,然後同步更新到Slave上,所以從Master同步到Slave機器有一定的延遲,當系統很繁忙的時候,延遲問題會更加嚴重,Slave機器數量的增加也會使這個問題更加嚴重。

故障恢復

img

優先級在redis.conf中默認:replica-priority 100,值越小優先級越高

偏移量是指獲得原主機數據最全的

每個redis實例啓動後都會隨機生成一個40位的runid

主從複製

private static JedisSentinelPool jedisSentinelPool=null;
public static  Jedis getJedisFromSentinel(){
    if(jedisSentinelPool==null){
        Set<String> sentinelSet=new HashSet<>();
        sentinelSet.add("192.168.11.103:26379");
        JedisPoolConfig jedisPoolConfig =new JedisPoolConfig();
        jedisPoolConfig.setMaxTotal(10); //最大可用連接數
        jedisPoolConfig.setMaxIdle(5); //最大閒置連接數
        jedisPoolConfig.setMinIdle(5); //最小閒置連接數
        jedisPoolConfig.setBlockWhenExhausted(true); //連接耗盡是否等待
        jedisPoolConfig.setMaxWaitMillis(2000); //等待時間
        jedisPoolConfig.setTestOnBorrow(true); //取連接的時候進行一下測試 ping pong
        jedisSentinelPool=new JedisSentinelPool("mymaster",sentinelSet,jedisPoolConfig);
        return jedisSentinelPool.getResource();
    }else{
        return jedisSentinelPool.getResource();
    }
}

第二章 Redis集羣

2.1 問題背景

  • 容量不夠,redis如何進行擴容?
  • 併發操作, redis如何分攤?

另外,主從模式,薪火相傳模式,主機宕機,導致ip地址發生變化,應用程序中配置需要修改對應的主機地址、端口等信息。

之前通過代理主機來解決(缺點:服務器數量多),但是redis3.0中提供瞭解決方案。就是無中心化集羣配置(任何一臺服務器都可以作爲集羣的入口,責任鏈模式)。

2.2 什麼是Redis集羣?

Redis 集羣實現了對Redis的水平擴容,即啓動N個redis節點,將整個數據庫分佈存儲在這N個節點中,每個節點存儲總數據的1/N(均分)。

Redis 集羣通過分區(partition)來提供一定程度的可用性(availability): 即使集羣中有一部分節點失效或者無法進行通訊, 集羣也可以繼續處理命令請求。

2.3 刪除持久化數據

將rdb,aof文件都刪除掉。

2.4 製作6個實例

6379,6380,6381,6389,6390,6391

3主3從

配置基本信息

開啓daemonize yes

Pid文件名字

指定端口

Log文件名字

Dump.rdb名字

Appendonly 關掉或者換名字

redis cluster配置修改

cluster-enabled yes

打開集羣模式

cluster-config-file nodes-6379.conf 

設定節點配置文件名

cluster-node-timeout 15000  

設定節點失聯時間,超過該時間(毫秒),集羣自動進行主從切換。

include /home/bigdata/redis.conf
port 6379
pidfile "/var/run/redis_6379.pid"
dbfilename "dump6379.rdb"
dir "/home/bigdata/redis_cluster"
logfile "/home/bigdata/redis_cluster/redis_err_6379.log"
cluster-enabled yes
cluster-config-file nodes-6379.conf
cluster-node-timeout 15000

修改好redis6379.conf文件,拷貝多個redis.conf文件

img

使用查找替換修改另外5個文件

shell中

:%s/6379/6380

啓動6個redis服務

img

2.5 將六個節點合成一個集羣

組合之前,請確保所有redis實例啓動後,nodes-xxxx.conf文件都生成正常。

img

合體:

cd /opt/redis-6.2.1/src

redis-cli --cluster create --cluster-replicas 1 192.168.11.101:6379 192.168.11.101:6380 192.168.11.101:6381 192.168.11.101:6389 192.168.11.101:6390 192.168.11.101:6391

此處不要用127.0.0.1, 請用真實IP地址

--replicas 1 採用最簡單的方式配置集羣,一臺主機,一臺從機,正好三組。

img

img

普通方式登錄

可能直接進入讀主機,存儲數據時,會出現MOVED重定向操作。所以,應該以集羣方式登錄。

img

2.6 -c 採用集羣策略連接,設置數據會自動切換到相應的寫主機

img

2.7 通過 cluster nodes 命令查看集羣信息

img

2.8 redis cluster 如何分配這六個節點?

一個集羣至少要有三個主節點。

選項 --cluster-replicas 1 表示我們希望爲集羣中的每個主節點創建一個從節點。

分配原則儘量保證每個主數據庫運行在不同的IP地址,每個從庫和主庫不在一個IP地址上。(交叉部署,保證高可用)

2.9 什麼是slots?

[OK] All nodes agree about slots configuration.

>>> Check for open slots...

>>> Check slots coverage...

[OK] All 16384 slots covered.

一個 Redis 集羣包含 16384 個插槽(hash slot), 數據庫中的每個鍵都屬於這 16384 個插槽的其中一個,

集羣使用公式 CRC16(key) % 16384 來計算鍵 key 屬於哪個槽, 其中 CRC16(key) 語句用於計算鍵 key 的 CRC16 校驗和 。

集羣中的每個節點負責處理一部分插槽。 舉個例子, 如果一個集羣可以有主節點, 其中:

  • 節點 A 負責處理 0 號至 5460 號插槽。
  • 節點 B 負責處理 5461 號至 10922 號插槽。
  • 節點 C 負責處理 10923 號至 16383 號插槽。

插槽起到了負載均衡的作用,根據插槽的值來決定由哪個主機來存儲key

2.10 在集羣中錄入值

在redis-cli每次錄入、查詢鍵值,redis都會計算出該key應該送往的插槽,如果不是該客戶端對應服務器的插槽,redis會報錯,並告知應前往的redis實例地址和端口。

redis-cli客戶端提供了 –c 參數實現自動重定向。

如 redis-cli -c –p 6379 登入後,再錄入、查詢鍵值對可以自動重定向。

不在一個slot下的鍵值,是不能使用mget,mset等多鍵操作。

img

可以通過{}來定義組的概念,從而使key中{}內相同內容的鍵值對放到一個slot中去。

計算cust所在的插槽值

img

2.11 查詢集羣中的值

CLUSTER GETKEYSINSLOT <slot><count> 

返回 count 個 slot 槽中的鍵。

img

注意插槽的範圍

2.12 故障恢復

如果主節點下線?從節點能否自動升爲主節點?注意:15秒超時

img

主節點恢復後,主從關係會如何?主節點回來變成從機。

img

如果所有某一段插槽的主從節點都宕掉,redis服務是否還能繼續?

如果某一段插槽的主從都掛掉,而cluster-require-full-coverage 爲yes ,那麼 ,整個集羣都掛掉

如果某一段插槽的主從都掛掉,而cluster-require-full-coverage 爲no ,那麼,該插槽數據全都不能使用,也無法存儲。

redis.conf中的參數 cluster-require-full-coverage

2.13 集羣的Jedis開發

即使連接的不是主機,集羣會自動切換主機存儲。主機寫,從機讀。

無中心化主從集羣。無論從哪臺主機寫的數據,其他主機上都能讀到數據。

public class JedisClusterTest {
  public static void main(String[] args) { 
     Set<HostAndPort>set =new HashSet<HostAndPort>();
     set.add(new HostAndPort("192.168.31.211",6379));
     JedisCluster jedisCluster=new JedisCluster(set);
     jedisCluster.set("k1", "v1");
     System.out.println(jedisCluster.get("k1"));
  }
}

2.14 Redis集羣提供了以下好處

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

2.15 Redis集羣的不足

  • 多鍵操作是不被支持的
  • 多鍵的Redis事務是不被支持的。lua腳本不被支持
  • 由於集羣方案出現較晚,很多公司已經採用了其他的集羣方案,而代理或者客戶端分片的方案想要遷移至redis cluster,需要整體遷移而不是逐步過渡,複雜度較大。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章