Redis Cluster 初探(1) - 叢集搭建與擴容

來源:互聯網
上載者:User

轉:http://www.jianshu.com/p/bd7bf38d9b87

Redis Cluster 初探(1) - 叢集搭建與擴容 字數2278 閱讀154 評論0 喜歡2

Redis Cluster是Redis官方的叢集實現方案,在此之前已經有一些民間的第三方Redis叢集解決方案,如Twitter的Twenproxy,豌豆莢的Codis,與其不同的是,Redis Cluster並非使用Porxy的模式來串連叢集節點,而是使用無中心節點的模式來組建叢集,有一定效能優勢也有缺點,本文主要是我調研Redis Cluster的一些知識整理與經驗匯總。

首先我們來嘗試下搭建一個Redis Cluster叢集 前置準備

Redis Cluster需要Redis 3.0及以上版本才支援,此文發布的時候,Redis的最高版本為3.0.5。

wget http://download.redis.io/releases/redis-3.0.5.tar.gztar -xvf redis-3.0.5.tar.gzcd redis-3.0.5make

編譯完Redis,產生的可執行檔在redis-3.0.5/src之中,為了方便使用,我們把可執行檔的目錄加入PATH之中。

vim ~/.bashrc# 增加以下內容REDIS_HOME=/home/xiezefan/sofeware/redis-3.0.5/srcPATH=$REDIS_HOME:$PATHexport PATH# 儲存後讓修改生效source ~/.bashrc

要建立Redis Cluster,我們還需要安裝Ruby以及RubyGems。

yum install rubyyum install gcc g++ make automake autoconf curl-devel openssl-devel zlib-devel httpd-devel apr-devel apr-util-devel sqlite-develyum install ruby-rdoc ruby-develyum install rubygemsgem install redis
建立叢集

此次此時我們需要建立8個節點,連接埠號碼7000~7007

複製redis-3.0.5/redis.conf,修改一下內容

mkdir clustercp ~/sofeware/redis-3.0.5/redis.conf cluster/vim cluster/redis.conf# 修改以下內容port 7000cluster-enabled yescluster-config-file nodes.confcluster-node-timeout 5000appendonly yes

批量複製7份,修改設定檔的連接埠號碼。修改完畢後,分別進入各個節點的目錄中啟動redis

cd 7000redis-server redis.confcd 7001redis-server redis.conf# 依次啟動7000-7007...

至此,8個Redis全都啟動完畢,但是他們還處於彼此互相不知道彼此的階段。

xiezefan@ubuntu:~$ ps -ef | grep redisxiezefan 13372     1  0 20:09 ?        00:00:08 redis-server *:7000 [cluster]xiezefan 13376     1  0 20:09 ?        00:00:08 redis-server *:7001 [cluster]xiezefan 13380     1  0 20:09 ?        00:00:08 redis-server *:7002 [cluster]xiezefan 13382     1  0 20:09 ?        00:00:08 redis-server *:7003 [cluster]xiezefan 13386     1  0 20:09 ?        00:00:08 redis-server *:7004 [cluster]xiezefan 13390     1  0 20:09 ?        00:00:08 redis-server *:7005 [cluster]xiezefan 13394     1  0 20:09 ?        00:00:08 redis-server *:7006 [cluster]xiezefan 13400     1  0 20:09 ?        00:00:08 redis-server *:7007 [cluster]

下一步,我們要將7000-7005這六個節點串連成一個叢集。

redis-trib.rb create --replicas 1 10.211.55.4:7000 10.211.55.4:7001 10.211.55.4:7002 10.211.55.4:7003 10.211.55.4:7004 10.211.55.4:7005

該命令表示,將7000-7006節點建立一個叢集,冗餘為1,就是3主3從。切記,此處指定的IP會在client發送move命令的時候返回,所以一定要指定為用戶端能訪問到的IP,例如下面這種IP是不可行的,client拿到的IP就位是127.0.0.1導致一直重新導向失敗。

redis-trib.rb create --replicas 1 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005

輸入後,redis-trib自動分配給出一個slot的分配方案

