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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

《Redis开发与运维》学习第十章

發(fā)布時間:2023/12/10 数据库 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 《Redis开发与运维》学习第十章 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

第十章 Redis Cluster集群


什么叫集群??

集群(cluster)技術(shù)是一種較新的技術(shù),通過集群技術(shù),可以在付出較低成本的情況下獲得在性能、可靠性、靈活性方面的相對較高的收益,其任務(wù)調(diào)度則是集群系統(tǒng)中的核心技術(shù)
集群是一組相互獨立的、通過高速網(wǎng)絡(luò)互聯(lián)的計算機,它們構(gòu)成了一個,并以單一系統(tǒng)的模式加以管理。一個客戶與集群相互作用時,集群像是一個獨立的服務(wù)器。集群配置是用于提高可用性和可縮放性。--------百度百科

Redis Cluster是把這種集群技術(shù)運用到Redis數(shù)據(jù)庫中。


這一章主要講解Redis Cluster的數(shù)據(jù)分布、節(jié)點通信、集群伸縮、請求路由、故障轉(zhuǎn)移、集群運維等幾個方面來介紹。

10.1 數(shù)據(jù)分布


10.1.1 數(shù)據(jù)分布理論

分布式數(shù)據(jù)庫首先要解決的是如何把整個數(shù)據(jù)集按照分區(qū)規(guī)則映射到多個節(jié)點的問題。即把數(shù)據(jù)集劃分到多個節(jié)點上,每個節(jié)點負責整體數(shù)據(jù)的一個子集。
這里需要重點關(guān)注的是數(shù)據(jù)分區(qū)規(guī)則。
常見的數(shù)據(jù)分區(qū)規(guī)則有哈希分區(qū)和順序分區(qū),如下表所示:

Redis Cluster采用的是哈希分區(qū)規(guī)則,接下來介紹常見的哈希分區(qū)規(guī)則;

1 節(jié)點取余規(guī)則
實現(xiàn)方案是:使用特定的數(shù)據(jù),如Redis的鍵或用戶ID,再根據(jù)節(jié)點數(shù)量N使用公式:hash(key)%N計算出哈希值,用來決定映射到哪一個節(jié)點上。這方案實現(xiàn)起來比較簡單,但是它存在一個問題:當節(jié)點數(shù)量變化時,數(shù)據(jù)節(jié)點映射關(guān)系需要重新計算,這樣會導致數(shù)據(jù)的重新紅轉(zhuǎn)移。

2 一致性哈希分區(qū)
實現(xiàn)思路:為系統(tǒng)中的每一個節(jié)點分配一個token,范圍在0~2的32次方,這些token構(gòu)成一個哈希環(huán)。數(shù)據(jù)讀寫執(zhí)行節(jié)點查找操作時,先根據(jù)key計算hash值,然后順時針找到第一個大于等于該哈希值的token節(jié)點,這種方式最帶的優(yōu)點是插入刪除節(jié)點時只影響哈希環(huán)中相鄰的節(jié)點 。但是這種仍然存在很多問題。因此引入了虛擬槽技術(shù)對這種方式進行改進。
如下圖所示:

3 虛擬槽技術(shù)(Redis Cluster采用的集群分區(qū)方案)
虛擬槽分區(qū)巧妙的使用了哈希空間 ,使用分散度較好的哈希函數(shù)把所有的數(shù)據(jù)映射到一個固定范圍的整數(shù)集合中,整數(shù)定義為槽(slot).
這個范圍一般遠大于節(jié)點數(shù)目,比如Redis Cluster的槽范圍是0~16383.
槽是集群內(nèi)數(shù)據(jù)管理和遷移的單位。采用大范圍的槽主要是為了方便數(shù)據(jù)拆分和集群擴展。


10.1.2 數(shù)據(jù)分區(qū)

Redis Cluster采用虛擬槽技術(shù)分區(qū),所有的鍵根據(jù)哈希函數(shù)映射到0~16383整數(shù)槽內(nèi),計算公式:slot=CRC16(key)&16383。每一個節(jié)點負責維護一部分槽以及槽所映射的鍵值數(shù)據(jù)。
如圖示:


