在虛擬機上模擬redis5.0的集群,由於redis的投票機制,一個集群至少需要3個redis節點,如果每個節點設置一主一備,一共需要六台虛擬機來搭建集群,此處,在一台虛擬機上使用6個redis實例來模擬搭建一個偽分布式的redis集群。
1.安裝ruby
搭建redis集群需要ruby腳本,需要安裝ruby的環境
(1)yum install ruby
(2) yum install rubygems
2. 創建一個集群的目錄
3. 復制編譯安裝好的redis節點
進入redis01目錄,刪除快照文件
修改配置文件中的端口號,去掉集群配置cluster-enabled yes前面的#
除此之外,還需要將綁定ip注釋掉,即 bind命令前面加#(以便除了linux機器之外的其他ip可以訪問),關閉保護模式:protected-mode yes改為protected-mode no
(這樣做是為了通過Java代碼能夠訪問到虛擬機上的redis5集群,redis3不存在這兩項設置,如果是生產環境搭建redis集群,bind應該是要綁定本機回環地址 )
4.復制其他5個節點並修改redis.conf的端口號為7002~7006
5.啟動所有節點:
vim startall.sh 創建一個啟動腳本:
cd redis01
./redis-server redis.conf
cd ..
cd redis02
./redis-server redis.conf
cd ..
cd redis03
./redis-server redis.conf
cd ..
cd redis04
./redis-server redis.conf
cd ..
cd redis05
./redis-server redis.conf
cd ..
cd redis06
./redis-server redis.conf
保存后賦予執行權限:
[root@localhost redis-cluster]# chmod +x startall.sh
並執行腳本:bash startall.sh:
6.創建集群:redis5創建集群的工具集成到了redis-cli命令行中,
創建集群命令如下:進入任意一個redis實例,此處進入redis01目錄下:
./redis-cli --cluster create 192.168.93.135:7001 192.168.93.135:7002 192.168.93.135:7003 192.168.93.135:7004 192.168.93.135:7005 192.168.93.135:7006 --cluster-replicas 1
(以命令為准,下圖僅供示例)
創建集群過程中分配槽號:
7測試集群狀態:
./redis-cli -h 192.168.93.135 -p 7001 -c( -h表示host ip,-p表示端口,-c表示要連接的是集群的節點)
查看集群所有節點:
向集群中添加數據:(此時會計算槽號,並將數據保存到對應的槽)
8.停止集群所有節點:在 redis-cluster目錄下創建shutdown-all.sh腳本,內容如下:
redis01/redis-cli -p 7001 shutdown
redis02/redis-cli -p 7002 shutdown
redis03/redis-cli -p 7003 shutdown
redis04/redis-cli -p 7004 shutdown
redis05/redis-cli -p 7005 shutdown
redis06/redis-cli -p 7006 shutdown
然后賦予執行權限,bash該腳本,即可停止所有redis集群節點
9.Java代碼訪問redis5.0 集群節點:
1 @Test 2 public void testJedisCluster() throws IOException { 3 /*redis.clients.jedis.JedisCluster.JedisCluster(Set<HostAndPort> nodes)*/ 4 Set<HostAndPort> nodes = new HashSet<>(); 5 String clusterHost = "192.168.93.135"; 6 nodes.add(new HostAndPort(clusterHost, 7001)); 7 nodes.add(new HostAndPort(clusterHost, 7002)); 8 nodes.add(new HostAndPort(clusterHost, 7003)); 9 nodes.add(new HostAndPort(clusterHost, 7004)); 10 nodes.add(new HostAndPort(clusterHost, 7005)); 11 nodes.add(new HostAndPort(clusterHost, 7006)); 12 JedisCluster cluster = new JedisCluster(nodes); 13 // 向redis集群中保存數據 14 cluster.set("name", "LBG"); 15 String name = cluster.get("name"); 16 System.out.println(name); 17 cluster.close(); 18 }
結果報如下錯誤:節點不可訪問,這是由於redis的集群節端口沒有開放,被防火牆攔截了
redis.clients.jedis.exceptions.JedisNoReachableClusterNodeException: No reachable node in cluster at redis.clients.jedis.JedisSlotBasedConnectionHandler.getConnection(JedisSlotBasedConnectionHandler.java:57) at redis.clients.jedis.JedisSlotBasedConnectionHandler.getConnectionFromSlot(JedisSlotBasedConnectionHandler.java:74) at redis.clients.jedis.JedisClusterCommand.runWithRetries(JedisClusterCommand.java:116) at redis.clients.jedis.JedisClusterCommand.run(JedisClusterCommand.java:31) at redis.clients.jedis.JedisCluster.set(JedisCluster.java:103) at com.tao.rest.jedis.JedisTest.testJedisCluster(JedisTest.java:71) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:539) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:761) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:461) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:207)
執行如下命令開放redis集群每個節點的端口即可正常訪問redis集群了:
[root@localhost bin]# /sbin/iptables -I INPUT -p tcp --dport 7006 -j ACCEPT [root@localhost bin]# /etc/rc.d/init.d/iptables save
參考文檔:
https://redis.io/topics/cluster-tutorial redis官網集群指導
https://www.18188.org/articles/2018/10/19/1539930723215.html Redis5.0客戶端redis-cli管理cluster嘗試