1. 程式人生 > >高階開發不得不懂的Redis Cluster資料分片機制

高階開發不得不懂的Redis Cluster資料分片機制

Redis 叢集簡介

Redis Cluster 是 Redis 的分散式解決方案,在 3.0 版本正式推出,有效地解決了 Redis 分散式方面的需求。

Redis Cluster 一般由多個節點組成,節點數量至少為 6 個才能保證組成完整高可用的叢集,其中三個為主節點,三個為從節點。三個主節點會分配槽,處理客戶端的命令請求,而從節點可用在主節點故障後,頂替主節點。

如上圖所示,該叢集中包含 6 個 Redis 節點,3主3從,分別為M1,M2,M3,S1,S2,S3。除了主從 Redis 節點之間進行資料複製外,所有 Redis 節點之間採用 Gossip 協議進行通訊,交換維護節點元資料資訊。

一般來說,主 Redis 節點會處理 Clients 的讀寫操作,而從節點只處理讀操作。

資料分片策略

分散式資料儲存方案中最為重要的一點就是資料分片,也就是所謂的 Sharding。

為了使得叢集能夠水平擴充套件,首要解決的問題就是如何將整個資料集按照一定的規則分配到多個節點上,常用的資料分片的方法有:範圍分片,雜湊分片,一致性雜湊演算法和虛擬雜湊槽等。

範圍分片假設資料集是有序,將順序相臨近的資料放在一起,可以很好的支援遍歷操作。範圍分片的缺點是面對順序寫時,會存在熱點。比如日誌型別的寫入,一般日誌的順序都是和時間相關的,時間是單調遞增的,因此寫入的熱點永遠在最後一個分片。

對於關係型的資料庫,因為經常性的需要表掃描或者索引掃描,基本上都會使用範圍的分片策略。

Redis Cluster 採用虛擬雜湊槽分割槽,所有的鍵根據雜湊函式對映到 0 ~ 16383 整數槽內,計算公式:slot = CRC16(key) & 16383。每一個節點負責維護一部分槽以及槽所對映的鍵值資料。

Redis 虛擬槽分割槽的特點:

  • 解耦資料和節點之間的關係,簡化了節點擴容和收縮難度。
  • 節點自身維護槽的對映關係,不需要客戶端或者代理服務維護槽分割槽元資料
  • 支援節點、槽和鍵之間的對映查詢,用於資料路由,線上叢集伸縮等場景。

Redis 叢集提供了靈活的節點擴容和收縮方案。在不影響叢集對外服務的情況下,可以為叢集新增節點進行擴容也可以下線部分節點進行縮容。可以說,槽是 Redis 叢集管理資料的基本單位

,叢集伸縮就是槽和資料在節點之間的移動。

下面我們就先來看一下 Redis 叢集伸縮的原理。然後再瞭解當 Redis 節點資料遷移過程中或者故障恢復時如何保證叢集可用。

擴容叢集

為了讓讀者更好的理解上線節點時的擴容操作,我們通過 Redis Cluster 的命令來模擬整個過程。

當一個 Redis 新節點執行並加入現有集群后,我們需要為其遷移槽和資料。首先要為新節點指定槽的遷移計劃,確保遷移後每個節點負責相似數量的槽,從而保證這些節點的資料均勻。

  1. 首先啟動一個 Redis 節點,記為 M4。
  2. 使用 cluster meet 命令,讓新 Redis 節點加入到叢集中。新節點剛開始都是主節點狀態,由於沒有負責的>槽,所以不能接受任何讀寫操作,後續我們就給他遷移槽和填充資料。
  3. 對 M4 節點發送 cluster setslot { slot } importing { sourceNodeId } 命令,讓目標節點準備匯入槽的資料。 >4) 對源節點,也就是 M1,M2,M3 節點發送 cluster setslot { slot } migrating { targetNodeId } 命令,讓源節>點準備遷出槽的資料。
  4. 源節點執行 cluster getkeysinslot { slot } { count } 命令,獲取 count 個屬於槽 { slot } 的鍵,然後執行步驟>六的操作進行遷移鍵值資料。
  5. 在源節點上執行 migrate { targetNodeIp} " " 0 { timeout } keys { key... } 命令,把獲取的鍵通過 pipeline 機制>批量遷移到目標節點,批量遷移版本的 migrate 命令在 Redis 3.0.6 以上版本提供。
  6. 重複執行步驟 5 和步驟 6 直到槽下所有的鍵值資料遷移到目標節點。
  7. 向叢集內所有主節點發送 cluster setslot { slot } node { targetNodeId } 命令,通知槽分配給目標節點。為了>保證槽節點對映變更及時傳播,需要遍歷傳送給所有主節點更新被遷移的槽執行新節點。

