redis的集羣模式和哨兵模式

redis的集羣模式和哨兵模式java

redis中集羣模式

redis集羣模式配置支持3.0及以上的版本。目的提升redis的可用性,可是隻能保證必定程度的高可用node

redis-cluster原理

Redis 集羣有16384個哈希槽,每一個key經過CRC16校驗後對16384取模來決定放置哪一個槽.集羣的每一個節點負責一部分hash槽,舉個例子,好比當前集羣有3個節點,那麼:redis

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

這種結構不管添加刪除或者改變某個節點的哈希槽的數量都不會形成集羣不可用的狀態。spring

由於這種key分佈在不一樣的節點,因此不能使用多keys的操做。(其實也能夠變相的實現,可是在高負載的狀況下存在風險)。apache

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中的配置方式兩種方式,根據本身的狀況使用。(親測可用app

環境:spring-boot

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);
    }
}

固然,在開發中須要封裝基礎的工具類操做。下面是基本的操做的封裝,根據本身的須要修改便可。

相關文章
相關標籤/搜索