redis叢集部署和使用
喜歡的話,還可以打賞哦,以資鼓勵
(支付寶) (微信)
1.叢集概念
- Redis叢集採用主從複製模型,每個節點都有N – 1個複製品。
- Redis叢集有16384個雜湊槽,對key進行crc16演算法後,分配到對應的雜湊槽中。
- Redis叢集執行最少需要三個主節點,一般採用三主三從模式,主節點A、B、C,從節點a、b、c。a為A的從節點,b為B的從節點,c為C的從節點。
- 任何主節點或者從節點都可以失敗,主節點失敗後,從節點被選為新的主節點。但主節點和從節點不可以同時失敗。所以生產部署叢集最少需要2臺機器(主A、B、C一臺,從a、b、c一臺)。
2.部署步驟
假設有192.168.195.128和192.168.195.129兩臺機器。
我們計劃在這兩臺機器上部署redis叢集,192.168.195.128機器部署3個節點,192.168.195.129機器部署3個節點。
相關軟體版本:
Ruby 2.5.1 (ruby版本必須大於2.2)
Redis 4.0.9
2.1 安裝Ruby
在192.168.195.128和192.168.195.129兩臺機器都安裝ruby。
$ yum install ruby //ruby版本必須大於2.2
$ yum install rubygems
$ gem install redis
Ruby版本過低問題解決:
https://www.cnblogs.com/Zlcode/p/8305718.html
2.2 下載redis包,解壓編譯
1.在192.168.195.128和192.168.195.129上建立redis-cluster目錄,比如/usr/local/redis-cluster
2.解壓redis到/usr/local/redis-cluster目錄下,並編譯。
$ tar xzf redis-4.0.9.tar.gz
$ cd redis-4.0.9
$ make
編譯完後,在src目錄下可以看到服務程式redis-server和客戶端程式redis-cli。
2.3 配置
1.在192.168.195.128和192.168.195.129的/usr/local/redis-cluster下建立7000,7001,7002目錄(對應redis節點埠)。
2.在7000目錄下建立redis.conf檔案,內容如下
port 7000
pidfile redis_7000.pid
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
daemonize yes
protected-mode no
bind 192.168.195.128 127.0.0.1
3.拷貝redis.conf檔案到7001,7002目錄,並修改檔案中的port、bind和pidfile配置項,對應目錄名稱和機器的ip。
2.4 啟動redis節點
分別在192.168.195.128和192.168.195.129上執行如下語句:
for((i=0;i<3;i++)); do cd /usr/local/redis-cluster/700$i; /usr/local/redis-cluster/redis-4.0.9/src/redis-server /usr/local/redis-cluster/700$i/redis.conf; done
執行後檢視程序是否存在
ps -ef|grep redis
應該是每臺機器上三個節點
2.5 建立叢集
/usr/local/redis-cluster/redis-4.0.9/src/redis-trib.rb create --replicas 1 192.168.195.128:7000 192.168.195.128:7001 192.168.195.128:7002 192.168.195.129:7000 192.168.195.129:7001 192.168.195.129:7002
執行後會出現叢集配置資訊,確認就可以了
這時在7000、7001、7002目錄下就能看到叢集配置了
2.6 檢視叢集資訊
/usr/local/redis-cluster/redis-4.0.9/src/redis-trib.rb check 127.0.0.1:7000
可以看到六個節點,並且分別顯示了節點是主節點還是從節點
2.7 訪問叢集
/usr/local/redis-cluster/redis-4.0.9/src/redis-cli -h 127.0.0.1 -c -p 7000
嘗試設定一個key a
叢集部署成功
2.8 其他操作
關閉叢集
for((i=0;i<3;i++)); do /usr/local/redis-cluster/redis-4.0.9/src/redis-cli -c -h 127.0.0.1 -p 700$i shutdown; done
3. spring boot訪問redis叢集
3.1配置依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
3.2 配置項
spring.redis.cluster.nodes=192.168.195.128:7000 192.168.195.128:7001 192.168.195.128:7002 192.168.195.129:7000 192.168.195.129:7001 192.168.195.129:7002
spring.redis.password=
3.3 存在問題的使用方式
該種直接使用spring-boot-starter-data-redis的方式,在持續大量操作下會出現連不上節點的異常。
@SpringBootApplication
public class SpringDemoApplication implements InitializingBean{
@Autowired
public RedisTemplate<String, String> redisTemplate;
public static void main(String[] args) {
SpringApplication.run(SpringDemoApplication.class, args);
}
@Override
public void afterPropertiesSet() throws Exception {
redisTemplate.opsForValue().set("6-22-1", "1");
Thread.sleep(2000);
System.out.println(redisTemplate.opsForValue().get("6-22-1"));
}
}
3.4 正確的使用方式
該例子採用Jedis+spring boot
@Configuration
@ConfigurationProperties(prefix="spring.redis.cluster")
public class RedisConfig {
private String nodes;
@Bean
public JedisCluster createJedisCluster(){
String[] ipPortStrs = nodes.split(",");
Set<HostAndPort> nodes = new HashSet<HostAndPort>();
for (String ipPortStr:ipPortStrs) {
String[] ipPortPair = ipPortStr.split(":");
nodes.add(new HostAndPort(ipPortPair[0], Integer.parseInt(ipPortPair[1])));
}
JedisCluster cluster = new JedisCluster(nodes);
return cluster;
}
public String getNodes() {
return nodes;
}
public void setNodes(String nodes) {
this.nodes = nodes;
}
}
@SpringBootApplication
public class SpringDemoApplication implements InitializingBean{
@Autowired
public RedisTemplate<String, String> redisTemplate;
@Autowired
public JedisCluster jedisCluster;
public static void main(String[] args) {
SpringApplication.run(SpringDemoApplication.class, args);
}
@Override
public void afterPropertiesSet() throws Exception {
for (int i = 0; i < 100000; i++) {
jedisCluster.set(i+"", "6");
System.out.println(i);
}
}
}