收縮叢集

收縮節點就是將 Redis 節點下線,整個流程需要如下操作流程。

  1. 首先需要確認下線節點是否有負責的槽,如果是,需要把槽遷移到其他節點,保證節點下線後整個叢集槽節點對映的完整性。
  2. 當下線節點不再負責槽或者本身是從節點時,就可以通知叢集內其他節點忘記下線節點,當所有的節點忘記改節點後可以正常關閉。

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

遷移完槽後,還需要通知叢集內所有節點忘記下線的節點,也就是說讓其他節點不再與要下線的節點進行 Gossip 訊息交換。

Redis 叢集使用 cluster forget { downNodeId } 命令來講指定的節點加入到禁用列表中,在禁用列表內的節點不再發送 Gossip 訊息。

客戶端路由

在叢集模式下,Redis 節點接收任何鍵相關命令時首先計算鍵對應的槽,在根據槽找出所對應的節點,如果節點是自身,則處理鍵命令;否則回覆 MOVED 重定向錯誤,通知客戶端請求正確的節點。這個過程稱為 MOVED 重定向。

需要注意的是 Redis 計算槽時並非只簡單的計算鍵值內容,當鍵值內容包括大括號時,則只計算括號內的內容。比如說,key 為 user:{10000}:books時,計算雜湊值只計算10000。

MOVED 錯誤示例顯示的資訊如下,鍵 x 所屬的雜湊槽 3999 ,以及負責處理這個槽的節點的 IP 和埠號 127.0.0.1:6381 。 客戶端需要根據這個 IP 和埠號, 向所屬的節點重新發送一次 GET 命令請求。

GET x
-MOVED 3999 127.0.0.1:6381

由於請求重定向會增加 IO 開銷,這不是 Redis 叢集高效的使用方式,而是要使用 Smart 叢集客戶端。Smart 客戶端通過在內部維護 slot 到 Redis 節點的對映關係,本地就可以實現鍵到節點的查詢,從而保證 IO 效率的最大化,而 MOVED 重定向負責協助客戶端更新對映關係。

Redis 叢集支援線上遷移槽( slot ) 和資料來完成水平伸縮,當 slot 對應的資料從源節點到目標節點遷移過程中,客戶端需要做到智慧遷移,保證鍵命令可正常執行。例如當 slot 資料從源節點遷移到目標節點時,期間可能出現一部分資料在源節點,而另一部分在目標節點。

所以,綜合上述情況,客戶端命令執行流程如下所示:

  • 客戶端根據本地 slot 快取傳送命令到源節點,如果存在鍵對應則直接執行並返回結果給客戶端。
  • 如果節點返回 MOVED 錯誤,更新本地的 slot 到 Redis 節點的對映關係,然後重新發起請求。
  • 如果資料正在遷移中,節點會回覆 ASK 重定向異常。格式如下: ( error ) ASK { slot } { targetIP } : { targetPort }

客戶端從 ASK 重定向異常提取出目標節點資訊,傳送 asking 命令到目標節點開啟客戶端連線標識,再執行鍵命令。

ASK 和 MOVED 雖然都是對客戶端的重定向控制,但是有著本質區別。ASK 重定向說明叢集正在進行 slot 資料遷移,客戶端無法知道什麼時候遷移完成,因此只能是臨時性的重定向,客戶端不會更新 slot 到 Redis 節點的對映快取。但是 MOVED 重定向說明鍵對應的槽已經明確指定到新的節點,因此需要更新 slot 到 Redis 節點的對映快取。

故障轉移

當 Redis 叢集內少量節點出現故障時通過自動故障轉移保證叢集可以正常對外提供服務。

