大資料 網際網路架構階段 Redis(三)redis叢集
阿新 • • 發佈:2018-12-25
Redis(三) redis叢集
一、 redis哨兵模式的缺點
- 問題一 : 橫向擴充套件不方便 , 一旦擴充套件 , 無論程式碼結構多麼簡單, 都需要修改
- 問題二 : 雜湊分散式演算法是hash一致性 , 無論多少的資料遷移都會造成擴充套件叢集和收縮叢集時必須要做資料遷移 。
- redis在3.0 版本時引入redis叢集的技術 , 解決以上問題
- 無論如何擴充套件redis叢集 , 程式碼都無需修改 , 繼續使用舊配置
- redis叢集支援手動遷移資料(只需啊要一個命令即可) , 而且無需知道底層演算法 , 維護人員手動遷移資料 , 而且可以控制遷移數量
二、 redis叢集架構
- 對於客戶端,連線redis叢集無需配置全部結點的ip和埠最少配置一個就可以,分散式不是程式碼維護而是叢集內部管理資料分佈
- 內部資料(key-value)是根據0~16383的槽道傳遞的
- 內部資料的重定向
- 使用key值進行雜湊取模 , 得到的就是槽道號 , 結點會判斷這個槽道號是不是自己所管理的, 如果是 , 則儲存 ; 如果不是 , 則資料從定向
- 這樣快取結構在擴容或收縮時 , 就解決了需要手動修改程式碼的問題
- 手動遷移資料
- 在叢集中所有的key真正對映關係和redis節點本身無關,只和槽道號有關,需要資料遷移時,不能直接對key-value對資料操作,而是將槽道進行重新分配(reshard)叢集中的所有資料將會根據重新計算的槽道管理內容進行重新轉發儲存(遷移的過程類似於修改資料加鎖的過程,不能再遷移時進行資料操作)
- 重新分配 槽道後 ,所有的對應當前遷移這些槽道號的key-value資料將會 根據槽道的重新分配進行轉發儲存
- 在redis中可以呼叫遷移命令來reshard資料槽道號 , 所以無需程式碼客戶端呼叫程式重新分配資料 。
- 在叢集中所有的key真正對映關係和redis節點本身無關,只和槽道號有關,需要資料遷移時,不能直接對key-value對資料操作,而是將槽道進行重新分配(reshard)叢集中的所有資料將會根據重新計算的槽道管理內容進行重新轉發儲存(遷移的過程類似於修改資料加鎖的過程,不能再遷移時進行資料操作)
三 、 搭建redis叢集
- 安裝ruby : 因為叢集命令需要ruby環境的支援
- 如果有外網連線 , 則直接使用yum install ruby 命令 , 但是要注意版本 , 必須使用2.3版本以上
- 檢查安裝是否成功
- 如果沒有外網連線 , 則需要實現準備安裝包 , 上傳到linux中後使用tar -xvf ruby資源 解壓 (或者有網的情況下 wget “https://cache.ruby-lang.org/pub/ruby/2.3/ruby-2.3.1.tar.gz
- 進入ruby目錄 , 執行編譯
- 編譯安裝 使用make && make install
- 如果有外網連線 , 則直接使用yum install ruby 命令 , 但是要注意版本 , 必須使用2.3版本以上
- 安裝gems
- RubyGems(簡稱gems)是一個用於對ruby組將進行打包的ruby打包系統 , ,它提供一個分發ruby程式和庫的標準格式 , 還提供一個管理程式的包安裝工具 , 是一種技術支援
- 使用命令 yum install rubygems 安裝
- 安裝redis介面包 : gem install redis
- 檢查安裝情況 ruby -v
- 安裝redis 略(在redis一中)
- 要求reids的版本必須是3.0以上
建立叢集節點
- 建立不同redis節點對應的管理目錄
修改配置文redis.conf件並上傳到指定目錄
P61 bind 127.0.0.1//預設ip為127.0.0.1改為其他節點機器可訪問的ip 註釋掉bind P80 protected-mode no //yes修改為no P84 port 7000 //埠7000 P128 daemonize yes //後臺執行 P150 pidfile /var/run/redis_7000.pid //pidfile檔案對應7000 當大量的程序啟動後,很難通過ps -ef|grep redis直接尋找你需要操作的程序的pid P163 logfile=7000/redis.log //相對路徑,啟動時在redis的根目錄 P593 appendonly yes P721 cluster-enabled yes //開啟叢集 P729 cluster-config-file nodes_7000.conf //叢集的配置 P735 cluster-node-timeout 15000 //請求超時 預設15秒,可自行設定
- 修改完成並上傳完成後檢查
分別啟動這些 結點
redis-server 7000/redis7000.conf redis-server 7001/redis7001.conf redis-server 7002/redis7002.conf redis-server 7003/redis7003.conf redis-server 7004/redis7004.conf redis-server 7005/redis7005.conf
- 檢查是否啟動陳宮
- 但是現在所有的結點並不是說結群的狀態
- 在src目錄下有個redis-trib.rb 檔案, 這個就是ruby語言寫的命令檔案 。
執行建立叢集命令 。
./redis-trib.rb 如果我使用的是./說明當前的/etc/profile中沒有對PATH進行 ./的配置,所有不在環境變數中的命令檔案需要到對應目錄呼叫./啟動 在src目錄下執行 #./redis-trib.rb create --replicas 1 106.75.74.254:7000 106.75.74.254:7001 106.75.74.254:7002 106.75.74.254:7003 106.75.74.254:7004 106.75.74.254:7005 ./redis-trib.rb create 新節點ip:埠 舊ip:埠 解釋下, --replicas 1 表示 自動為每一個master節點分配一個slave節點 上面有6個節點,程式會按照一定規則生成 3個master(主)3個slave(從)
防火牆一定要關閉 , 否則會建立失效
建立成功
- 測試叢集:
- 登入這裡需要注意 ,如果使用原有的命令(沒有 -c) , 則表示單節點登入 , 沒有叢集效果
- 檢視叢集效果epoch是一個邏輯計算時間, 與節點的所有變化都有關 , cluster_current_epoch:6 , 代表當前叢集的邏輯計算時間 , 數字越大 , 表示操作或配置越新 , 整個叢集的之歌值都是一致的 。 cluster_my_epoch:1表示當前節點的邏輯計算時間 。
- 檢視叢集節點這裡會顯示節點ID 、 ip:port(節點的ip和埠號) 、 flags(節點的角色 , 如: master 、 slave 、 myself) 、 以及狀態 。
- 如果一個節點是一個從節點 , 則跟在flags後面的將是主節點的ID
- master 後有一個值的範圍 , 這個就是該主節點管理的hash槽道 , 預設在叢集開啟時將槽道平均分配到個master節點。
- 高可用驗證:
- 停掉一個主節點的程序(kill 掉 7000)
- 然後登陸叢集檢視叢集節點
- 啟動停掉的結點會自動拼成slave加入
- 建立並啟動新節點7007 , 7006
- 執行新增結點命令 , 將結點新增在叢集中前面的是需要被新增的結點 , 後面是叢集中已有的任意節點
- 可能會出現以下問題需要檢視當前節點中是否存在key如果被天劍的結點中已有資料 , 將會新增叢集失敗 , 這是為了防止資料衝突, 不允許帶有資料的結點動態新增到叢集中 。使用flushdb命令將7006中的資料清空
- 進入進群檢視結點狀態
- 指定 新增為某個主節點的從節點(如果不指定 , 預設新增為從節點)–slave和–master-id 必須同時使用才能起到指定master新增節點的作用
- 新增從節點 (實現建立並開啟7007)
- 執行新增節點成為某一臺主節點的從節點命令 (–slave 指定當前節點以從節點的角色新增到叢集中 , –master-id 指定從節點新增時掛載的主節點的ID)新的master要起作用需要儲存快取資料 , 資料實際是被槽道控制 , 所以新增主節點後需要遷移槽道來為新的主節點分配槽道
- 根據提示操作
- 問你需要移動多少槽道
- 接收移動的槽道的結點的ID(7006ID)
- 從哪裡遷移槽道?
- 如果從指定的多個結點遷移 ,則依次貼上對應的結點的ID , 必須是主節點 , 新增完成之後輸入done 表示分配計算結束
- 如果需要所有主節點平均分配 , 則直接輸入all
- 你確定這樣的分片計劃麼 yes
- 檢視cluster nodes 發現7006已經有了從其他主結點遷移過來的槽道了
- 刪除節點
- 刪除從節點 (無資料直接刪除)
- 主節點不能直接刪除 , 需要將槽道全部移除之後再刪除將槽道移到7003這裡必須寫7006的id 這裡只從7006移除槽道所以寫完7006ID後輸入done結束輸入
- 完成之後呼叫刪除節點命令刪除節點
- 檢視叢集節點狀態 , 7006 和他的從節點7007都消失了
四、 引出的問題
- 叢集的擴充套件思路分析
- 維護人員可以人為地控制當前節點上的槽道 , 從而人為的控制資料傾斜
- 問題: 每一個節點是如何知道自己管理的槽道有哪些?
- 問題: 如果不是自己管理的槽道 , 那麼將資料轉發到那個節點 ?
解答: 每一個節點都維護著兩個資訊
- 一個是16384為的位序列
- 一個是所有節點共享的16384個元素的陣列
- 要知道本節點維護的槽道號, 只需要訪問本節點中的這個16384位的為序列即可
在叢集中所有節點共享一個16384個元素的陣列 , 陣列元素儲存節點資訊;叢集中每個節點的陣列資訊一致
reshard分片過程中,位序列和陣列的變化 位序列先計算,變化,每一個變動槽道號的master節點的位序列; 例子;7001 400-500;然後將這101個槽道挪走了挪到7002 位序列變化 400-500節點從1程式設計0;陣列資訊 400-500的元素清空; 7002 接收400-500;然後位序列中的400-500位從0變成1;將共享陣列的400-500元素賦值,自己的值 主從從複製,主宕從頂的特點; 主從複製;複製主節點的key-value資料 位序列為0 共享陣列也存在從節點; 主從替換;7001主,7003從 位序列不一樣,資料一樣,陣列一樣; 7003頂替的過程;將陣列進行分析,是7001的獲取下標,計算位序列;根據位序列修改陣列,將位序列是1的下標對應更新陣列元素;陣列同步複製; 資料的重新計算: 1 主從替換時,資料完全不用動 2 reshard過程完成後,所有key重新計算,根據轉發邏輯,改轉發的轉發,改保留的保留