久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

Redis哈希分片原理是什么

164次閱讀
沒有評論

共計 3502 個字符,預計需要花費 9 分鐘才能閱讀完成。

本篇內容介紹了“Redis 哈希分片原理是什么”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓丸趣 TV 小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

集群分片模式

如果 Redis 只用復制功能做主從,那么當數據量巨大的情況下,單機情況下可能已經承受不下一份數據,更不用說是主從都要各自保存一份完整的數據。在這種情況下,數據分片是一個非常好的解決辦法。

Redis 的 Cluster 正是用于解決該問題。它主要提供兩個功能:

自動對數據分片,落到各個節點上

即使集群部分節點失效或者連接不上,依然可以繼續處理命令

對于第二點,它的功能有點類似于 Sentienl 的故障轉移(可以了解下之前 Sentinel 的文章),在這里不細說。下面詳細了解下 Redis 的槽位分片原理,在此之前,先了解下分布式簡單哈希算法和一致性哈希算法,以幫助理解槽位的作用。

簡單哈希算法

假設有三臺機,數據落在哪臺機的算法為

 c = Hash(key) % 3

例如 key A 的哈希值為 4,4%3=1,則落在第二臺機。Key ABC 哈希值為 11,11%3=2,則落在第三臺機上。

利用這樣的算法,假設現在數據量太大了,需要增加一臺機器。A 原本落在第二臺上,現在根據算法 4%4=0,落到了第一臺機器上了,但是第一臺機器上根本沒有 A 的值。這樣的算法會導致增加機器或減少機器的時候,引起大量的緩存穿透,造成雪崩。

一致性哈希算法

在 1997 年,麻省理工學院的 Karger 等人提出了一致性哈希算法,為的就是解決分布式緩存的問題。

在一致性哈希算法中,整個哈希空間是一個虛擬圓環

假設有四個節點 Node A、B、C、D,經過 ip 地址的哈希計算,它們的位置如下

有 4 個存儲對象 Object A、B、C、D,經過對 Key 的哈希計算后,它們的位置如下

對于各個 Object,它所真正的存儲位置是按順時針找到的第一個存儲節點。例如 Object A 順時針找到的第一個節點是 Node A,所以 Node A 負責存儲 Object A,Object B 存儲在 Node B。

一致性哈希算法大概如此,那么它的容錯性和擴展性如何呢?

假設 Node C 節點掛掉了,Object C 的存儲丟失,那么它順時針找到的最新節點是 Node D。也就是說 Node C 掛掉了,受影響僅僅包括 Node B 到 Node C 區間的數據,并且這些數據會轉移到 Node D 進行存儲。

同理,假設現在數據量大了,需要增加一臺節點 Node X。Node X 的位置在 Node B 到 Node C 直接,那么受到影響的僅僅是 Node B 到 Node X 間的數據,它們要重新落到 Node X 上。

所以一致性哈希算法對于容錯性和擴展性有非常好的支持。但一致性哈希算法也有一個嚴重的問題,就是數據傾斜。

如果在分片的集群中,節點太少,并且分布不均,一致性哈希算法就會出現部分節點數據太多,部分節點數據太少。也就是說無法控制節點存儲數據的分配。如下圖,大部分數據都在 A 上了,B 的數據比較少。

哈希槽

Redis 集群(Cluster)并沒有選用上面一致性哈希,而是采用了哈希槽(SLOT)的這種概念。主要的原因就是上面所說的,一致性哈希算法對于數據分布、節點位置的控制并不是很友好。

首先哈希槽其實是兩個概念,第一個是哈希算法。Redis Cluster 的 hash 算法不是簡單的 hash(),而是 crc16 算法,一種校驗算法。

另外一個就是槽位的概念,空間分配的規則。其實哈希槽的本質和一致性哈希算法非常相似,不同點就是對于哈希空間的定義。一致性哈希的空間是一個圓環,節點分布是基于圓環的,無法很好的控制數據分布。而 Redis Cluster 的槽位空間是自定義分配的,類似于 Windows 盤分區的概念。這種分區是可以自定義大小,自定義位置的。

Redis Cluster 包含了 16384 個哈希槽,每個 Key 通過計算后都會落在具體一個槽位上,而這個槽位是屬于哪個存儲節點的,則由用戶自己定義分配。例如機器硬盤小的,可以分配少一點槽位,硬盤大的可以分配多一點。如果節點硬盤都差不多則可以平均分配。所以哈希槽這種概念很好地解決了一致性哈希的弊端。

另外在容錯性和擴展性上,表象與一致性哈希一樣,都是對受影響的數據進行轉移。而哈希槽本質上是對槽位的轉移,把故障節點負責的槽位轉移到其他正常的節點上。擴展節點也是一樣,把其他節點上的槽位轉移到新的節點上。