10.2 搭建集群

三個步驟:
1)準備節(jié)點
2)節(jié)點握手
3) 分配槽


10.2.1 準備節(jié)點
Redis集群一般有多個節(jié)點組成,節(jié)點數(shù)量至少為6個才能保證組成完整高可用的集群。
每個節(jié)點需要開啟配置cluster-enabled yes.,讓redis運行在集群模式下。集群相關(guān)配置如下:

節(jié)點啟動過程如下:


10.2.2 節(jié)點握手

節(jié)點握手是指一批運行在集群模式下的節(jié)點通過Gossip協(xié)議彼此通信,達到感知對方的過程。
圖示:

命令cluster meet 127.0.0.1 6380讓節(jié)點6379和6380節(jié)點進行握手通信。cluster meet 是一個異步命令,執(zhí)行完后立刻返回。

6379和6380兩個節(jié)點通過meet命令建立通信后的集群結(jié)構(gòu)如圖10-9.
工作流程如下:


對節(jié)點6379和6380執(zhí)行cluster nodes命令,可以看到他們已經(jīng)感受道對方的存在:

我們只需在集群內(nèi)任意節(jié)點上執(zhí)行cluster meet命令加入新節(jié)點,握手狀態(tài)會通過消息在集群內(nèi)傳播,這樣其他節(jié)點會自動發(fā)現(xiàn)新節(jié)點并發(fā)起握手流程。最后執(zhí)行cluster nodes命令確認6個節(jié)點都彼此感知并組成集群:

通過cluster info命令可以獲取集群當前狀態(tài):

從輸出內(nèi)容上看出:
被分配的槽cluster_slots_assigned是0 ,因為目前所有的槽沒有分配到節(jié)點,因此集群無法發(fā)完成槽到節(jié)點的映射。只有當16384個槽全部分配給節(jié)點后,集群才進入在線狀態(tài)。


10.2.3 分配槽

Redis集群把所有的數(shù)據(jù)映射到16384個槽中。
每個key會映射為一個固定的槽,只有當節(jié)點分配了槽,才會相應(yīng)和這些槽相關(guān)的鍵命令。
通過cluster addslots為節(jié)點分配槽。

這里利用bash特性批量設(shè)置槽slots :

把16384個slot個槽平均分配給6379 6380 6381三個節(jié)點。

執(zhí)行cluster info查看集群狀態(tài):


作為一個完整的集群,每個負責處理槽的節(jié)點應(yīng)該具有從節(jié)點,保證它出現(xiàn)故障時可以自動進行故障轉(zhuǎn)移。
集群模式下,Redis節(jié)點角色分為主節(jié)點和從節(jié)點。
首次啟動的節(jié)點和被分配的節(jié)點都是主節(jié)點,從節(jié)點負責復制主節(jié)點槽信息和相關(guān)的數(shù)據(jù)。
使用cluster replicate {nodeId}讓一個節(jié)點成為從節(jié)點。這個命令必須在對應(yīng)的從節(jié)點上執(zhí)行,nodeId是要復制的主節(jié)點的節(jié)點ID :

復制完成后,整個集群結(jié)構(gòu)如下:

如上,我們是依照Redis協(xié)議手動搭建一個集群。該集群由6個節(jié)點組成,3個主節(jié)點負責處理槽和相關(guān)數(shù)據(jù),3個從節(jié)點負責故障轉(zhuǎn)移。
手動集群比較繁瑣,Redis官方提供了redis-trib.rb工具方便我們快速搭建集群。


10.2.4 介紹用redis-trib.rb工具搭建集群

redis-trib.rb

是一個采用Ruby實現(xiàn)的Redis集群管理工具。Ruby是一個依賴環(huán)境。
主要是介紹這個工具,不詳細展開啦,給出課本上的一些命令。

1 Ruby環(huán)境準備

2 準備節(jié)點

3 創(chuàng)建集群