當某一個 Redis 節點客觀下線時,Redis 叢集會從其從節點中通過選主選出一個替代它,從而保證叢集的高可用性。這塊內容並不是本文的核心內容,感興趣的同學可以自己學習。

但是,有一點要注意。預設情況下,當叢集 16384 個槽任何一個沒有指派到節點時整個叢集不可用。執行任何鍵命令返回 CLUSTERDOWN Hash slot not served 命令。當持有槽的主節點下線時,從故障發現到自動完成轉移期間整個叢集是不可用狀態,對於大多數業務無法忍受這情況,因此建議將引數 cluster-require-full-coverage 配置為 no ,當主節點故障時隻影響它負責槽的相關命令執行,不會影響其他主節點的可用性。

讀者福利

針對於上面的文章我總結出了網際網路公司java程式設計師面試涉及到的絕大部分面試題及答案做成了文件和架構視訊資料免費分享給大家(包括Dubbo、Redis、Netty、zookeeper、Spring cloud、分散式、高併發等架構技術資料),希望能幫助到您面試前的複習且找到一個好的工作,也節省大家在網上搜索資料的時間來學習。

資料獲取方式:加qun群:956011797點選立即加入 找管理小姐姐免費獲取!

合理利用自己每一分每一秒的時間來學習提升自己,不要再用"沒有時間“來掩飾自己思想上的懶惰!趁年輕,使勁拼,給未來的自己一個交代!

相關推薦

高階開發不得不Redis Cluster資料分片機制

Redis 叢集簡介 Redis Cluster 是 Redis 的分散式解決方案,在 3.0 版本正式推出,有效地解決了 Red

Redis Cluster資料分片機制

上一篇《分散式資料快取中的一致性雜湊演算法》 文章中講述了一致性雜湊演算法的基本原理和實現,今天就以 Redis Cluster 為例,詳細講解一下分散式資料快取中的資料分片,上線下線時資料遷移以及請求重定向等操作。 Redis 叢集簡介 Redis Cluster 是 Redis 的分散式解決方案,在

Java反射-高階開發必須

理解反射對學習Java框架有很大的幫助,如Spring框架的核心就是使用Java反射實現的,而且對做一些Java底層的操作會很有幫助。 一:Class類的使用①.萬事萬物皆物件,(當然,基本資料型別,靜態成員不是面向物件(屬於類的)),所以我們建立的每一個類也都是物件,即類本身是java.lang.Clas

反射---Java高階開發必須

理解反射對學習Java框架有很大的幫助,如Spring框架的核心就是使用Java反射實現的,而且

高階開發必須理解的Java中SPI機制

本文通過探析JDK提供的,在開源專案中比較常用的Java SPI機制,希望給大家在實際開發實踐、學習開源專案提供參考。 SPI是什麼 SPI全稱Service Provider Interface,是Java提供的一套用來被第三方實現或者擴充套件的API,它可以用來啟

R的極客理想:高階開發篇(資料分析技術叢書).epub

  【下載地址】 R的極客理想”系列圖書以作者多年開發經驗為素材,系統地梳理了R語言的知識。在《R的極客理想——工具篇》中介紹了R語言的30多個工具包的使用方法,並以IT人的視角,告訴讀者如何高效地使用第三方R包。 《R的極客理想——高階開發篇》則以R語言的高階程式設計為

redis cluster 叢集重新分片故障處理(基於redis 4.0.6)

redis cluster 叢集重新分片故障處理(基於redis 4.0.6)  環境: redis:4.0.6 現象: 開始gem安裝redis預設版本,gem install redis,部署叢集完畢後,測試程式碼寫入叢集資料,然後進行分片,發現一隻報錯,錯誤如下

WEBAPP開發MUI框架下一個簡單的JS模仿redis資料儲存外掛

開發環境:HBuder工具 + mui框架 公司開發APP一直使用的webApp的方式進行,這樣既可以不用額外招聘安卓和ios開發外,還可以不用頭疼各種解析度相容的問題。 之前有個APP有個需求是需要將某些使用者資料儲存到手機,並且不能被使用者主動刪除的那種,

STM32高階開發(12)-在GCC中使用printf列印串列埠資料