但一定要注意的是,對于槽位的轉移和分派,Redis 集群是不會自動進行的,而是需要人工配置的。所以 Redis 集群的高可用是依賴于節點的主從復制與主從間的自動故障轉移。

集群搭建

下面以最簡單的例子,拋開高可用主從復制級轉移的內容,來重點介紹下 Redis 集群是如何搭建,槽位是如何分配的,以加深對 Redis 集群原理及概念的理解。

redis.conf 配置

先找到 redis.conf,啟用 cluster 功能。

cluster-enabled yes 默認是關閉的,要啟用 cluster,讓 redis 成為集群的一部分,需要手動打開才行。

然后配置 cluster 的配置文件

每一個 cluster 節點都有一個 cluster 的配置文件,這個文件主要用于記錄節點信息,用程序自動生成和管理,不需要人工干預。唯一要注意的是,如果在同一臺機器上運行多個節點,需要修改這個配置為不同的名字。

本次為了方便搭建,所有 Redis 實例都在同一臺機器上,所以修改不同的 cluster config 名字后,復制三份 redis.conf 配置,以用于啟動三個集群實例(cluster 至少要三個主節點才能進行)。

集群關聯

   redis-server /usr/local/etc/redis/redis-6379.conf --port 6379  
   redis-server /usr/local/etc/redis/redis-6380.conf --port 6380  
   redis-server /usr/local/etc/redis/redis-6381.conf --port 6381 

符號的作用是讓命令在后臺執行,但程序執行的 log 依然會打印在 console 中。也可以通過配置 redis.conf 中 deamonize yes,讓 Redis 在后臺運行。

連上 6379 的 Redis 實例,然后通過 cluster nodes 查看集群范圍。

連上其他實例也是一樣,目前 6379、6380、6381 在各自的集群中,且集群只有它們自己一個。

在 6379 上,通過 cluster meet 命令,與 6380、6381 建立鏈接。

 127.0.0.1:6379  cluster meet 127.0.0.1 6380
 127.0.0.1:6379  cluster meet 127.0.0.1 6381

可以看到集群中已經包含了 6379、6380、6381 三個節點了。登錄其他節點查看也是一樣的結果。即使 6380 與 6381 之間沒有直接手動關聯,但在集群中,節點一旦發現有未關聯的節點,會自動與之握手關聯。

槽位分配

通過 cluster info 命令查看集群的狀態

state 的狀態是 fail 的,還沒啟用。看下官方的說明
Redis 哈希分片原理是什么
只有 state 為 ok,節點才能接受請求。如果只要有一個槽位(slot)沒有分配,那么這個狀態就是 fail。而一共需要分配 16384 槽位才能讓集群正常工作。

接下來給 6379 分配 0~5000 的槽位,給 6380 分配 5001~10000 的槽位,給 6381 分配 10001~16383 的槽位。

   redis-cli -c -p 6379 cluster addslots {0..5000}
   redis-cli -c -p 6380 cluster addslots {5001..10000}
   redis-cli -c -p 6381 cluster addslots {10001..16383}

再看看 cluster info
Redis 哈希分片原理是什么
state 已經為 ok,16384 個槽位都已經分配好了。現在集群已經可以正常工作了。

效果測試

隨便登上一個實例,記得加上參數 -c,啟用集群模式的客戶端,否則無法正常運行。

 redis-cli -c -p 6380

嘗試下 set、get 操作
Redis 哈希分片原理是什么
可以看到,Redis 集群會計算 key 落在哪個卡槽,然后會把命令轉發到負責該卡槽的節點上執行。

利用 cluster keyslot 命令計算出 key 是在哪個槽位上,從而得出會跳轉到哪個節點上執行。

“Redis 哈希分片原理是什么”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注丸趣 TV 網站,丸趣 TV 小編將為大家輸出更多高質量的實用文章!

正文完
 
丸趣
版權聲明:本站原創文章,由 丸趣 2023-07-20發表,共計3502字。
轉載說明:除特殊說明外本站除技術相關以外文章皆由網絡搜集發布,轉載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 亳州市| 准格尔旗| 江达县| 奉节县| 明光市| 巴塘县| 洪雅县| 淮滨县| 汝南县| 台东市| 若尔盖县| 兖州市| 偏关县| 淮滨县| 托里县| 娄底市| 鄂伦春自治旗| 宁波市| 沈丘县| 壤塘县| 太保市| 阿城市| 易门县| 油尖旺区| 穆棱市| 锡林浩特市| 无棣县| 巴南区| 楚雄市| 远安县| 赫章县| 岳阳县| 施甸县| 乐安县| 宿松县| 甘孜| 徐闻县| 安平县| 翁牛特旗| 宣汉县| 开平市|