在centos上搭建redis集群并附测试(真集群非伪集群)
環(huán)境:centos6.5 x86 32位 redis3.2.8 ruby-2.2.3
一. redis集群原理
redis是單線程,但是一般的作為緩存使用的話,redis足夠了,因?yàn)樗淖x寫速度太快了。
官方的一個(gè)簡(jiǎn)單測(cè)試:
測(cè)試完成了50個(gè)并發(fā)執(zhí)行100000個(gè)請(qǐng)求。
設(shè)置和獲取的值是一個(gè)256字節(jié)字符串。
結(jié)果:讀的速度是110000次/s,寫的速度是81000次/s
在這么快的讀寫速度下,對(duì)于一般程序來說足夠用了,但是對(duì)于訪問量特別大的網(wǎng)站來說,還是稍有不足。
那么,如何提升redis的性能呢?看標(biāo)題就知道了,搭建集群。
先來一張redis集群的架構(gòu)圖:
然后就可以訪問集群中的任何一個(gè)節(jié)點(diǎn)。對(duì)其進(jìn)行存取和其他操作。
那么redis是怎么做到的呢?首先,在redis的每一個(gè)節(jié)點(diǎn)上,都有這么兩個(gè)東西,一個(gè)是插槽(slot)可以理解為是一個(gè)可以存儲(chǔ)兩個(gè)數(shù)值的一個(gè)變量。
這個(gè)變量的取值范圍是:0-16383。還有一個(gè)就是cluster我個(gè)人把這個(gè)cluster理解為是一個(gè)集群管理的插件。當(dāng)我們的存取的key到達(dá)的時(shí)候,
redis會(huì)根據(jù)crc16的算法得出一個(gè)結(jié)果,然后把結(jié)果對(duì) 16384 求余數(shù),這樣每個(gè) key 都會(huì)對(duì)應(yīng)一個(gè)編號(hào)在 0-16383 之間的哈希槽,
通過這個(gè)值,去找到對(duì)應(yīng)的插槽所對(duì)應(yīng)的節(jié)點(diǎn),然后直接自動(dòng)跳轉(zhuǎn)到這個(gè)對(duì)應(yīng)的節(jié)點(diǎn)上進(jìn)行存取操作。
還有就是因?yàn)槿绻旱脑?#xff0c;是有好多個(gè)redis一起工作的,那么,就需要這個(gè)集群不是那么容易掛掉,所以呢,理論上就應(yīng)該給集群中的每個(gè)節(jié)點(diǎn)至少一個(gè)備用的redis服務(wù)。
這個(gè)備用的redis稱為從節(jié)點(diǎn)(slave)。那么這個(gè)集群是如何判斷是否有某個(gè)節(jié)點(diǎn)掛掉了呢?
首先要說的是,每一個(gè)節(jié)點(diǎn)都存有這個(gè)集群所有主節(jié)點(diǎn)以及從節(jié)點(diǎn)的信息。
它們之間通過互相的ping-pong判斷是否節(jié)點(diǎn)可以連接上。如果有一半以上的節(jié)點(diǎn)去ping一個(gè)節(jié)點(diǎn)的時(shí)候沒有回應(yīng),集群就認(rèn)為這個(gè)節(jié)點(diǎn)宕機(jī)了,
然后去連接它的備用節(jié)點(diǎn)。如果某個(gè)節(jié)點(diǎn)和所有從節(jié)點(diǎn)全部掛掉,我們集群就進(jìn)入faill狀態(tài)。還有就是如果有一半以上的主節(jié)點(diǎn)宕機(jī),那么我們集群同樣進(jìn)入發(fā)力了狀態(tài)。
這就是我們的redis的投票機(jī)制,具體原理如下圖所示:
(1)投票過程是集群中所有master參與,如果半數(shù)以上master節(jié)點(diǎn)與master節(jié)點(diǎn)通信超時(shí)(cluster-node-timeout),認(rèn)為當(dāng)前master節(jié)點(diǎn)掛掉.
(2):什么時(shí)候整個(gè)集群不可用(cluster_state:fail)?
a:如果集群任意master掛掉,且當(dāng)前master沒有slave.集群進(jìn)入fail狀態(tài),也可以理解成集群的slot映射[0-16383]不完整時(shí)進(jìn)入fail狀態(tài).
ps : redis-3.0.0.rc1加入cluster-require-full-coverage參數(shù),默認(rèn)關(guān)閉,打開集群兼容部分失敗.
b:如果集群超過半數(shù)以上master掛掉,無論是否有slave,集群進(jìn)入fail狀態(tài).
二 . 集群安裝配置
2.1 安裝配置redis
此步省略,請(qǐng)參考我到博文【http://blog.csdn.net/wx5040257/article/details/78347729】【http://blog.csdn.net/wx5040257/article/details/78388588】我準(zhǔn)備的服務(wù)器ip及各服務(wù)器角色如下圖所示:
各節(jié)點(diǎn)間互聯(lián)互通,master和slave由創(chuàng)建集群時(shí)確定。
2.2 安裝cluster依賴環(huán)境
只需在任意一臺(tái)主機(jī)上(如169.254.130.122)安裝即可。
建議進(jìn)行源碼安裝。
2.2.1 安裝ruby
解壓縮源碼包,并移動(dòng)到/usr/local/src目錄下tar -zxf
mv ruby-2.2.3 /usr/local/src/ruby
進(jìn)入源碼目錄進(jìn)行安裝cd /usr/local/src/ruby
./configure
make && make install
安裝完畢后如圖所示:
提示系統(tǒng)缺失zlib,可能后續(xù)還要安裝zlib包,請(qǐng)繼續(xù)往下看。可用ruby -v命令查看安裝成功的ruby版本。
2.2.2 安裝ruby redis接口
gem install redis
報(bào)錯(cuò),如圖所示:
解決方案,安裝zlib-dev,yum命令安裝即可
yum -y install zlib-devel
然后進(jìn)入ruby源碼文件夾
安裝ruby自身提供的zlib包
#cd ext/zlib
#ruby ./extconf.rb
#make
#make install
接下來再執(zhí)行
gem install redis
又報(bào)錯(cuò),如下所示:
[root@localhost zlib]# gem install redisERROR: While executing gem ... (Gem::Exception)Unable to require openssl, install OpenSSL and rebuild ruby (preferred) or use non-HTTPS sources原因:
缺少openssl,需要安裝openssl包,我現(xiàn)在這里來安裝一個(gè)openssl-1.0.1s.tar.gz(下載鏈接:http://www.openssl.org/source/)
解決方法步驟:
1.解壓在/usr/local/src目錄下,進(jìn)入/usr/local/src/openssl目錄準(zhǔn)備安裝:
openssl的配置文件必須要配置-fPIC參數(shù),如果沒有該參數(shù)下面的安裝中會(huì)出現(xiàn)問題!
安裝完成,可以檢測(cè)一下是否安裝成功:
2.進(jìn)入ruby源碼[/usr/local/src/ruby]目錄下的ext/openssl 目錄:
[root@localhost openssl]# cd ../ruby-2.3.0 [root@localhost ruby]# cd ext/openssl [root@localhost openssl]# ruby extconf.rb checking for t_open() in -lnsl... no checking for socket() in -lsocket... no checking for assert.h... yes checking for openssl/ssl.h... no提示沒有找到ssl.h, 因?yàn)槌霈F(xiàn)了錯(cuò)誤:openssl/ssl.h … no ,輸入如下代碼,重新執(zhí)行:
# ruby extconf.rb --with-openssl-include=/usr/local/openssl/include/ --with-openssl-lib=/usr/local/openssl/lib
ok,成功
3.接下來并且將ruby 源碼目錄下的include目錄軟鏈接到 / 目錄下:
ln -s /usr/local/src/ruby/include /
注意:創(chuàng)建軟鏈的時(shí)候一定要寫全路徑,不能寫相對(duì)路徑
再次使用gem install 安裝 ruby redis 接口:
gem install redis
仍然報(bào)錯(cuò):
[root@localhost openssl]# gem install redisERROR: Could not find a valid gem 'redis' (>= 0), here is why:Unable to download data from https://rubygems.org/ - SSL_connect returned=1 errno=0 state=error: certificate verify failed (https://api.rubygems.org/specs.4.8.gz)意思上無法自動(dòng)下載rubygems安裝,那好吧,我們自己下載安裝,例如我下載的是:redis-3.2.1.gem
[root@localhost soft]# gem install redis-3.2.1.gem Successfully installed redis-3.2.1Parsing documentation for redis-3.2.1Installing ri documentation for redis-3.2.1Done installing documentation for redis after 1 secondsWARNING: Unable to pull data from 'https://rubygems.org/': SSL_connect returned=1 errno=0 state=error: certificate verify failed (https://api.rubygems.org/specs.4.8.gz)1 gem installed
ok,安裝成功了!
2.3 接下來進(jìn)行集群的創(chuàng)建
vi /usr/redis/redis.conf
cluster-enabled yes ==>表示開啟集群功能
cluster-config-file nodes-6379.conf ====>表示自動(dòng)生成的集群配置文件
cluster-node-timeout 15000====> 表示集群節(jié)點(diǎn)連接超時(shí)時(shí)間
創(chuàng)建集群環(huán)境的命令格式為redis-trib.rb create --replicas masterNode1,masterNode2,masterNodeN,slaveNode1,slaveNode2,slaveNodeN
Node的格式為"IP:port",slaveCount表示每個(gè)masterNode對(duì)應(yīng)的slaveNode個(gè)數(shù),在集群環(huán)境中可以沒有slave(在命令中省略掉slaveNode部分即可)。
但如果有slave,則命令中,前n中個(gè)節(jié)點(diǎn)都為master,后n個(gè)節(jié)點(diǎn)都為slave,第n個(gè)master節(jié)點(diǎn)對(duì)應(yīng)的slave應(yīng)該是第n個(gè)。
注意:創(chuàng)建集群前,每個(gè)節(jié)點(diǎn)到數(shù)據(jù)都要清空,用flushall命令
127.0.0.1:6379 > flushall執(zhí)行命令創(chuàng)建集群:
redis-trib.rb create --replicas 1 169.254.130.122:6379 169.254.130.10:6379 169.254.130.20:6379 169.254.130.12:6379 169.254.130.11:6379 169.254.130.25:6379注意:這條命令沒有跨行
出現(xiàn)如下提示信息:
從上面可看出,六個(gè)節(jié)點(diǎn)都處于"OK"狀態(tài),并且前三個(gè)6379端口的都為master,而都三個(gè)6379端口的都為slave。
此時(shí)出現(xiàn)提示,鍵入yes后,各節(jié)點(diǎn)將會(huì)進(jìn)行互聯(lián)操作
輸入yes,接下來報(bào)錯(cuò)了:
錯(cuò)誤提示是
slot插槽被占用了(這是 搭建集群前時(shí),以前redis的舊數(shù)據(jù)和配置信息沒有清理干凈。)
解決方案是
用redis-cli 登錄到每個(gè)節(jié)點(diǎn)執(zhí)行 flushall 和 cluster reset 就可以了。
然后重新執(zhí)行創(chuàng)建集群的命令:
redis-trib.rb create --replicas 1 169.254.130.122:6379 169.254.130.10:6379 …(省略)
接下來又卡住了,如下:
Can I set the above configuration? (type 'yes' to accept): yesNodes configuration updatedAssign a different config epoch to each nodeSending CLUSTER MEET messages to join the clusterWaiting for the cluster to join...................................................................................................................................................................................................................................................................原因:
redis集群不僅需要開通redis客戶端連接的端口,而且需要開通集群總線端口
集群總線端口為redis客戶端連接的端口 + 10000
如redis端口為6379
則集群總線端口為16379
故,所有服務(wù)器的點(diǎn)需要開通redis的客戶端連接端口和集群總線端口
注意:iptables 放開,如果有安全組,也要放開這兩個(gè)端口
受不了啦,把所有節(jié)點(diǎn)的防火墻全部關(guān)閉算了。重新執(zhí)行創(chuàng)建集群的命令,這回成功了:
從上面可看出16384個(gè)哈希槽已均勻分配給了三個(gè)master節(jié)點(diǎn),分別為:
169.254.130.20:6379(10923-16384)
169.254.130.10:6379(5461-10922)
169.254.130.122:6379(0-5460)
大功告成!!!
2.5 進(jìn)行測(cè)試
登錄122主機(jī),用redis-cli -c命令
-c命令在連接集群結(jié)點(diǎn)時(shí)使用,此選項(xiàng)可防止moved和ask異常。
[root@localhost redis]# redis-cli -c127.0.0.1:6379> set key1 "hello redis cluster"-> Redirected to slot [9189] located at 169.254.130.10:6379OK169.254.130.10:6379> set key2 java-> Redirected to slot [4998] located at 169.254.130.122:6379OK169.254.130.122:6379> 169.254.130.122:6379> keys *1) "key2"169.254.130.122:6379> get key2"java"169.254.130.122:6379> get key1-> Redirected to slot [9189] located at 169.254.130.10:6379"hello redis cluster"169.254.130.10:6379> get key20-> Redirected to slot [905] located at 169.254.130.122:6379"html"169.254.130.122:6379>從中可以發(fā)現(xiàn)存時(shí)是分布式存儲(chǔ),取時(shí)也是從集群中取,測(cè)試成功
總結(jié)
以上是生活随笔為你收集整理的在centos上搭建redis集群并附测试(真集群非伪集群)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: redis的安全性及客户端工具的使用
- 下一篇: Java连接Redis及操作(一)