Redis集群搭建

redis集群搭建

docker-compose配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
version: '3.3'
services:
# redis1
redis-6380:
image: redis
container_name: redis-6380
# 必须是host
network_mode: "host"
volumes:
- /home/jtx/Documents/redis/redis6380/redis.conf:/usr/local/etc/redis/redis.conf
command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
# redis2
redis-6381:
image: redis
container_name: redis-6381
network_mode: "host"
volumes:
- /home/jtx/Documents/redis/redis6381/redis.conf:/usr/local/etc/redis/redis.conf
command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
# redis3
redis-6382:
image: redis
container_name: redis-6382
network_mode: "host"
volumes:
- /home/jtx/Documents/redis/redis6382/redis.conf:/usr/local/etc/redis/redis.conf
command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
# redis4
redis-6383:
image: redis
container_name: redis-6383
network_mode: "host"
volumes:
- /home/jtx/Documents/redis/redis6383/redis.conf:/usr/local/etc/redis/redis.conf
command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
# redis5
redis-6384:
image: redis
container_name: redis-6384
network_mode: "host"
volumes:
- /home/jtx/Documents/redis/redis6384/redis.conf:/usr/local/etc/redis/redis.conf
command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
# redis6
redis-6385:
image: redis
container_name: redis-6385
network_mode: "host"
volumes:
- /home/jtx/Documents/redis/redis6385/redis.conf:/usr/local/etc/redis/redis.conf
command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
# redis7
redis-6386:
image: redis
container_name: redis-6386
network_mode: "host"
volumes:
- /home/jtx/Documents/redis/redis6386/redis.conf:/usr/local/etc/redis/redis.conf
command: ["redis-server", "/usr/local/etc/redis/redis.conf"]

redis.conf配置

1
2
3
4
5
6
7
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
requirepass pass
# 每个端口应该设置为不一样的
port 6380

启动后

随便进入一个容器

1
docker exec -it redis-6380 bash
1
2
3
4
# ip地址必须写外部应用可连接的ip,不然程序连接时会报错
redis-cli --cluster create 10.3.30.40:6380 10.3.30.40:6381 10.3.30.40:6382 10.3.30.40:6383 10.3.30.40:6384 10.3.30.40:6385 10.3.30.40:6386 --cluster-replicas 1

# 输入 yes

SpringBoot连接

pom

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!-- 需要引入springboot -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<exclusions>
<exclusion>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>

yml配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
spring:
redis:
cluster:
nodes: 10.3.30.40:6380,10.3.30.40:6381,10.3.30.40:6382,10.3.30.40:6383,10.3.30.40:6384,10.3.30.40:6385,10.3.30.40:6386
max-redirects: 12
jedis:
pool:
max-idle: 16
max-active: 32
min-idle: 8
database: 0
redis:
timeout: 10000 #客户端超时时间单位是毫秒 默认是2000
maxIdle: 300 #最大空闲数
maxTotal: 1000 #控制一个pool可分配多少个jedis实例,用来替换上面的redis.maxActive,如果是jedis 2.4以后用该属性
maxWaitMillis: 1000 #最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。
minEvictableIdleTimeMillis: 300000 #连接的最小空闲时间 默认1800000毫秒(30分钟)
numTestsPerEvictionRun: 1024 #每次释放连接的最大数目,默认3
timeBetweenEvictionRunsMillis: 30000 #逐出扫描的时间间隔(毫秒) 如果为负数,则不运行逐出线程, 默认-1
testOnBorrow: true #是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个
testWhileIdle: true #在空闲时检查有效性, 默认false

配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
@Value("${spring.redis.cluster.nodes}")
private String clusterNodes;
@Value("${spring.redis.cluster.max-redirects}")
private int maxRedirects;
@Value("${redis.timeout}")
private int timeout;
@Value("${redis.maxIdle}")
private int maxIdle;
@Value("${redis.maxTotal}")
private int maxTotal;
@Value("${redis.maxWaitMillis}")
private int maxWaitMillis;
@Value("${redis.minEvictableIdleTimeMillis}")
private int minEvictableIdleTimeMillis;
@Value("${redis.numTestsPerEvictionRun}")
private int numTestsPerEvictionRun;
@Value("${redis.timeBetweenEvictionRunsMillis}")
private int timeBetweenEvictionRunsMillis;
@Value("${redis.testOnBorrow}")
private boolean testOnBorrow;
@Value("${redis.testWhileIdle}")
private boolean testWhileIdle;

