Redis叢集環境搭建(筆記)
一、序言
之前文章 http://blog.csdn.net/strburnchang/article/details/78634226 介紹了redis單機版服務搭建過程。
這次是來學習叢集版redis搭建及其使用。因硬體條件限制,僅在一臺伺服器做demo
二、Redis單機版搭建過程
三、Redis叢集版搭建過程。
1、Redis叢集架構圖,
架構細節:
(1)所有的redis節點彼此互聯(PING-PONG機制),內部使用二進位制協議優化傳輸速度和頻寬.
(2)節點的fail是通過叢集中超過半數的節點檢測失效時才生效.
(3)客戶端與redis節點直連,不需要中間proxy層.客戶端不需要連線叢集所有節點,連線叢集中任何一個可用節點即可
(4)redis-cluster把所有的物理節點對映到[0-16383]slot上,cluster 負責維護node<->slot<->value
注:
Redis 叢集中內建了 16384 個雜湊槽,當需要在 Redis 叢集中放置一個 key-value 時,redis 先對 key 使用 crc16 演算法算出一個結果,然後把結果對 16384 求餘數,這樣每個 key 都會對應一個編號在 0-16383 之間的雜湊槽,redis 會根據節點數量大致均等的將雜湊槽對映到不同的節點
2、叢集搭建
叢集中應該至少有三個節點,每個節點有一備份節點。需要6臺伺服器。搭建偽分散式,需要
(因環境限制,僅是在同一臺伺服器上使用6個不同埠啟動redis個例項,3個作為主節點,3個作為備用節點)
(1)搭建步驟
A、建立6個redis例項並指定埠(7001-7006)
在redis目錄下建立 redis-cluster目錄
cd /usr/local/redis/;mkdir redis-cluster
將redis原始碼複製6份放到redis-cluster目錄下
B、修改redis配置檔案(六個都需要改)
vi ./redis01/etc/redis.conf
將cluster-enable yes註釋開啟
然後修改對應埠 port 7001(其他依次為 7002 ...)
C、安裝ruby環境(因為叢集執行需要一個ruby指令碼)
1、yum install ruby
2、安裝redis叢集需要的包
gem install redis -v 3.3.3
[[email protected] /usr/local/redis]#gem install redis -v 3.3.3
Fetching: redis-3.3.3.gem (100%)
Successfully installed redis-3.3.3
Parsing documentation for redis-3.3.3
Installing ri documentation for redis-3.3.3
1 gem installed
D、寫一個shell指令碼用來啟動redis叢集所有服務
vim start-all.sh
#!/bin/bash
clusterpath="/usr/local/redis/redis-cluster/"
cd $clusterpath
redis_arr=(01 02 03 04 05 06)
for num in ${redis_arr[@]}
do
echo "start ${num}nth redis server..."
cd redis${num}/bin/
redis-server ../etc/redis.conf
cd ..
cd ..
done
chmod +x start-all.sh
啟動所有rediss例項
./start-all.sh
E、使用redis-trib.rb建立叢集
命令
./redis-trib.rb create --replicas 1 192.168.1.102:7001 192.168.1.102:7002 192.168.1.102:7003 192.168.1.102:7004 192.168.1.102:7005 192.168.1.102:7006
發現這個命令會出錯。說我沒有許可權。然後給前面加了ruby 表明是ruby指令碼。
ruby ./redis-trib.rb create --replicas 1 192.168.1.102:7001 192.168.1.102:7002 192.168.1.102:7003 192.168.1.102:7004 192.168.1.102:7005 192.168.1.102:7006
這個也出錯,說不能連線到7001節點。百度了下,是因為redis配置檔案中已經打開了認證功能(密碼),所以挨著關閉了。
更改配置檔案之後,再重新啟動節點
./start-all.sh
ruby ./redis-trib.rb create --replicas 1 192.168.1.102:7001 192.168.1.102:7002 192.168.1.102:7003 192.168.1.102:7004 192.168.1.102:7005 192.168.1.102:7006
成功
F、建立cluster過程可能會遇到一些問題:
參考:http://www.2bowl.info/centos7%E4%B8%8A%E6%90%AD%E5%BB%BAredis-cluster/
1)、>>> Creating cluster
[ERR] Node 192.168.1.102:7001 is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0.
解決方法:
刪除每個節點下的dump.rdb檔案
或挨個進行flushdb
redis-cli -h 192.168.1.102 -p 6390
flushdb
2)、/usr/local/share/gems/gems/redis-3.3.3/lib/redis/client.rb:121:in call': ERR Slot 741 is already busy (Redis::CommandError)
block in method_missing’
from /usr/local/share/gems/gems/redis-3.3.3/lib/redis.rb:2705:in
from /usr/local/share/gems/gems/redis-3.3.3/lib/redis.rb:58:in block in synchronize'
mon_synchronize’
from /usr/share/ruby/monitor.rb:211:in
from /usr/local/share/gems/gems/redis-3.3.3/lib/redis.rb:58:in synchronize'
method_missing’
from /usr/local/share/gems/gems/redis-3.3.3/lib/redis.rb:2704:in
from ./redis-trib.rb:212:in flush_node_config'
block in flush_nodes_config’
from ./redis-trib.rb:776:in
from ./redis-trib.rb:775:in each'
flush_nodes_config’
from ./redis-trib.rb:775:in
from ./redis-trib.rb:1296:in create_cluster_cmd'
from ./redis-trib.rb:1701:in
解決方法:由於上一次的配置不正確導致的,重新刪除節點中node.conf檔案,重啟節點即可
四、使用redis的java客戶端jedis
1、新增maven依賴
<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
2、建立測試類
package com.gs.redis;
import org.junit.Test;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;
import java.util.HashSet;
import java.util.Set;
public class TestRedis {
private final String REDIS_HOST = "192.168.1.102";
@Test
public void testJedisCluster() throws Exception {
//建立一個JedisCluster物件
Set<HostAndPort> nodes = new HashSet<HostAndPort>();
nodes.add(new HostAndPort(REDIS_HOST, 7001));
nodes.add(new HostAndPort(REDIS_HOST, 7002));
nodes.add(new HostAndPort(REDIS_HOST, 7003));
nodes.add(new HostAndPort(REDIS_HOST, 7004));
nodes.add(new HostAndPort(REDIS_HOST, 7005));
nodes.add(new HostAndPort(REDIS_HOST, 7006));
//在nodes中指定每個節點的地址
//jedisCluster在系統中是單例的。
JedisCluster jedisCluster = new JedisCluster(nodes);
jedisCluster.set("name", "zhangsan");
jedisCluster.set("value", "100");
String name = jedisCluster.get("name");
String value = jedisCluster.get("value");
System.out.println(name);
System.out.println(value);
//系統關閉時關閉jedisCluster
jedisCluster.close();
}
}
到此,redis叢集搭建完成。後面會再記錄redis整合spring(單機版和叢集版本)