4 集群完整性檢查


10.3 節(jié)點通信

10.3.1 通信流程

分布式存儲中需要提供維護節(jié)點元數(shù)據(jù)信息的機制。所謂元數(shù)據(jù)是指:節(jié)點負責哪些數(shù)據(jù),是否出現(xiàn)故障等狀態(tài)信心。
常見的元數(shù)據(jù)維護方式分為:集中式和P2P方式。 person to person 個人對個人
Redis集群采用P2P的Gossip(流言)協(xié)議:節(jié)點彼此之間不斷的通信交換信息,一段時間后所有的節(jié)點都會知道集群完整的信息,這種方式類似于流言傳播。原理如圖所示:

通信過程如下圖所示:


10.3.2 Gossip 消息

Gossip 消息的主要職責是信息交換。信息交換的載體就是節(jié)點彼此發(fā)送的Gossip消息。
常見的Gossip消息可分為:ping 消息 pong 消息 meet消息 fail消息 .他們的通信模式如下:


所有的消息格式為:消息頭和消息體
消息頭包含發(fā)送節(jié)點自身狀態(tài)數(shù)據(jù),接收節(jié)點根據(jù)消息頭就可以獲取到發(fā)送節(jié)點的相關(guān)數(shù)據(jù)。結(jié)構(gòu)如下:


10.3.3 節(jié)點選擇

Redis集群內(nèi)節(jié)點通信采用固定頻率,因此節(jié)點每次選擇需要通信的節(jié)點列表很重要。
Redis內(nèi)集群通信節(jié)點的選擇規(guī)則如下:


根據(jù)通信節(jié)點選擇的流程可以看出消息交換的成本主要體現(xiàn)在單位時間選擇發(fā)送消息的節(jié)點數(shù)量和每個消息攜帶的數(shù)據(jù)量

1 選擇發(fā)送消息的節(jié)點數(shù)量

2 消息數(shù)據(jù)量


10.4 集群伸縮

10.4.1 伸縮原理

一般Redis集群可以實現(xiàn)對節(jié)點的靈活上線下線:其中原理可以抽象為槽和對應(yīng)數(shù)據(jù)在不同節(jié)點之間靈活移動。

首先 看下之間搭建的集群槽和數(shù)據(jù)節(jié)點的對應(yīng)關(guān)系:

其中三個主節(jié)點分別維護自己負責的槽和對應(yīng)的數(shù)據(jù),如果希望加入一個節(jié)點實現(xiàn)集群擴容時,需要通過相關(guān)命令把一部分槽和數(shù)據(jù)遷移給新節(jié)點,如圖所示:

圖中每個節(jié)點把一部分槽和數(shù)據(jù)遷移到新的節(jié)點6385,每個節(jié)點負責的槽和數(shù)據(jù)相比之前少了從而達到集群擴容的目的。
可以簡單的理解為:
集群伸縮=槽和數(shù)據(jù)在節(jié)點之間的移動


10.4.2 擴容集群
擴容是分布式存儲最常見的需求。Redis集群擴容操作可以分為如下幾個步驟:
1) 準備新節(jié)點
2)加入集群
3)遷移槽和數(shù)據(jù)


1 準備新節(jié)點

新節(jié)點建議與集群內(nèi)的節(jié)點配置保持一致
準備號配置后啟動兩個節(jié)點的命令如下:

redis-server conf/redis-6385.conf redis-server conf/redis-6386.conf

2 加入集群
新節(jié)點依然采用cluster meet命令加入到現(xiàn)有集群中。在集群內(nèi)任意節(jié)點處執(zhí)行cluster meet讓6385和6386兩個節(jié)點加入 :

cluster meet 127.0.0.1 6385 cluster meet 127.0.0.1 6386

新節(jié)點加入集群前后的示意圖:

新節(jié)點剛開始是主節(jié)點狀態(tài),但是由于沒有負責的槽,所以不能接受任何讀寫操作,對于新加入的節(jié)點的 后續(xù)操作一般有兩種::
1 為他遷移槽和數(shù)據(jù)實現(xiàn)擴容
2 作為其他主節(jié)點的從節(jié)點負責故障轉(zhuǎn)移