/**
* Redis连接池的配置
*
* @return JedisPoolConfig
*/
@Bean
public JedisPoolConfig getJedisPoolConfig() {
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
// 最大空闲数
jedisPoolConfig.setMaxIdle(maxIdle);
// 连接池的最大数据库连接数
jedisPoolConfig.setMaxTotal(maxTotal);
// 最大建立连接等待时间
jedisPoolConfig.setMaxWaitMillis(maxWaitMillis);
// 逐出连接的最小空闲时间 默认1800000毫秒(30分钟)
jedisPoolConfig.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
// 每次逐出检查时 逐出的最大数目 如果为负数就是 : 1/abs(n), 默认3
jedisPoolConfig.setNumTestsPerEvictionRun(numTestsPerEvictionRun);
// 逐出扫描的时间间隔(毫秒) 如果为负数,则不运行逐出线程, 默认-1
jedisPoolConfig.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
// 是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个
jedisPoolConfig.setTestOnBorrow(testOnBorrow);
// 在空闲时检查有效性, 默认false
jedisPoolConfig.setTestWhileIdle(testWhileIdle);
return jedisPoolConfig;
}

/**
* Redis集群的配置
*
* @return RedisClusterConfiguration
*/
@Bean
public RedisClusterConfiguration redisClusterConfiguration() {
RedisClusterConfiguration redisClusterConfiguration = new RedisClusterConfiguration();
// Set<RedisNode> clusterNodes
String[] serverArray = clusterNodes.split(",");
Set<RedisNode> nodes = new HashSet<RedisNode>();
for (String ipPort : serverArray) {
String[] ipAndPort = ipPort.split(":");
nodes.add(new RedisNode(ipAndPort[0].trim(), Integer.valueOf(ipAndPort[1])));
}
redisClusterConfiguration.setClusterNodes(nodes);
redisClusterConfiguration.setMaxRedirects(maxRedirects);
return redisClusterConfiguration;
}

/**
* redis连接工厂类
*
* @return JedisConnectionFactory
*/
@Bean
public JedisConnectionFactory jedisConnectionFactory() {
// 集群模式
JedisConnectionFactory factory = new JedisConnectionFactory(redisClusterConfiguration(), getJedisPoolConfig());
return factory;
}

/**
* 实例化 RedisTemplate 对象
*
* @return RedisTemplate<String, Object>
*/
@Bean
public RedisTemplate<String, Object> redisTemplate() {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
// Template初始化
initDomainRedisTemplate(redisTemplate);
return redisTemplate;
}

/**
* 设置数据存入 redis 的序列化方式 使用默认的序列化会导致key乱码
*/
private void initDomainRedisTemplate(RedisTemplate<String, Object> redisTemplate) {
// 开启redis数据库事务的支持
redisTemplate.setEnableTransactionSupport(true);
redisTemplate.setConnectionFactory(jedisConnectionFactory());
// 如果不配置Serializer,那么存储的时候缺省使用String,如果用User类型存储,那么会提示错误User can't cast to
// String!
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
redisTemplate.setKeySerializer(stringRedisSerializer);
// hash的key也采用String的序列化方式
redisTemplate.setHashKeySerializer(stringRedisSerializer);
// jackson序列化对象设置
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(
Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
// value序列化方式采用jackson
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
// hash的value序列化方式采用jackson
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.afterPropertiesSet();
}

相关文章

SpringCloud

服务注册与发现

服务调用

SpringCloud-OpenFeign问题

SpringCloud-GateWay工具类

DockerCompose常用软件配置

SpringQuartz动态定时任务

redis分布式锁

服务链路追踪

K8S