>>> Performing hash slots allocation on 6 nodes...Using 3 masters:10.211.55.4:700010.211.55.4:700110.211.55.4:7002Adding replica 10.211.55.4:7003 to 10.211.55.4:7000Adding replica 10.211.55.4:7004 to 10.211.55.4:7001Adding replica 10.211.55.4:7005 to 10.211.55.4:7002M: 9dfef549f7917794cbabaf96781ed0e19957c1f3 10.211.55.4:7000   slots:0-5460 (5461 slots) masterM: c14485e8d7f1f3ec5c505b41fe727b657c951d8d 10.211.55.4:7001   slots:5461-10922 (5462 slots) masterM: 8b308093e99f4299b8c18ab1dd81c5a83a3528c6 10.211.55.4:7002   slots:10923-16383 (5461 slots) masterS: 632409883570eb5cecf6089583fba64a41d1154f 10.211.55.4:7003   replicates 9dfef549f7917794cbabaf96781ed0e19957c1f3S: edd31196e2980360b0738c57af95e1a69b0f9c9b 10.211.55.4:7004   replicates c14485e8d7f1f3ec5c505b41fe727b657c951d8dS: 95063a99c5cf2cc4abc51ca1e8ff0f3b8d60271c 10.211.55.4:7005   replicates 8b308093e99f4299b8c18ab1dd81c5a83a3528c6Can I set the above configuration? (type 'yes' to accept):

輸入yes後,叢集自動建立,建立完畢後,通過redis-cli進入任一節點,使用cluster nodes命令可以查看各個節點的狀態

xiezefan@ubuntu:~$ redis-cli -p 7000127.0.0.1:7000>cluster nodesc14485e8d7f1f3ec5c505b41fe727b657c951d8d 10.211.55.4:7001 master - 0 1449060968280 2 connected 5461-1092295063a99c5cf2cc4abc51ca1e8ff0f3b8d60271c 10.211.55.4:7005 slave 8b308093e99f4299b8c18ab1dd81c5a83a3528c6 0 1449060968280 6 connectededd31196e2980360b0738c57af95e1a69b0f9c9b 10.211.55.4:7004 slave c14485e8d7f1f3ec5c505b41fe727b657c951d8d 0 1449060967274 5 connected8b308093e99f4299b8c18ab1dd81c5a83a3528c6 10.211.55.4:7002 master - 0 1449060966769 3 connected 10923-16383632409883570eb5cecf6089583fba64a41d1154f 10.211.55.4:7003 slave 9dfef549f7917794cbabaf96781ed0e19957c1f3 0 1449060967274 4 connected9dfef549f7917794cbabaf96781ed0e19957c1f3 10.211.55.4:7000 myself,master - 0 0 1 connected 0-5460

隨便輸入一個查詢指令get user.1

127.0.0.1:7000> get user.1(error) MOVED 9645 10.211.55.4:7001

因為user.1所在的solt-9645在7001節點上,cluster給你發送MOVED指令讓你去7001節點尋找資料,串連redis-cli的時候,使用-c參數可以指定查詢時接收到MOVED指令自動跳轉

xiezefan@ubuntu:~$ redis-cli -c -p 7000127.0.0.1:7000> get user.1-> Redirected to slot [9645] located at 10.211.55.4:7001(nil)
叢集擴容

現在我們已經有一個包含6個節點的叢集,我寫了段代碼,往叢集寫入10W條測試資料。
現在類比機器擴容情境,為叢集加入一個master節點7006和一個slave節點7007。

redis-trib.rb add-node 10.211.55.4:7006 10.211.55.4:7000

以上命令將7006節點接入7000所在的叢集。接下來,我們為7006增加一個slave節點。

redis-trib.rb add-node --slave 10.211.55.4:7007 10.211.55.4:7000

以上命令表示增加slave節點,將7006的節點加入7000節點所在的叢集中作為slave節點,隨機依附現有的master節點中slave最少的節點,如果需要再指定特別的master節點,使用

redis-trib.rb add-node --slave --master-id 23b412673af0506df6382353e3a65960d5b7e66d 10.211.55.4:7007 10.211.55.4:7000

其中的23b412673af0506df6382353e3a65960d5b7e66d是7006節點的id,我們可以通過cluster nodes命令查看節點的id。

接下來我們用坐負載平衡,Slot是Redis Cluster資料承載的最小單位,我們可以指定將一定範圍的Slot轉移到新的節點來實現負載平衡。

Redis Cluster轉移一個Slot的步驟是: 在目標節點上聲明將從源節點上遷入Slot CLUSTER SETSLOT <slot> IMPORTING <source_node_id> 在源節點上聲明將往目標節點遷出Slot CLUSTER SETSLOT <slot> IMPORTING <source_node_id> 批量從源節點擷取KEY CLUSTER GETKEYSINSLOT <slot> <count> 將擷取的Key遷移到目標節點 MIGRATE <target_ip> <target_port> <key_name> 0 <timeout> 重複步驟3,4直到所有資料移轉完畢 分別向雙方節點發送 CLUSTER SETSLOT <slot> NODE <target_node_id>,該命令將會廣播給叢集其他節點,已經將Slot轉移到目標節點。 等待叢集狀態變為OK CLUSTER INFO 中的 cluster_state = ok

我編寫了一個指令碼來批量遷移Slot

