Redis叢集之Redis Cluster

來源:互聯網
上載者:User

Redis叢集之Redis Cluster
1. Linux系統配置1.1. vm.overcommit_memory設定

overcommit_memory檔案指定了核心針對記憶體配置的策略,其值可以是0、1、2。                               

0, 表示核心將檢查是否有足夠的可用記憶體供應用進程使用;如果有足夠的可用記憶體,記憶體申請允許;否則,記憶體申請失敗,並把錯誤返回給應用進程。 
1, 表示核心允許分配所有的實體記憶體,而不管當前的記憶體狀態如何。
2, 表示核心允許分配超過所有實體記憶體和交換空間總和的記憶體

jenkins_service@jenkinsservice:~/redis-3.0.1$ sudo sysctl vm.overcommit_memory=1

vm.overcommit_memory = 1

1.2. Transparent Huge Pages開啟

THP(Transparent Huge Pages)是一個使管理Huge Pages自動化的抽象層。

目前需要注意的是,由於實現方式問題,THP會造成記憶體鎖影響效能,尤其是在程式不是專門為大內記憶體頁開發的時候,簡單介紹如下:

作業系統後台有一個叫做khugepaged的進程,它會一直掃描所有進程佔用的記憶體,在可能的情況下會把4kpage交換為Huge Pages,在這個過程中,對於操作的記憶體的各種分配活動都需要各種記憶體鎖,直接影響程式的記憶體訪問效能,並且,這個過程對於應用是透明的,在應用程式層面不可控制,對於專門為4k page最佳化的程式來說,可能會造成隨機的效能下降現象。

Redis Cluster 命令列

 //叢集(cluster) 

  1. CLUSTER INFO 列印叢集的資訊 
  2. CLUSTER NODES 列出叢集當前已知的所有節點(node),以及這些節點的相關資訊。   
  3.  
  4. //節點(node) 
  5. CLUSTER MEET <ip> <port> 將 ip 和 port 所指定的節點添加到叢集當中,讓它成為叢集的一份子。 
  6. CLUSTER FORGET <node_id> 從叢集中移除 node_id 指定的節點。 
  7. CLUSTER REPLICATE <node_id> 將當前節點設定為 node_id 指定的節點的從節點。 
  8. CLUSTER SAVECONFIG 將節點的設定檔儲存到硬碟裡面。   
  9.  
  10. //槽(slot) 
  11. CLUSTER ADDSLOTS <slot> [slot ...] 將一個或多個槽(slot)指派(assign)給當前節點。 
  12. CLUSTER DELSLOTS <slot> [slot ...] 移除一個或多個槽對當前節點的指派。 
  13. CLUSTER FLUSHSLOTS 移除指派給當前節點的所有槽,讓當前節點變成一個沒有指派任何槽的節點。 
  14. CLUSTER SETSLOT <slot> NODE <node_id> 將槽 slot 指派給 node_id 指定的節點,如果槽已經指派給另一個節點,那麼先讓另一個節點刪除該槽>,然後再進行指派。 
  15. CLUSTER SETSLOT <slot> MIGRATING <node_id> 將本節點的槽 slot 遷移到 node_id 指定的節點中。 
  16. CLUSTER SETSLOT <slot> IMPORTING <node_id> 從 node_id 指定的節點中匯入槽 slot 到本節點。 
  17. CLUSTER SETSLOT <slot> STABLE 取消對槽 slot 的匯入(import)或者遷移(migrate)。   
  18.  
  19. //鍵 (key) 
  20. CLUSTER KEYSLOT <key> 計算鍵 key 應該被放置在哪個槽上。 
  21. CLUSTER COUNTKEYSINSLOT <slot> 返回槽 slot 目前包含的索引值對數量。 
  22. CLUSTER GETKEYSINSLOT <slot> <count> 返回 count 個 slot 槽中的鍵。 

 

2. 設定檔

開啟cluster的redis必須是空伺服器

修改redis.conf開啟cluster

 

設定3個cluster

10.24.6.7:6379

10.24.6.4:6379

10.24.6.6:6379

3. 查看初始redis叢集狀態

啟動三個節點上的Redis伺服器。此時,三個Redis伺服器節點均會以Redis Cluster的方式開始運行,但並沒有自動構建叢集,因為三者還處於“我不認識你,你不屬於我”的狀態,它們每個都是孤零零的Redis節點,或者是只包含了一個節點的叢集。我們可以通過Redis用戶端串連到伺服器查看它們的狀態,圖一給出了狀態查詢方法和查詢結果,其中cluster nodes命令用於查看當前Redis節點所屬的Redis叢集中的所有節點,而cluster info則用於查看當前Redis節點所屬的Redis叢集的整體狀態。由圖中我們可以看到,Redis叢集中僅包含一個Redis節點,也就是當前節點,整個叢集的狀態是fail。

 

4. 分配hash slot

通過上面的操作,我們已經將三個各自為政的Redis節點規划到一個相同的叢集中,那麼我們現在是否就已經完成了叢集搭建的所有工作了呢?非也!通過圖二中對叢集狀態的查看我們可以知道,當前叢集的狀態還是fail,此時的Redis叢集是不工作的,無法處理任何Redis命令。那麼叢集的狀態為什麼還是fail呢?本博主通過查看官方文檔說明找到了原因所在,現摘錄原文如下:

The FAIL state for the cluster happens in two cases.

1) If at least one hash slot is not served as the node serving it currently is in FAIL state.

2) If we are not able to reach the majority of masters (that is, if the majorify of masters are simply in PFAIL state, it is enough for the node to enter FAIL mode).

