新聞中心
redis從3.0開始支持集群功能。redis集群采用無中心節(jié)點方式實現(xiàn),無需proxy代理,客戶端直接與redis集群的每個節(jié)點連接,根據(jù)同樣的hash算法計算出key對應的slot,然后直接在slot對應的redisj節(jié)點上執(zhí)行命令。在redis看來,響應時間是最苛刻的條件,增加一層帶來的開銷是redis不能接受的。因此,redis實現(xiàn)了客戶端對節(jié)點的直接訪問,為了去中心化,節(jié)點之間通過gossip協(xié)議交換互相的狀態(tài),以及探測新加入的節(jié)點信息。redis集群支持動態(tài)加入節(jié)點,動態(tài)遷移slot,以及自動故障轉移。

成都創(chuàng)新互聯(lián)公司專注于德安網(wǎng)站建設服務及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗。 熱誠為您提供德安營銷型網(wǎng)站建設,德安網(wǎng)站制作、德安網(wǎng)頁設計、德安網(wǎng)站官網(wǎng)定制、小程序制作服務,打造德安網(wǎng)絡公司原創(chuàng)品牌,更為您提供德安網(wǎng)站排名全網(wǎng)營銷落地服務。
1. Linux系統(tǒng)配置
1.1. vm.overcommit_memory設置
overcommit_memory文件指定了內(nèi)核針對內(nèi)存分配的策略,其值可以是0、1、2。
0, 表示內(nèi)核將檢查是否有足夠的可用內(nèi)存供應用進程使用;如果有足夠的可用內(nèi)存,內(nèi)存申請允許;否則,內(nèi)存申請失敗,并把錯誤返回給應用進程。 1, 表示內(nèi)核允許分配所有的物理內(nèi)存,而不管當前的內(nèi)存狀態(tài)如何。2, 表示內(nèi)核允許分配超過所有物理內(nèi)存和交換空間總和的內(nèi)存
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自動化的抽象層。
目前需要注意的是,由于實現(xiàn)方式問題,THP會造成內(nèi)存鎖影響性能,尤其是在程序不是專門為大內(nèi)內(nèi)存頁開發(fā)的時候,簡單介紹如下:
操作系統(tǒng)后臺有一個叫做khugepaged的進程,它會一直掃描所有進程占用的內(nèi)存,在可能的情況下會把4kpage交換為Huge Pages,在這個過程中,對于操作的內(nèi)存的各種分配活動都需要各種內(nèi)存鎖,直接影響程序的內(nèi)存訪問性能,并且,這個過程對于應用是透明的,在應用層面不可控制,對于專門為4k page優(yōu)化的程序來說,可能會造成隨機的性能下降現(xiàn)象。
Redis Cluster 命令行
//集群(cluster)
1. CLUSTER INFO 打印集群的信息
2. CLUSTER NODES 列出集群當前已知的所有節(jié)點(node),以及這些節(jié)點的相關信息。
3.
4. //節(jié)點(node)
5. CLUSTER MEET 將 ip 和 port 所指定的節(jié)點添加到集群當中,讓它成為集群的一份子。
6. CLUSTER FORGET
從集群中移除 node_id 指定的節(jié)點。 7. CLUSTER REPLICATE
將當前節(jié)點設置為 node_id 指定的節(jié)點的從節(jié)點。 8. CLUSTER SAVECONFIG 將節(jié)點的配置文件保存到硬盤里面。 9. 10. //槽(slot) 11. CLUSTER ADDSLOTS [slot ...] 將一個或多個槽(slot)指派(assign)給當前節(jié)點。 12. CLUSTER DELSLOTS [slot ...] 移除一個或多個槽對當前節(jié)點的指派。 13. CLUSTER FLUSHSLOTS 移除指派給當前節(jié)點的所有槽,讓當前節(jié)點變成一個沒有指派任何槽的節(jié)點。 14. CLUSTER SETSLOT NODE
將槽 slot 指派給 node_id 指定的節(jié)點,如果槽已經(jīng)指派給另一個節(jié)點,那么先讓另一個節(jié)點刪除該槽>,然后再進行指派。 15. CLUSTER SETSLOT MIGRATING
將本節(jié)點的槽 slot 遷移到 node_id 指定的節(jié)點中。 16. CLUSTER SETSLOT IMPORTING
從 node_id 指定的節(jié)點中導入槽 slot 到本節(jié)點。 17. CLUSTER SETSLOT STABLE 取消對槽 slot 的導入(import)或者遷移(migrate)。 18. 19. //鍵 (key) 20. CLUSTER KEYSLOT 計算鍵 key 應該被放置在哪個槽上。 21. CLUSTER COUNTKEYSINSLOT 返回槽 slot 目前包含的鍵值對數(shù)量。 22. CLUSTER GETKEYSINSLOT 返回 count 個 slot 槽中的鍵。
2. 配置文件
開啟cluster的redis必須是空服務器
修改redis.conf開啟cluster
img
設置3個cluster
10.24.6.7:6379
10.24.6.4:6379
10.24.6.6:6379
3. 查看初始redis集群狀態(tài)
啟動三個節(jié)點上的Redis服務器。此時,三個Redis服務器節(jié)點均會以Redis Cluster的方式開始運行,但并沒有自動構建集群,因為三者還處于“我不認識你,你不屬于我”的狀態(tài),它們每個都是孤零零的Redis節(jié)點,或者是只包含了一個節(jié)點的集群。我們可以通過Redis客戶端連接到服務器查看它們的狀態(tài),圖一給出了狀態(tài)查詢方法和查詢結果,其中cluster nodes命令用于查看當前Redis節(jié)點所屬的Redis集群中的所有節(jié)點,而cluster info則用于查看當前Redis節(jié)點所屬的Redis集群的整體狀態(tài)。由圖中我們可以看到,Redis集群中僅包含一個Redis節(jié)點,也就是當前節(jié)點,整個集群的狀態(tài)是fail。
img
4. 分配hash slot
通過上面的操作,我們已經(jīng)將三個各自為政的Redis節(jié)點規(guī)劃到一個相同的集群中,那么我們現(xiàn)在是否就已經(jīng)完成了集群搭建的所有工作了呢?非也!通過圖二中對集群狀態(tài)的查看我們可以知道,當前集群的狀態(tài)還是fail,此時的Redis集群是不工作的,無法處理任何Redis命令。那么集群的狀態(tài)為什么還是fail呢?本博主通過查看官方文檔說明找到了原因所在,現(xiàn)摘錄原文如下:
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狀態(tài)的原因不是第二個條,也就是說至少有一個hash slot沒有被服務!稍微考慮一下,可不是!何止有一個hash slot沒有被服務,壓根兒就沒有Redis節(jié)點為任何hash slot服務!眾所周知,Redis Cluster通過hash slot將數(shù)據(jù)根據(jù)主鍵來分區(qū),所以一條key-value數(shù)據(jù)會根據(jù)算法自動映射到一個hash slot,但是一個hash slot存儲在哪個Redis節(jié)點上并不是自動映射的,是需要集群管理者自行分配的。那么我們需要為多少個hash slot分配Redis節(jié)點呢?根據(jù)源碼可知是16384個,即我們要將16384個hash slot分配到集群內(nèi)的三個節(jié)點上。Redis中用于分配hash slot的命令有很多,其中包括cluster addslots、cluster delslots和cluster setslot。鑒于我們現(xiàn)在是集群的初始化階段,所以我們可以選擇cluster addslots來分配hash slot,該命令的語法為cluster addslots slot1 [slot2] … [slotN]。
4.1. nodes-6379.conf分配
每個redis客戶端單獨分配自己負責的部分
修改內(nèi)容如下:cda76a0a094d2ce624e33bed7f3c75689a4128fd :0 myself,master – 0 0 connected 0-5000(注意是在自身節(jié)點的描述,也就是包含了myself那一行的后面追加hash slot的范圍)。類似的,Redis Cluster Node2上nodes-6379.conf文件中追加5001-10000,Redis Cluster Node3上nodes-6379.conf文件中追加10001-16383。經(jīng)過這樣的配置后,Redis Cluster Node1負責存儲0至5000之間的所有hash slots,Redis Cluster Node2負責存儲5001至10000之間的所有hash slots,Redis Cluster Node3負責存儲10001至16383的所有hash slots。
img
4.2. Redis cluster 命令分配
img
5. 搭建Redis集群
這里所謂的搭建集群,說白了就是讓之前啟動的三個Redis節(jié)點彼此連通,意識到彼此的存在,那么如何做到這一點呢?答案就是cluster meet命令。該命令的作用就是將當前節(jié)點主動介紹給另外一個節(jié)點認識,圖二給出了cluster meet命令的執(zhí)行方法和執(zhí)行效果,由圖中可知我們使用cluster meet命令分別將Redis Cluster Node1介紹給了Redis Cluster Node2(節(jié)點IP地址為192.168.32.3,運行端口為6379)和Redis Cluster Node3(節(jié)點IP地址為192.168.32.4,運行端口為6379),之后我們再次查看集群節(jié)點和集群狀態(tài)就可以知道,三個節(jié)點已經(jīng)成功合并到了同一個集群中。
img
這里找到了3個節(jié)點
查看10.24.6.6客戶端
img
至此,3個結點
img
搭建完成標識:
img
在集群狀態(tài)顯示為ok之后,我們就可以像在Redis單機版上一樣執(zhí)行Redis命令了。
6. 測試
6.1. 非集群模式
6.1.1. Redis-cli
img
img
非集群模式客戶端在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(‘a(chǎn)aaaaaaaaaaaaaa’, ‘bar’)
master.set(‘bbbbbbbbbbbbbbbb’, ‘bar’)
print master.get(‘a(chǎn)aaaaaaaaaaaaaa’)
print master.get(‘bbbbbbbbbbbbbbbb’)
Traceback (most recent call last):
File “E:/HomeInternet/server/utest_workspace/utest_utils/utest_unit/init.py”, line 23, in
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
img
集群模式客戶端在跳轉時會自動進行結點轉向
6.2.2. Redis 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”)
img
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”)
**
分享文章:Linux中部署Redis集群:RedisCluster
當前鏈接:http://m.fisionsoft.com.cn/article/cogosoo.html


咨詢
建站咨詢
