1. 程式人生 > >redis進化五(1):redis叢集的安裝使用(redis-cluster) 及其 原理

redis進化五(1):redis叢集的安裝使用(redis-cluster) 及其 原理

叢集結構

      

特點

      1、所有redis節點(包括主和從)彼此互聯(兩兩通訊),底層使用內部的二進位制傳輸協議,優化傳輸速度;

           (所有功能特點的基礎)

      2、叢集中也有主從,也有高可用邏輯,但是沒有哨兵程序,整合到主節點的功能裡了;

           叢集中的事件被主節點(大部分主節點),通過主節點的過半選舉實現哨兵以前的邏輯

      3、客戶端與redis-cluster連線,無需關心分片的計算,客戶端不再關心分片的計算邏輯,

            內部分發分散式資料(內部有分片計算邏輯),客戶端將key交給redis節點後,

            叢集內部判斷key值的正確儲存位置,轉發儲存。

      4、redis-cluster把所有的主節點對應到[0-16383]整數區間--槽道slot;

            各自的主節點維護一批槽道號(0-5000,5001-10000,10001-16383);

            在分片計算時,對key值做hash取模運算(就是取餘,不再使用hashCode,CRC16);

            key值對應的取模運算結果,將會判斷由哪個節點維護;

            將key--slot--node,如果我們想要遷移某個key值,必須將對應的slot一併遷移;

  核心概念操作的工作原理

      儲存獲取值時的轉發邏輯

      

      槽道遷移,資料key遷移

      

      槽道原理拋2個問題:

            1、節點接收資料計算槽道號後,如何判斷當前槽道號是否歸我管?

            2、判斷不貴本節點管理時,如何獲取正確管理者資訊