#!/bin/bashsource_host=$1  # 源節點HOSTsource_port=$2  # 源節點連接埠target_host=$3  # 目標節點HOSTtarget_port=$4  # 目標節點連接埠start_slot=$5   # 遷移節點的其實範圍end_slot=$6     # 遷移節點的結束範圍for slot in `seq ${start_slot} ${end_slot}`do    redis-cli -c -h ${target_host} -p ${target_port} cluster setslot ${slot} importing `redis-cli -c -h ${source_host} -p ${source_port} cluster nodes | grep ${source_port} | awk '{print $1}'`    echo "Setslot importing ${slot} to ${target_host}:${target_port} success"    redis-cli -c -h ${source_host} -p ${source_port} cluster setslot ${slot} migrating `redis-cli -c -h ${target_host} -p ${target_port} cluster nodes | grep ${target_port} | awk '{print $1}'`    echo "Setslot migrating ${slot} from ${source_host}:${source_port} success"    while [ 1 -eq 1 ]    do        allkeys=`redis-cli -c -h ${source_host} -p ${source_port} cluster getkeysinslot ${slot} 10`        if [ -z "${allkeys}" ]        then            redis-cli -c -h ${source_host} -p ${source_port} cluster setslot ${slot} node `redis-cli -c -h ${target_host} -p ${target_port} cluster nodes | grep ${target_port} | awk '{print $1}'`            redis-cli -c -h ${target_host} -p ${target_port} cluster setslot ${slot} node `redis-cli -c -h ${source_host} -p ${target_port} cluster nodes | grep ${target_port} | awk '{print $1}'`            echo "Migrate slot ${slot} finish"            break        else             for key in ${allkeys}            do                redis-cli -c -h ${source_host} -p ${source_port} migrate ${target_host} ${target_port} ${key} 0 5000                echo "Migrate slot ${slot} key ${key} success"            done        fi    donedone

執行命令 bash rebalance-cluster.sh 10.211.55.4 7000 10.211.55.4 7006 0 1000 將7000節點上0-1000這個範圍內的Slot轉移到7006節點,通過cluster nodes命令我們可以看到0-1000這個區間是slot已經從7000轉移到7006

xiezefan@ubuntu:~/sheel$ redis-cli -c -p 7000 cluster nodes23b412673af0506df6382353e3a65960d5b7e66d 10.211.55.4:7006 master - 0 1449064402389 7 connected 0-10000c2954d21d7bcdae333f4fdecf468ce05aa25544 10.211.55.4:7001 master - 0 1449064400372 2 connected 5461-10922384a3bb5bd9ecb2fc7db75c866abc715d7966f82 10.211.55.4:7002 master - 0 1449064401381 3 connected 10923-16383c3e09d286ef2dce49843268b20832d65a5d516a1 10.211.55.4:7004 slave 0c2954d21d7bcdae333f4fdecf468ce05aa25544 0 1449064401885 5 connected50737b4a91443ab1a34eec4ef99d4f6fe5d358f4 10.211.55.4:7005 slave 384a3bb5bd9ecb2fc7db75c866abc715d7966f82 0 1449064402389 6 connected3c62cc6664bba378cceb8ae8e02f5d727deafe9d 10.211.55.4:7007 slave 23b412673af0506df6382353e3a65960d5b7e66d 0 1449064400878 7 connectedd6441916dcd89cbf431465d92dfc0eb3dd235295 10.211.55.4:7003 slave 6ee21c5d93a6d2f293a2df1b37e8c9c27cb55ad8 0 1449064402389 4 connected6ee21c5d93a6d2f293a2df1b37e8c9c27cb55ad8 10.211.55.4:7000 myself,master - 0 0 1 connected 1001-5460
參考文章 全面剖析Redis Cluster原理和應用 Redis叢集功能預覽 Redis-Cluster實戰--8.Redis-Cluster水平擴容(redis-cli實現版) 談談陌陌爭霸在資料庫方面踩過的坑( Redis 篇)

本文首發: http://xiezefan.me/2015/12/03/redis_cluster_research_1/ Redis Cluster 初探(2) - 運行規制 - 簡書 — 上一篇文章我們說過,RedisCluster採用SmartClient的方式,避免與節點的通訊還需要通過一層Proxy,以達到效能地提升。SmartClient的優點與缺點網上也有很多人在討論,我們現在來瞭解下RedisClient的串連模式。RedisCluster是無中心節點的設計,Client可以串連叢集中的任一一個節點,當操作的Key不在該節點的Slot中的時候,如訪問在Slot-6433的Key,用戶端會返回一個(error)MOVED643310.211.55.4:7001這樣的錯誤資訊。Cl

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

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.