在大家使用keil或是iar開發stm32等arm晶片的時候,想來最不陌生的就是使用print通過串列埠輸出一些資料,用來除錯或是其他作用。但是要明確的是由於keil iar gcc 他們使用的標準C語言庫雖然都遵循一個標準,但他們底層的函式實現方式都是不同的,那麼在GCC中

Redis Cluster安全的替換原有資料

1.使用背景 redis叢集,每個key帶有一個副本,經常在更新資料時,程式出現卡頓。 2.原因分析 1.單機Redis:所有的資料都儲存在一個機器上,使用rename覆蓋原有值時不會影響。 2.叢集Redis:所有的資料分佈在多臺機器上(設定了副本),使用rename覆蓋原有

Redis學習系列二之.Net開發環境搭建及基礎資料結構String字串

一、簡介 Redis有5種基本資料結構,分別是string、list(列表)、hash(字典)、set(集合)、zset(有序集合),這是必須掌握的5種基本資料結構.注意Redis作為一個鍵值對快取系統,其所有的資料結構,都以唯一的key(字串)作為名稱,然後通過key來獲取對應的資料.  

Redis資料分片處理(六)

Redis分片處理(twemproxy代理機制) 代理元件:twemproxy 不管你現在的電腦效能有多好,只要你運行了Redis,那麼就有可能造成一種可怕的局面,你電腦的記憶體將立刻被佔滿。而且一臺Redis資料庫的效能終歸是有限制的,那麼現在如果要保證使

cluster叢集、資料分片

在前面配置了一個簡單的redis主從架構: 我們現在進入真正的叢集配置: 如果我們的資料特別大,併發壓力特別高,我們的redis主伺服器也會有很大壓力,所以我們需要多個主從,也就是叢集的架構。 在mysql裡,多個主從的架構下,我們藉助了中間價my

redis cluster 叢集配置示例: 建立, 新增節點, 重新分片, 刪除節點

1 redis叢集搭建 Redis 從3.0.0正式版開始官方支援叢集,  下面開始做一個叢集配置的示例. [[email protected] ~]# tar xf redis-3.2.0.tar.gz [[email protected]

redis-cluster的上萬資料測試

Redis-cluster叢集資料測試 測試資料10000條 儲存10000條資料速度:8072ms 資料分佈情況:均勻儲存在三個主節點上,   取某一條key用時:10ms : 當一臺主節點宕機後,該主節點的某一個key,能否繼續取出:能取

redis-cluster部署及資料遷移

工作原理 Redis叢集介紹 Redis 叢集是一個提供在多個Redis間節點間共享資料的程式集。 Redis叢集並不支援處理多個keys的命令,因為這需要在不同的節點間移動資料,從而達不到像Redis那樣的效能,在高負載的情況下可能會導致不可預料的錯誤. Redis

redis資料一致性,開發中關於快取和資料同步問題

在開發中出現很多關於快取和資料共存問題,本小G網上翻閱cache aside pattern 一些資料,加上專案體驗寫下 寫下這一小簡,大家一塊來探討: 使用場景:在使用redis來做資料快取,減輕資料壓力和速度,但是有一個問題就是快取和my

22、資料分佈演算法:hash+一致性hash+redis cluster的hash slot

1、redis cluster介紹 (1)自動將資料進行分片,每個master上放一部分資料 (2)提供內建的高可用支援,部分master不可用時,還是可以繼續工作的在redis cluster架構下,每個redis要放開兩個埠號,比如一個是6379,另外一個就是加10000的埠號,比如1637

Redis資料分片

Redis的分片(Sharding或者Partitioning)技術是指將資料分散到多個Redis例項中的方法,分片之後,每個redis擁有一部分原資料集的子集。在資料量非常大時,這種技術能夠將資料量分散到若干主機的redis例項上,進而減輕單臺redis例項的壓力。

做IT的,不管你是運維、開發或架構師,這些安全知識你不得不

以前剛接觸IT行業,而我身為運維,我以為我所需要做的安全就是修改伺服器密碼為複雜的,ssh埠改為非22,還有就是不讓人登入伺服器就可以保證我維護的東西安全。 現在的認知 工作也好幾年了,在這摸爬滾打中,遇到了伺服器被黑,網站被人DDOS攻擊,資料庫被篡改等等。