redis集群架構(gòu)圖
成都創(chuàng)新互聯(lián)公司自2013年起,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項(xiàng)目成都做網(wǎng)站、網(wǎng)站設(shè)計(jì)網(wǎng)站策劃,項(xiàng)目實(shí)施與項(xiàng)目整合能力。我們以讓每一個(gè)夢(mèng)想脫穎而出為使命,1280元河源做網(wǎng)站,已為上家服務(wù),為河源各地企業(yè)和個(gè)人服務(wù),聯(lián)系電話:18980820575
上圖藍(lán)色為redis集群的節(jié)點(diǎn)。
節(jié)點(diǎn)之間通過ping命令來測(cè)試連接是否正常,節(jié)點(diǎn)之間沒有主區(qū)分,連接到任何一個(gè)節(jié)點(diǎn)進(jìn)行操作時(shí),都可能會(huì)轉(zhuǎn)發(fā)到其他節(jié)點(diǎn)。
1、Redis的容錯(cuò)機(jī)制
節(jié)點(diǎn)之間會(huì)定時(shí)的互相發(fā)送ping命令,測(cè)試節(jié)點(diǎn)的健康狀態(tài),當(dāng)節(jié)點(diǎn)接受到ping命令后,會(huì)返回一個(gè)pong字符串。
投票機(jī)制:如果一個(gè)節(jié)點(diǎn)A給節(jié)點(diǎn)B發(fā)送ping沒有得到pong返回,會(huì)通知其他節(jié)點(diǎn)再次給B發(fā)送ping,如果集群中有超過一半的節(jié)點(diǎn)收不B節(jié)點(diǎn)的pong。那么就認(rèn)為B節(jié)點(diǎn)掛了。一般會(huì)為每個(gè)節(jié)點(diǎn)提供一個(gè)備份節(jié)點(diǎn),如果掛掉會(huì)切換到備份節(jié)點(diǎn)。
2、Redis集群存儲(chǔ)原理
Redis對(duì)于每個(gè)存放的key會(huì)進(jìn)行hash操作,生成一個(gè)[0-16384]的hash值(先進(jìn)行
crc 算法再對(duì)16384取余)。
集群的情況下,就是把[0-16384]的區(qū)間進(jìn)行拆分,放到不同的redis中。
3、Redis的持久化
Snapshotting:定時(shí)的將Redis內(nèi)存中的數(shù)據(jù)保存到硬盤中
AOF:將所有的command操作保存到aof中,AOP的同步頻率很高,數(shù)據(jù)即使丟失,粒度也很小,但會(huì)在性能上造成影響。
二、集群環(huán)境搭建
redis集群管理工具redis-trib.rb依賴ruby環(huán)境,首先需要安裝ruby環(huán)境
安裝ruby
yum install ruby yum install rubygems
安裝ruby和redis的接口程序
拷貝redis-3.0.0.gem至/usr/local下
執(zhí)行:
gem install /usr/local/redis-3.0.0.gem
三、創(chuàng)建Redis集群
在一臺(tái)服務(wù)器上,可以用不同端口號(hào)來表示不同redis服務(wù)器。
Redis集群最少需要三臺(tái)服務(wù)器,而每臺(tái)服務(wù)器有需要備用服務(wù)器,所以最少需要6臺(tái)服務(wù)器。端口規(guī)劃如下:
主服務(wù)器:192.168.100.66 :7001 :7002 :7003
從服務(wù)器:192.168.100.66 :7004 :7005 :7006
在/usr/local 創(chuàng)建文件夾用來存放服務(wù)器程序
mkdir 7001 7002 7003 7004 7005 7006
如果想讓redis支持集群需要修改redis.config配置文件的cluster-enabled yes
本例中我們以端口來區(qū)別不同的redis服務(wù),所以還需要修改redis.config的port為對(duì)應(yīng)端口
修改完配置文件,將redis安裝目錄的bin復(fù)制到上面每個(gè)目錄中。
分別進(jìn)入7001/bin/ 7002/bin .....
啟動(dòng)服務(wù)./redis-server ./redis.conf
查看redis進(jìn)程:ps -aux|grep redis 如下圖則說明啟動(dòng)成功
創(chuàng)建集群:
將之前解壓的文件夾的redis-3.0.0/src/redis-trib.rb復(fù)制到redis-cluster目錄
運(yùn)行
./redis-trib.rb create --replicas 1 192.168.100.66:7001 192.168.100.66:7002 192.168.100.66:7003 192.168.100.66:7004 192.168.100.66:7005 192.168.100.66:7006
如果執(zhí)行時(shí)報(bào)如下錯(cuò)誤:
[ERR] Node XXXXXX is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0
解決方法是刪除生成的配置文件nodes.conf,如果不行則說明現(xiàn)在創(chuàng)建的結(jié)點(diǎn)包括了舊集群的結(jié)點(diǎn)信息,需要?jiǎng)h除redis的持久化文件后再重啟redis,比如:appendonly.aof、dump.rdb
如果成功最終輸入如下:
查詢集群信息:
說明:
./redis-cli -c -h 192.168.101.3 -p 7001 ,其中-c表示以集群方式連接redis,-h指定ip地址,-p指定端口號(hào)
cluster nodes 查詢集群結(jié)點(diǎn)信息
cluster info 查詢集群狀態(tài)信息
hash槽重新分配
第一步:連接上集群
./redis-trib.rb reshard 192.168.101.3:7001(連接集群中任意一個(gè)可用結(jié)點(diǎn)都行)
第二步:輸入要分配的槽數(shù)量
輸入 500表示要分配500個(gè)槽
第三步:輸入接收槽的結(jié)點(diǎn)id
這里準(zhǔn)備給7007分配槽,通過cluster nodes查看7007結(jié)點(diǎn)id為15b809eadae88955e36bcdbb8144f61bbbaf38fb
輸入:15b809eadae88955e36bcdbb8144f61bbbaf38fb
第四步:輸入源結(jié)點(diǎn)id
這里輸入all
第五步:輸入yes開始移動(dòng)槽到目標(biāo)結(jié)點(diǎn)id
添加從節(jié)點(diǎn)
集群創(chuàng)建成功后可以向集群中添加節(jié)點(diǎn),下面是添加一個(gè)slave從節(jié)點(diǎn)。
添加7008從結(jié)點(diǎn),將7008作為7007的從結(jié)點(diǎn)。
./redis-trib.rb add-node --slave --master-id 主節(jié)點(diǎn)id 添加節(jié)點(diǎn)的ip和端口 集群中已存在節(jié)點(diǎn)ip和端口
執(zhí)行如下命令:
./redis-trib.rb add-node --slave --master-id cad9f7413ec6842c971dbcc2c48b4ca959eb5db4 192.168.101.3:7008 192.168.101.3:7001
cad9f7413ec6842c971dbcc2c48b4ca959eb5db4 是7007結(jié)點(diǎn)的id,可通過cluster nodes查看。
注意:如果原來該結(jié)點(diǎn)在集群中的配置信息已經(jīng)生成cluster-config-file指定的配置文件中(如果cluster-config-file沒有指定則默認(rèn)為nodes.conf),這時(shí)可能會(huì)報(bào)錯(cuò):
[ERR] Node XXXXXX is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0
解決方法是刪除生成的配置文件nodes.conf,刪除后再執(zhí)行./redis-trib.rb add-node指令
查看集群中的結(jié)點(diǎn),剛添加的7008為7007的從節(jié)點(diǎn):
刪除結(jié)點(diǎn):
./redis-trib.rb del-node 127.0.0.1:7005 4b45eb75c8b428fbd77ab979b85080146a9bc017
刪除已經(jīng)占有hash槽的結(jié)點(diǎn)會(huì)失敗,報(bào)錯(cuò)如下:
[ERR] Node 127.0.0.1:7005 is not empty! Reshard data away and try again.
需要將該結(jié)點(diǎn)占用的hash槽分配出去(參考hash槽重新分配章節(jié))。
測(cè)試:
Maven:redis.clients jedis 2.7.0 junit junit 4.12 test org.springframework spring-test 4.3.10.RELEASE test
普通測(cè)試:
@Test public void redisClusterTest1(){ JedisPoolConfig config=new JedisPoolConfig(); config.setMaxTotal(30); config.setMaxIdle(2); SetjedisNode=new HashSet (); jedisNode.add(new HostAndPort("192.168.100.66",7001)); jedisNode.add(new HostAndPort("192.168.100.66",7002)); jedisNode.add(new HostAndPort("192.168.100.66",7003)); jedisNode.add(new HostAndPort("192.168.100.66",7004)); jedisNode.add(new HostAndPort("192.168.100.66",7005)); jedisNode.add(new HostAndPort("192.168.100.66",7006)); JedisCluster jc=new JedisCluster(jedisNode,config); jc.set("name","老王"); String value=jc.get("name"); System.out.println(value); }
Spring測(cè)試:
配置文件:
測(cè)試類:
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration({"classpath:spring-config.xml"}) public class RedisClusterTest { @Autowired private JedisCluster jedisCluster; @Test public void redisClusterTest2(){ jedisCluster.set("username","小明啦啦"); String name=jedisCluster.get("username"); System.out.println(name); } }
以上就是redis分布式集群搭建介紹的詳細(xì)內(nèi)容,更多請(qǐng)關(guān)注創(chuàng)新互聯(lián)其它相關(guān)文章!