1. 程式人生 > >Redis cluster的配置過程

Redis cluster的配置過程

    當訪問量比較大,使用到redis叢集的時候,就需要面臨一個問題,讀寫分離。這就意味要麼客戶端知道主節點是哪個節點,從節點是哪些節點?要麼就是,中間加一個代理,來實現主從複製的要求。Redis叢集的方案有很多,此處介紹redis官方給出的方案,推薦使用。

    基於分片。一個 Redis cluster叢集包含 16384 個雜湊槽, 任意一個key都可以通過 CRC16(key) % 16384 這個公式計算出應當屬於哪個槽。每個槽應當落在哪個節點上,也是事先定好。這樣,進行任一操作時,首先會根據key計算出對應的節點,然後操作相應的節點就可以了。所以說,其實cluster跟單點相比,只是多了一個給key計算sharding值的過程,並沒有增加多少複雜度,個人認為完全可以放心使用。像增刪節點、重啟這些對redis本身的操作,和client端對資料的操作,是兩套流程,可以做到互不干擾。關於節點故障,一是有slave,二是即便這一個節點完全掛掉,也只是落在這個節點上的資料不可用,不會有類似"雪崩"這樣的問題影響整個叢集。資料的恢復之類的邏輯,也與單點完全一致,是獨立於叢集其他部分的。redis cluster的整個設計是比較簡單的,並沒有引入太多新問題,大部分操作都可以按照單點的操作流程進行操作。至於cluster最終的易用性,其實很大程度上取決client端的程式碼可靠性,而jedis現在的程式碼也已經很完善了,用起來也比較方便。

優點:無中心的P2P Gossip分散式模式,更少的來回次數並降低延遲,自動在多個節點進行分片,不需要第三方軟體支援協調機制;缺點:依賴於redis 3,0或更高的版本,沒有後臺介面,需要智慧客戶端,Redis客戶端必須支援Redis Cluster架構,教Codis有更多的維護升級成本;

叢集檔案配置:

cluster-enabled:是否啟用叢集環境,預設註釋掉的;

cluster-config-file:cluster叢集配置檔案,該檔案不需要有東西,叢集會自己寫,但是必須要有該檔案,預設註釋掉了。該檔案,預設放置在etc目錄下;

cluster-node-timeout:判斷節點是否故障的超時時長,預設被註釋;

cluster-slave-validity-factor 進行故障轉移時,salve會申請成為master。有時slave會和master失聯很久導致資料較舊,這樣的slave不應該成為master。這個配置用來判斷slave是否和master失聯時間過長。

實驗:實現redis叢集

三臺主機,node1,node2,node3;實現redis-cluster;

在三個節點上執行:

vim /etc/redis.conf

bind 0.0.0.0

cluster-enabled yes

cluster-config-file nodes-6379.conf

cluster-node-timeout 15000

cluster-slave-validity-factor 10

systemctl start redis

node1節點:

systemctl start redis

ss -ntl

redis-cli

127.0.0.1:6379> config get cluster-enabled

    (empty list or set)

127.0.0.1:6379> cluster info

    cluster_state:fail        # 叢集的狀態;

    cluster_slots_assigned:0

    cluster_slots_ok:0

    cluster_slots_pfail:0

    cluster_slots_fail:0

    cluster_known_nodes:1

    cluster_size:0

    cluster_current_epoch:0

    cluster_my_epoch:0

    cluster_stats_messages_sent:0

    cluster_stats_messages_received:0

127.0.0.1:6379> exit

for i in {0..5461};do redis-cli cluster addslots $i;done        # 新增雜湊槽;

node2節點:

systemctl restart redis

ss -ntl

for i in {5462..10922};do redis-cli cluster addslots$i;done    # 新增雜湊槽;

node3節點:

systemctl restart redis

ss -ntl

for i in {10923..16384};do redis-cli cluster addslots $i;done    # 新增雜湊槽

node2節點:

for i in {1..20};do redis-cli set key$i value$i;done        # 新增資料,測試效果;

    OK

    (error) MOVED 4998 192.168.109.7:6379

    (error) MOVED 935 192.168.109.7:6379

    (error) MOVED 13120 192.168.109.6:6379

    OK

    (error) MOVED 4866 192.168.109.7:6379

    ……

node1節點:

redis-cli

127.0.0.1:6379> cluster meet 192.168.109.6

    (error) ERR Wrong CLUSTER subcommand or number of arguments

127.0.0.1:6379> cluster meet 192.168.109.6 6379    # 新增叢集;

    OK

127.0.0.1:6379> cluster meet 192.168.109.8 6379    # 新增叢集;

    OK

127.0.0.1:6379> cluster info        # 檢視叢集的狀態;

    cluster_state:ok            # 叢集配置成功

    cluster_slots_assigned:16384

    cluster_slots_ok:16384

    cluster_slots_pfail:0

    cluster_slots_fail:0    

    cluster_known_nodes:3

    cluster_size:3

    cluster_current_epoch:2

    cluster_my_epoch:2

    cluster_stats_messages_sent:29

    cluster_stats_messages_received:29

127.0.0.1:6379> cluster nodes    # 檢視叢集的節點;

    b22df3f9965c33375956887de1bf17483fc1d58f 192.168.109.8:6379 master - 0 1513168145410 0 connected 5462-10922

    11e6acb0b53841b276c1ffed1913f6e3d16ee15c 192.168.109.6:6379 master - 0 1513168144401 1 connected 10923-16383

    94b161eea14d5eb7ed99e1f71c79cea980330ae2 192.168.109.7:6379 myself,master - 0 0 2 connected 0-5461

127.0.0.1:6379> get key1    

    (error) MOVED 9189 192.168.109.8:6379        # 在節點1上,檢視key1的值,因為該值不在此處存放,所以,node1反饋給客戶端,資料的地址。在生產環境中,使用的是智慧裝置,它會自己去訪問,此處沒辦法模擬。

127.0.0.1:6379> get key2

    (nil)

127.0.0.1:6379> get key3

    (nil)

node2節點:

redis-cli

127.0.0.1:6379> get key1

    "value1"

127.0.0.1:6379> get key2

    (error) MOVED 4998 192.168.109.7:6379

注意:在工作環境中,還需要使用主從備份。此處由於沒有多餘的機器,沒有設定從屬節點;可以使用多例項技術。