注意
正式環(huán)境下建議使用redis-trib.rb add-node 命令加入新節(jié)點。一般不選擇手動添加的方式,而是利用redis-trib這個工具。


3 遷移槽和數(shù)據(jù)

加入集群后需要為新節(jié)點遷移槽和相關(guān)相關(guān)數(shù)據(jù)。
遷移過程是集群擴容中的最核心環(huán)節(jié)。

1) 槽遷移計劃

槽是Redis集群管理數(shù)據(jù)的基本單位,首先需要為新節(jié)點制定槽的遷移計劃,確定原有節(jié)點的哪些槽需要遷移新節(jié)點。

槽遷移計劃確定后開始逐個把槽內(nèi)的數(shù)據(jù)從源節(jié)點遷移到目標節(jié)點。
具體流程如圖所示


2 遷移數(shù)據(jù)
數(shù)據(jù)遷移過程是逐個槽進行的:
流程說明:
1) 對目標節(jié)點發(fā)送cluster setslot {slot} importing {sourceNodeId}命令,讓目標節(jié)點準備導入槽的數(shù)據(jù)
2) 對源節(jié)點發(fā)送cluster setslot {slot} migrating {targetNodeId},讓源節(jié)點準備遷出槽的數(shù)據(jù)
3) 源節(jié)點循環(huán)執(zhí)行cluster getkeysinslot {slot} {count}命令。獲取count個屬于{slot}的槽
4)在源節(jié)點上執(zhí)行migrate {targetIp} {targetPort} "" 0 {timeout} keys {keys...}命令,把獲取的鍵通過流水線機制(pipeline)批量遷移到目標節(jié)點。
5)重復執(zhí)行步驟3 4 直到槽下所有的鍵值數(shù)據(jù)遷移到目標節(jié)點
6) 向集群內(nèi)所有主節(jié)點發(fā)送cluster setslot {slot} node {targetNodeId}命令通知槽分配給目標節(jié)點。

但是一般我們不手動去遷移數(shù)據(jù),而是用redis-trib提供的槽重分片功能實現(xiàn)數(shù)據(jù)的遷移i。
具體操作是如何實現(xiàn)的可以查看課本。


10.4.3 收縮集群
收縮集群意味著縮減規(guī)模,需要從現(xiàn)有集群中安全下線部分節(jié)點。安全下線節(jié)點流程如下圖所示:


1 下線遷移槽
下線節(jié)點需要自己把自己負責的槽遷移到其他節(jié)點,原理與之前節(jié)點擴容的遷移槽過程一致。

2 忘記節(jié)點
由于集群內(nèi)的節(jié)點不斷的通過Gossip消息彼此交換節(jié)點狀態(tài),因此需要通過一種健壯的機制讓集群內(nèi)所有的節(jié)點忘記下線的節(jié)點。為此,Redis提供了cluster forget {downNodeId}實現(xiàn)該功能

線上操作不建議直接使用cluster forget執(zhí)行節(jié)點下線,建議使用redis-trib.rb del-node {host:port} {downNodeId}來執(zhí)行該操作。


10.5 請求路由

10.5.1 請求重定向
集群模式下,Redis接收任何鍵相關(guān)命令時首先計算鍵對應(yīng)的槽,再根據(jù)槽找出所對應(yīng)的節(jié)點,如果節(jié)點是自身,則處理鍵命令;否則回復MOVED重定向錯誤,通知客戶端請求正確的節(jié)點,這個過程稱為MOVED重定向
如圖所示:

鍵命令執(zhí)行步驟主要分為兩步:計算槽,查找槽所對應(yīng)的節(jié)點。

1 計算槽
Redis首先需要計算鍵所對應(yīng)的槽。根據(jù)鍵的有效部分使用CRC16函數(shù)計算出散列值,再取對16383的余數(shù),使每個鍵都可以映射到0-16383槽范圍內(nèi)