很明顯,導致我們的叢集處於fail狀態的原因不是第二個條,也就是說至少有一個hash slot沒有被服務!稍微考慮一下,可不是!何止有一個hash slot沒有被服務,壓根兒就沒有Redis節點為任何hash slot服務!眾所周知,Redis Cluster通過hash slot將資料根據主鍵來分區,所以一條key-value資料會根據演算法自動對應到一個hash slot,但是一個hash slot儲存在哪個Redis節點上並不是自動對應的,是需要叢集管理者自行分配的。那麼我們需要為多少個hash slot分配Redis節點呢?根據源碼可知是16384個,即我們要將16384個hash slot分配到叢集內的三個節點上。Redis中用於分配hash slot的命令有很多,其中包括cluster addslots、cluster delslots和cluster setslot。鑒於我們現在是叢集的初始化階段,所以我們可以選擇cluster addslots來分配hash slot,該命令的文法為cluster addslots slot1 [slot2] ... [slotN]。

4.1. nodes-6379.conf分配

每個redis用戶端單獨分配自己負責的部分

修改內容如下:cda76a0a094d2ce624e33bed7f3c75689a4128fd :0 myself,master - 0 0 connected 0-5000(注意是在自身節點的描述,也就是包含了myself那一行的後面追加hash slot的範圍)。類似的,Redis Cluster Node2上nodes-6379.conf檔案中追加5001-10000,Redis Cluster Node3上nodes-6379.conf檔案中追加10001-16383。經過這樣的配置後,Redis Cluster Node1負責儲存0至5000之間的所有hash slots,Redis Cluster Node2負責儲存5001至10000之間的所有hash slots,Redis Cluster Node3負責儲存10001至16383的所有hash slots。

 

4.2. Redis cluster 命令分配

 

5. 搭建Redis叢集

這裡所謂的搭建叢集,說白了就是讓之前啟動的三個Redis節點彼此連通,意識到彼此的存在,那麼如何做到這一點呢?答案就是cluster meet命令。該命令的作用就是將當前節點主動介紹給另外一個節點認識,圖二給出了cluster meet命令的執行方法和執行效果,由圖中可知我們使用cluster meet命令分別將Redis Cluster Node1介紹給了Redis Cluster Node2(節點IP地址為192.168.32.3,運行連接埠為6379)和Redis Cluster Node3(節點IP地址為192.168.32.4,運行連接埠為6379),之後我們再次查看叢集節點和叢集狀態就可以知道,三個節點已經成功合并到了同一個叢集中。

 

這裡找到了3個節點

查看10.24.6.6用戶端

 

至此,3個結點

 

搭建完成標識:

 

在叢集狀態顯示為ok之後,我們就可以像在Redis單機版上一樣執行Redis命令了。

 

6. 測試6.1. 非叢集模式6.1.1.  Redis-cli

 

非叢集模式用戶端在cluster跳轉時會提示MOVED錯誤

6.1.2.  Redis用戶端庫

from redis.sentinel import Sentinel
sentinel = Sentinel([(
'10.24.6.7', 26379)], socket_timeout=0.1)
master = sentinel.master_for(
'10.24.6.5master', socket_timeout=0.1)
print master
master.set(
'aaaaaaaaaaaaaaa', 'bar')
master.set(
'bbbbbbbbbbbbbbbb', 'bar')
print master.get('aaaaaaaaaaaaaaa')
print master.get('bbbbbbbbbbbbbbbb')

Traceback (most recent call last):

  File "E:/HomeInternet/server/utest_workspace/utest_utils/utest_unit/__init__.py", line 23, in <module>

    master.set('bbbbbbbbbbbbbbbb', 'bar')

  File "build\bdist.win32\egg\redis\client.py", line 1055, in set

  File "build\bdist.win32\egg\redis\client.py", line 565, in execute_command

  File "build\bdist.win32\egg\redis\client.py", line 577, in parse_response

  File "build\bdist.win32\egg\redis\sentinel.py", line 55, in read_response

  File "build\bdist.win32\egg\redis\connection.py", line 574, in read_response

redis.exceptions.ResponseError: MOVED 9577 10.24.6.6:6379

6.2. 叢集模式(-C)6.2.1.  Redis-cli

 

叢集模式用戶端在跳轉時會自動進行結點轉向

6.2.2. Redis Cluster

https://github.com/Grokzen/redis-py-cluster

 

from rediscluster import StrictRedisCluster
startup_nodes = [{
"host": "10.24.6.7", "port": "6379"}]
rc = StrictRedisCluster(startup_nodes=startup_nodes, decode_responses=True)
print rc.set("bbbbbbbbbbbbbbbb", "bar")
True
print rc.get("bbbbbbbbbbbbbbbb")

 

6.2.3. Redis Sentinel + Cluster

from redis.sentinel import Sentinel
from redisclusterimport StrictRedisCluster
sentinel = Sentinel([(
'10.24.6.7', 26379)], socket_timeout=0.1)
ip, port = sentinel.discover_master(
'10.24.6.5master')
rc = StrictRedisCluster(host=ip, port=port, decode_responses=True)
print rc.set("bbbbbbbbbbbbbbbb", "bar")
print rc.get("bbbbbbbbbbbbbbbb")

下面關於Redis的文章您也可能喜歡,不妨參考下:

Ubuntu 14.04下Redis安裝及簡單測試

Redis主從複製基本配置

Redis叢集明細文檔

Ubuntu 12.10下安裝Redis(圖文詳解)+ Jedis串連Redis

Redis系列-安裝部署維護篇

CentOS 6.3安裝Redis

Redis安裝部署學習筆記

Redis設定檔redis.conf 詳解

Redis 的詳細介紹:請點這裡
Redis 的:請點這裡

本文永久更新連結地址:

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.