Redis叢集的安裝和使用

      叢集環境安裝

      1、安裝ruby

            因為叢集命令檔案需要ruby語言支援

            a、wget到包後解壓

                  在linux中呼叫wget命令 去網上找源站路徑 複製貼上源站地址在裡面可以獲取tar包

                  解壓tar包並進入解壓目錄。

            b、./configure 在當前根目錄執行編譯;

                  編譯安裝:make && make install    

            c、yum安裝gems

                 #yum -y install  rubygems   //rubygems是什麼?

                 RubyGems(簡稱gems)是一個對Ruby元件進行打包的Ruby打包系統。

                 它提供一個分發Ruby程式和庫的標準格式,還提供一個管理程式包安裝的工具。

                 簡單理解就是ruby執行時,需要各種外掛都在gems裡;

                 是一種技術支援。

            d、gem安裝redis 介面包 gem install redis

      2、安裝redis

            上傳redis包,必須是3.0以上版本

            解壓編譯安裝

            make  && make install

      redis-cluster的具體測試

          建立節點

                建立叢集節點,不同的節點建立對應的目錄管理配置檔案

                例如: 佔用8000埠的redis服務,對應redis.conf放到8000的資料夾;

                這裡我們以節點埠名稱為名稱,本次建立6個節點的叢集目錄

                # mkdir 8000 8001 8002 8003 8004 8005

                

 

                # ll

                檢視當前所在目錄下的所有內容的詳細資訊,與ls類似

                

 

                準備8000-8005啟動的redis配置檔案,各自的配置檔案放到對應的資料夾下

                配置檔案修改並且上傳到指定目錄

                P61  bind 127.0.0.1//預設ip為127.0.0.1改為其他節點機器可訪問的ip

                註釋掉bind;可以監聽連線當前服務的所有-h 後的ip;例如;綁定了127.0.0.1,但是登入時使用-h 10.9.17.153

                P80        protected-mode no        //yes修改為no

                yes表示開啟,保護模式下,連線redis服務需要用到密碼;no表示不開啟,redis-cli登入時,不需要提供安全資訊,例如密碼;

                P84        port 8000                 //埠8000-8005

                P128    daemonize yes             //後臺執行

                P150    pidfile /var/run/redis_8000.pid //pidfile檔案對應7000

                當大量的程序啟動後,很難通過ps -ef|grep redis直接尋找你需要操作的程序的pid

                P163    logfile 8000/redis.log    //相對路徑,啟動時在redis的根目錄

                log檔案記錄的內容,就是在啟動時,控制檯列印的內容,和後續操作redis時所有的日誌資訊;

                P237    dump dump8000.rdb //指定當前服務載入的持久化檔案

                P593    appendonly yes            //預設是rdb方式持久化要改成

                P597      appendfilename "appendonly.aof" 指定一個aof格式的持久化檔案

                AOF模式;

                rdb持久化;和aof持久化模式對比

                rdb:需要客戶端必須呼叫命令 save完成資料從記憶體儲存到磁碟的操作;沒有來得及save的資料一旦丟失,資料出現未命中;

                aof:二進位制的日誌,實時記錄 redis客戶端操作的所有寫命令;沒有來得及save的資料不儲存在dump裡,

                但是命令內容,儲存在了aof檔案;恢復時,只需要將每save的所有內容的命令調出來,

                小量資料的效能對比: 開啟aof模式,比rdb單獨使用,多消耗2倍時間

                海量資料:同時開啟aof和rdb,單獨開啟rdb 消耗近似;

                

                P721    cluster-enabled yes     //載入當前配置檔案的redis服務一旦啟動需要開啟叢集模式,否則無法使用叢集的各種策略和邏輯

                P729    cluster-config-file nodes_8000.conf         //叢集配置啟動後,將會建立這個nodes檔案,

                記錄當前伺服器上唯一的一個叢集狀態;例如,搭建了8000-8005這樣一個叢集,

                操作失誤下,叢集失效,重新搭建叢集,當前伺服器讀取這個配置檔案會發現,

                槽道已經被一個叢集分配了,新的叢集搭建失敗;

                P735    cluster-node-timeout 15000     //請求超時 預設15秒,可自行設定

 

                利用vim的替換命令,將不同節點的埠在檔案中替換拷貝到對應管理的資料夾中

                vim中:%s/8000/8001/g

      

                完成之後呼叫ls檢查目錄中是否都存在redis.conf檔案

                

                分別啟動節點例項,一共啟動叢集配置的6個程序

                

 

                redis-server 8000/redis.conf

                redis-server 8001/redis.conf

                redis-server 8002/redis.conf

                redis-server 8003/redis.conf

                redis-server 8004/redis.conf

                redis-server 8005/redis.conf

                

                檢查是否啟動成功

                #ps -ef|grep redis

                搜尋關鍵字redis有關的啟動程序資訊

                

 

                #登入叢集的客戶端命令

                #redis-cli -c -p 8000

                -p 表示埠連線, -c 以叢集狀態登入節點(本質上是對單個節點的命令封裝);

                但是這個時候所有的節點並不是叢集狀態,我們單獨登入節點一樣無法實現

                叢集的操作

                #redis-cli -p 8

 

                

      建立叢集

                <檢視>啟動檔案

                在redis根目錄src目錄下有個檔案redis-trib.rb,這個就是用ruby寫的命令檔案,

                它是一個語言編寫的快速操作叢集的命令檔案,整合了底                

                層客戶端的各種各樣的命令,執行建立叢集命令(redis叢集最少需要3個master才能正常執行)

                ./redis-trib.rb 如果我使用的是./說明當前的/etc/profile中沒有對PATH進行 ./的配置,

                所有不在環境變數中的命令檔案需要到對應目錄呼叫./啟動

                

                ./redis-trib.rb  create   10.9.17.153:8000 10.9.17.153:8001 10.9.17.153:8002

                ./redis-trib.rb create --replicas 1

                host1:port1….hostn:portn

                例如:redis-trib.rb create --replicas 1 節點資訊們;

                這裡的8003 8004 8005暫不新增,後續新增節點使用

                解釋下, --replicas  1  表示 自動為每一個master節點分配至少一個slave節點   

                上面有6個節點,程式會按照一定規則生成 3個master(主)3個slave(從)

                

                提問是否同意以上內容的配置結果,yes表示同意

                

 

                 表示叢集搭建成功,槽道分配完畢;

                後期的連線需要埠開發,防火牆直接關閉;

                #service iptables stop //臨時關閉防火牆,重啟之後防火牆依然開啟

                #chkconfig iptables off //永久關閉防火牆配置,兩個命令配合,

 

      登陸

                #redis-cli -c -p 8000

                這裡注意,如果使用原有的命令沒有-c則表示單獨登陸節點,沒有叢集效果

                檢視叢集狀態

                8000>cluster info

                

                都比較好理解,唯獨epoch,epoch是個邏輯計算時間,與節點的所有變化都有關,與叢集事件有關;

                cluster_current_epoch:6 代表當前叢集的最新邏輯計算時間,數字越大,表示操作或者配置越新,整個叢集的這個值是保持一致的

                cluster_my_epoch:1代表當前節點的邏輯計算時間,

                檢視叢集節點

                8000>cluster nodes

                檢視叢集所有節點的資訊

                

                這裡的內容比較雜亂

                節點 ID :例如 3fc783611028b1707fd65345e763befb36454d73 。

                ip:port :節點的 IP 地址和埠號, 例如 127.0.0.1:7000 ,

                 flags :節點的角色(例如 master 、 slave 、 myself 如果標識myself說明當前客戶端登入的埠)以及狀態(例如 fail ,等等)。

                如果節點是一個從節點的話, 那麼跟在 flags 之後的將是主節點的節點 ID :

                 例如 127.0.0.1:7002 的主節點的節點 ID 就是 3c3a0c74aae0b56170ccb03a76b60cfe7dc1912e 。

                master節點最後有一個值的範圍,就是hash槽,0~16383(2^14),平均的分配到各master節點。

 

                測試set和get資料體會槽道的原理

                登入8000 set name hanlaoshi

                叢集底層計算判斷邏輯:name的雜湊取模,5798, 是否歸8000管理;轉向了8001,儲存

                

 

      動態新增節點

                啟動新節點8003 8004 8005

 

                

                執行新增節點命令(將8003新增到當前叢集中)

                ./redis-trib.rb add-node 10.9.17.153:8003 10.9.17.153:8001

                前面是新節點,後面是存在的任意一個節點

                

                (重啟時新增節點)如果出現如下問題

                提示內容:當前新節點已經被叢集知道,或者新節點有資料

                

                檢視當前節點的資料是否有key存在

                

 

                登入到新增節點,執行

                #8003>cluster nodes

                把新增節點的nodes檔案刪除,重啟服務,重新新增

                將節點中的資料清空

                

 

                

 

                進入叢集檢視節點狀態(預設情況是master,不管理槽道)

                

 

      動態新增從節點

                

                --slave 和--master-id 必須同時配置就可以指定給一個master新增從節點,新增節點就是從節點的角色

 

                新增從節點(8004新增到主節點8001)

                執行新增節點成為某一臺主節點的從節點命令

                --slave 指定當前節點以從節點角色新增到叢集中

                --master-id 後面跟隨主節點的masterid值,cluster nodes可以檢視

                [[email protected] src]# ./redis-trib.rb add-node --slave --master-id 5c90a71b4ace2ed64c28e686072cd40c535980fe    

                             10.9.17.153:8004 10.9.17.153:8003

                --master-id後面必須跟著主節點的id(可以使用cluster nodes檢視)

                

                檢查新增是否成功

 

                新的master要起作用需要儲存快取資料

                資料與槽道掛鉤,所以需要遷移槽道過來

                為新的節點分配槽道(只能分配空槽道)

                src/redis-trib.rb reshard 192.10.20.20:8003

                表示將叢集中的槽道重新分配,後面的節點資訊,已經在叢集中存在的任意節點資訊

                

                根據提示操作

                1 移動多少槽道

                How many slots do you want to move (from 1 to 16384)? 50

                將叢集中若干個槽道數量從新分配

                2 接收移動槽道的節點id是什麼

                What is the receiving node ID? 指定一個接收分配槽道的節點id8003id

               

                3 源資料節點都有哪些

                Please enter all the source node IDs.

                  Type 'all' to use all the nodes as source nodes for the hash slots.

                  Type 'done' once you entered all the source nodes IDs.

                如果從固定幾個節點獲取資料,直接貼上對應id,必須是主節點

                如果從所有id平均分配槽道,all

                輸入all或者done時,分配計算結束;

                Source node #1:all

                這裡我們就用all

                如果使用all將會自動計算從所有主節點平均獲取槽道移動

               

                4 確定輸入yes

                Do you want to proceed with the proposed reshard plan (yes/no)?

               

                5 螢幕滾動移動過程

                6 檢視cluster nodes 發現8003 已經配有的從各個源資料節點上移動過來的槽道

               

 

                重新分配槽道,不能重新操作有資料的槽道,空槽道可以reshard

                有資料的需要手動遷移資料後再遷移槽道(在補充操作中)

      高可用驗證

                停掉一個主的程序

                kill掉主節點8001

                #ps -ef|grep redis

               

                #kill 8554(執行登入到8001節點 shutdown的命令也可以)

                然後登陸叢集檢視叢集節點

                8000>cluster nodes

               

                啟動停掉的節點會自動拼接成slave加入

                等待一定時間,

                8000>cluster nodes

                發現8001的從節點8004重新選舉成新的主節點

 

               

 

                刪除節點(一旦刪除節點,無法直接重新加入)

               

                主節點不能直接刪除,需要reshard將槽道全部移出

                ./redis-trib.rb del-node 10.9.17.153:8000 09a25f98f963e3f90193440be5850bd351eb228b

                引數意義: 節點資訊是已經存在與叢集的節點,id表示刪除的節點id

                刪除從節點(無資料直接刪除)

                將8001重啟之後,稱為從節點加入叢集,可以測試刪除

               

 

                [[email protected] src]# ./redis-trib.rb del-node 10.9.17.153:8000 5c90a71b4ace2ed64c28e686072cd40c535980fe

               

 

                redis-trib.rb:能不能再執行的叢集維護叢集(只有新增刪除的功能可以在確定的環境下對執行著的叢集做操作,

                reshard不可以)為了快速的按照叢集的設計結構搭建一個叢集

      重新搭建叢集(僅限於測試環境)

                可以重新構造不同埠對應的叢集;

 

                沒有restart類似的重啟叢集的命令;

                重啟叢集的目的:操作時的各種失誤,導致叢集失效;

                殺掉所有程序

                刪掉檔案(dump檔案,nodes檔案,aof檔案)

                [[email protected] redis-3.2.11]# rm -f nodes*

                [[email protected] redis-3.2.11]# rm -f dump*

                rm表示刪除每刪除一個檔案,都要詢問管理員是否刪除 輸入yes表示同意

                -f是刪除命令的選項:表示所有檔案強制刪除,不要詢問

                dump* 是引數,表示當前資料夾下所有以dump開始命名的檔案

                以上命令執行的結果就是,強制刪除所有當前資料夾內以dump開始的檔案內容

                       (dump8000.rdb也刪除:為了防止啟動其他新節點時,讀取原有dump的資料導致新增叢集節點非空,失敗)

                然後清除appendonly*

 

                可以呼叫原有的配置檔案,啟動redis服務,利用redis-trib.rb重建叢集