2 槽節(jié)點查詢
Redis計算得到鍵對應(yīng)的槽后,需要查找槽所對應(yīng)的節(jié)點。


根據(jù)MOVED重定向機制,客戶端可以隨機連接集群內(nèi)任一Redis獲取鍵所在的節(jié)點,這種客戶端叫Dummy客戶端,它的代碼簡單,但是也存在一些問題。因此通常情況下,集群客戶端都采用另一種實現(xiàn):Smart客戶端。

10.5.2 Smart客戶端
實現(xiàn)原理:
Smart客戶端通過在內(nèi)部維護slot->node的映射關(guān)系,本地就可以實現(xiàn)鍵到節(jié)點的查找,從而保證IO效率的最大化,而MOVED重定向機制負責協(xié)助Smart客戶端更新slot->node映射。

10.5.3 ASK重定向


10.6 故障轉(zhuǎn)移

Redis集群內(nèi)節(jié)點通過ping/pong 命令實現(xiàn)節(jié)點通信,消息不但可以傳播節(jié)點槽信息,還可以傳播其他狀態(tài)如:主從狀態(tài)、節(jié)點故障等。因此故障發(fā)現(xiàn)也是通過消息傳播機制實現(xiàn)的,主要環(huán)節(jié)如下:主觀下線pfail和客觀下線fail

再次理解主管下線和客觀下線:

主觀下線:指某個節(jié)點認為另一個節(jié)點不可用,即下線狀態(tài),這個狀態(tài)并不是最終的故障判定,只能代表一個節(jié)點 的意見,可能存在誤判的情況。
客觀下線:標記一個節(jié)點真正的下線,集群內(nèi)多個節(jié)點都認為i該節(jié)點不可用,從而達成共識的結(jié)果。如果是持有槽的主節(jié)點故障,需要為該節(jié)點執(zhí)行故障轉(zhuǎn)移。

Redis集群是比較健壯的故障發(fā)現(xiàn)機制,因此只有當認為客觀下線后,才認為該節(jié)點是真正的下線。


10.6.2 故障恢復

故障節(jié)點變?yōu)榭陀^下線后,如果該節(jié)點是持有槽的主節(jié)點,則需要在它的從節(jié)點中選出一個替換它,從而保證的集群的高可用。下線主節(jié)點的所有從節(jié)點承擔故障恢復的義務(wù),當從節(jié)點通過內(nèi)部定時任務(wù)發(fā)現(xiàn)自身復制的主節(jié)點進入客觀下線后時,將觸發(fā)故障恢復流程。
故障恢復流程如下:


10.7 集群運維

10.7.1 集群完整性
為了保證集群的完整性,默認情況下當前集群16384個槽任何一個沒有指派到節(jié)點時整個集群不可用。


10.7.2 帶寬消耗
集群內(nèi)Gossip消息通信本身會消耗帶寬,官方建議集群內(nèi)最大規(guī)模在1000以內(nèi),也是出于對消息通信成本的考慮,因此單集群不適合部署超大規(guī)模的節(jié)點。


10.7.3 Pub/Sub 廣播問題
Redis 提供訂閱發(fā)布功能,用于針對頻道實現(xiàn)消息的發(fā)布和訂閱,但是在集群模式下內(nèi)部實現(xiàn)對所有的publish命令都會向所有的節(jié)點進行廣播,造成每條publish數(shù)據(jù)都會在集群內(nèi)所有節(jié)點傳播一次,加重帶寬負擔。


10.7.4 集群傾斜
集群傾斜指不同節(jié)點之間的數(shù)據(jù)量和請求量出現(xiàn)明顯差異,這種情況將加大負載均衡和開發(fā)運維的難度。
分為數(shù)據(jù)傾斜和請求傾斜


10.7.5 集群讀寫分離

10.7.6 手動故障轉(zhuǎn)移

10.7.7 數(shù)據(jù)遷移

總結(jié)

以上是生活随笔為你收集整理的《Redis开发与运维》学习第十章的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。