1. 程式人生 > >redis的叢集模式和哨兵模式

redis的叢集模式和哨兵模式

redis的叢集模式和哨兵模式

redis中叢集模式

redis叢集模式配置支援3.0及以上的版本。目的提高redis的可用性,但是隻能保證一定程度的高可用

redis-cluster原理

Redis 叢集有16384個雜湊槽,每個key通過CRC16校驗後對16384取模來決定放置哪個槽.叢集的每個節點負責一部分hash槽,舉個例子,比如當前叢集有3個節點,那麼:

  • 節點 A 包含 0 到 5500號雜湊槽.
  • 節點 B 包含5501 到 11000 號雜湊槽.
  • 節點 C 包含11001 到 16384號雜湊槽.

這種結構無論新增刪除或者改變某個節點的雜湊槽的數量都不會造成叢集不可用的狀態。

因為這種key分佈在不同的節點,所以不能使用多keys的操作。(其實也可以變相的實現,但是在高負載的情況下存在風險)。

redis-cluster的主從複製模型

為了實現一定程度的高可用,比如某個節點掛掉的情況下,服務仍然能夠正常使用。redis使用了主從複製模型,例如建立三個節點的叢集A,B,C,在叢集建立的時候或者過段時間為三個節點,新增從節點A1,B1,C1.此時整個叢集有三個master節點和三個slave節點。A節點down掉的情況,叢集推舉A1為主節點繼續服務。當然,如果A,A1都掛掉的情況,叢集則無法使用。所以這也是為什麼叢集只能保證一定程度的高可用。

redis叢集安裝配置

Linux Redis叢集安裝

redis-cluster在Java中的應用

這裡列出spring-boot中的配置方法和spring中的配置方式兩種方式,根據自己的情況使用。(親測可用

環境:

jdk:1.8

spring:

spring-boot:2.0.6

jedis:2.9.0(這個版本支援叢集密碼的配置,更早的版本不支援)

spring中的配置
Spring-boot中的配置

pom.xmL中引入jedis2.9依賴:

        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>2.9.0</version>
        </dependency>

application.properties中redis的配置:

# Redis伺服器地址
spring.redis.clusterNodes=ip:port,ip1:port1
# Redis伺服器連線埠
spring.redis.port=6379
# Redis伺服器連線密碼(預設為空)
spring.redis.password=XXXX
# 連線超時時間(毫秒)
spring.redis.timeout=3600
# 連線池最大連線數(使用負值表示沒有限制)
spring.redis.jedis.pool.max-active=8
# 連線池最大阻塞等待時間(使用負值表示沒有限制)
spring.redis.jedis.pool.max-wait=-1
# jedis超時
spring.redis.jedis.shutdown-timeout=100
# 連線池中的最大空閒連線
spring.redis.jedis.pool.max-idle=8
# 連線池中的最小空閒連線
spring.redis.jedis.pool.min-idle=0

接下來將這些配置讀取到Spring 容器中:

/**
 * @Author:chenglitao
 * @Description:
 * @Date:2018/11/7 16:15
 */

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;

/**
*@Author:chenglitao
*@Description:
*@Params:redis配置類
*@Date:2018/11/28 16:46
*
*/
@Configuration
public class JedisRedisConfig {
    @Value("${spring.redis.clusterNodes}")
    private String clusterNodes;
    @Value("${spring.redis.password}")
    private String password;
    @Value("${spring.redis.port}")
    private int port;
    @Value("${spring.redis.timeout}")
    private int timeout;
    @Value("${spring.redis.jedis.pool.max-idle}")
    private int maxIdle;
    @Value("${spring.redis.jedis.pool.min-idle}")
    private int minIdle;

    @Value("${spring.redis.jedis.pool.max-wait}")
    private long maxWaitMillis;
 
}

然後配置RedisCluster:

/**
 * @Author:chenglitao
 * @Description:
 * @Date:2018/11/7 16:13
 */


import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;

import java.util.HashSet;
import java.util.Set;

/**
*@Author:chenglitao
*@Description:
*@Params: 
*@Date:2018/11/28 16:44
*
*/
@Configuration

public class RedisClusterConfig {
    @Autowired
    private JedisRedisConfig redisProperties;

    @Bean
    public JedisCluster jedisCluster() {
        String[] serverArray = redisProperties.getClusterNodes().split(",");
        //獲取伺服器陣列,逗號分隔
        Set<HostAndPort> nodes = new HashSet<>();

        for (String ipPort : serverArray) {
            String[] ipPortPair = ipPort.split(":");
            nodes.add(new HostAndPort(ipPortPair[0].trim(), 									Integer.valueOf(ipPortPair[1].trim())));
        }

        GenericObjectPoolConfig config = new
                GenericObjectPoolConfig();
        config.setMaxTotal(3);
        return new JedisCluster(nodes, redisProperties.getTimeout(), 1000, 100, 			redisProperties.getPassword(), config);//需要密碼連線的建立物件方式,如果沒有密碼,就使用沒有密碼的方法,這裡有很多過載的構造方法。
    }

}

最後,寫test方法測試下就ok了。

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import redis.clients.jedis.JedisCluster;

@RunWith(SpringRunner.class)
@SpringBootTest
public class DemoApplicationTests {
    @Autowired
    private JedisCluster jedisCluster;

    @Test
    public void contextLoads() {
        jedisCluster.set("aa", "111");
        String aa = jedisCluster.get("aa");
        System.out.println(aa);
    }
}

當然,在開發中需要封裝基礎的工具類操作。下面是基本的操作的封裝,根據自己的需要修改即可。