Redis的切片集群

2021-10-19 21:55:59 字數 2756 閱讀 5329

要用redis儲存5000萬個鍵值對,每個鍵值對大約512b,這些鍵值對所佔的記憶體空間大約是25gb(5000萬 * 512b)。需要選擇一台32gb記憶體的雲主機來部署redis,因為32gb的記憶體可以儲存所有資料,而且還留有7gb來保證系統執行。

同時還需要採用rdb對資料做持久化,但是在使用過程中,redis的響應有時會非常慢。使用info命令檢視redis的latest_fork_usec指標值(最近一次fork的耗時),結果顯示這個指標值特別高,快到秒級別了。

在使用rdb進行持久化時,redis會fork子程序來完成,fork操作的用時和redis的資料量是正相關的,而fork在執行時會阻塞主線程。資料量越大,fork操作造成的主線程阻塞時間越長。所以在使用rdb對25gb資料進行持久化時,資料量較大,後台執行的子執行緒在fork建立時阻塞了主線程,於是就導致redis響應變慢了。

redis的切片集群可以儲存大量資料,而且對redis主線程的阻塞影響較小。切片集群也叫分片集群,就是指啟動多個redis例項組成乙個集群,然後按照一定的規則,把收到的資料劃分成多份,每乙份用乙個例項來儲存。

如果把25gb資料平均分成5份,使用5個例項來儲存,每個例項只需要儲存5gb資料。例項在為5gb資料生成rdb時,資料量就小了很多,fork子程序一般不會給主線程帶來較長時間的阻塞。

在剛剛的案例中,為了儲存大量資料,使用了大記憶體雲主機和切片集群兩種方法,實際上這種方法分別對應著redis應對資料量增多的兩種方案:

想要把切片集群用起來,還需要解決兩大問題:

切片集群是一種儲存大量資料的通用機制,這個機制可以有不同的實現方案。從redis3.0開始,官方提供了乙個名為redis cluster的方案,用於實現切片集群。redis cluster方案中就規定了資料和例項的對應規則。

redis cluster方案採用雜湊槽(hash slot)來處理資料和例項之間的對映關係。在redis cluster方案中,乙個切片集群共有16384個雜湊槽。

在部署redis cluster方案時,可以使用cluster create命令建立集群,此時,redis會自動把這些雜湊槽平均分布在集群例項上。

如果集群中不同redis例項的記憶體大小配置不一,也可以使用cluster meet命令手動建立例項間的連線,形成集群,再用cluster addslots命令,指定每個例項上的雜湊槽個數。

假設集群中一共有3個例項,有5個雜湊槽。可以通過以下命令手動分配雜湊槽:

redis-cli -h 172.16.19.3 -p 6379 cluster addslots 0,1

redis-cli -h 172.16.19.4 -p 6379 cluster addslots 2,3

redis-cli -h 172.16.19.4 -p 6379 cluster addslots 4

資料、雜湊槽、例項三者對映分布情況如下:在手動分配雜湊槽時,需要把16384個槽都分配完,否則redis集群無法正常工作。

在定位鍵值對資料時,它所處的雜湊槽是可以通過計算得到的,這個計算可以在客戶端傳送請求時來執行。redis例項會把自己的雜湊槽資訊傳送給和它相連線的其他例項,來完成雜湊槽分配資訊的擴散。客戶端收到雜湊槽資訊後,會把雜湊槽資訊快取在本地,當客戶端請求鍵值對時,會先計算鍵所對應的雜湊槽,然後就可以給響應的例項傳送請求了。

在集群中,例項和雜湊槽的對應關係並不是一成不變的,最常見的變化有兩個:

此時,例項之間還可以通過相互傳遞訊息,獲取最新的雜湊槽分配資訊,但是客戶端時無法感知這些變化的。redis cluster提供了一種重定向機制,就是指客戶端給乙個例項傳送資料讀寫操作時,這個例項並沒有相應的資料,客戶端要再給乙個新例項傳送操作命令。

當客戶端把乙個鍵值對的操作請求傳送給乙個例項時,如果這個例項上並命由這個鍵值對對映的雜湊槽,那麼這個例項就會給客戶端返回下面的moved相應結果,這個結果中就包含了新例項的訪問位址。

get hello:key

(error) moved 13320 172.16.19.5:6379

其中moved命令表示,客戶端請求的鍵值對所在雜湊槽13320,實際是在172.16.19.5這個例項上。通過返回moved命令,就相當於把雜湊槽所在的新例項的資訊告訴客戶端了。這樣客戶端就可以直接和172.16.19.5連線,並傳送操作請求了。

上圖中,客戶端給例項2傳送命令時,slot2中的資料已經全部遷移到了例項3,如果slot2中的資料比較多,可能slot2中的資料只有一部分遷移到了例項3,還有部分沒有遷移,這中遷移部分完成的情況下,客戶端就會收到一條ask報錯資訊:

get hello:key

(error) ask 13320 172.16.19.5:6379

這個結果中ask命令就是表示,客戶端所請求的鍵值對所在的雜湊槽13320,在172.16.19.5這個例項上,但是這個雜湊槽正在遷移。此時客戶端需要先給172.16.19.5這個例項傳送乙個asking命令,然後客戶端再向這個例項傳送get命令,以讀取資料。和moved命令不同,ask命令並不會更新客戶端快取的雜湊槽分配資訊。所以,上圖中,如果客戶端再次請求slot2中的資料,他還是會給例項2傳送請求。ask命令的作用只是讓客戶端能給新例項傳送一次請求,不會更改本地快取。

Redis集群(二) Redis的安裝

官方 本系列撒使用的版本是 3.0.0 一.安裝必要包 yum yinstall gcc redis 3.2.4.tar.gz有問題 什麼不支援64位cpu 使用3.0.0沒問題 wget tar zxvf redis 3.0.0.tar.gz cd redis 3.0.0 如果不加引數,linux...

redis的集群配置

按照所述分別在伺服器上裝好redis分別在伺服器1和伺服器2建立目錄 test redis cluster 再在該目錄下建立三個資料夾cluster1 cluster2 cluster3 一二伺服器共建六個cluster 資料夾,因為redis集群至少需要6個redis例項才能搭建,如下圖所示 將你...

redis集群的搭建

安裝步驟 第一步 redis的原始碼包上傳到linux系統。第二步 解壓縮redis。第三步 編譯。進入redis原始碼目錄。make 第四步 安裝。makeinstall prefix usr local redis prefix引數指定redis的安裝目錄。一般軟體安裝到 usr目錄下 後台啟動...