0032【Redis】简单玩玩从Redis单机扩展到一主二从三哨兵模式
二 一主二从三哨兵端口配置:
主:6371
从1:6372
从2:6373
哨兵1:26371
哨兵2:26372
哨兵3:26373
2.1 一主
2.1.1 配置
port 6371
bind 192.168.0.101
dir /Users/chyzhong/01-worktools/08-redis-6.0.8-cluster/3-data
pidfile /Users/chyzhong/01-worktools/08-redis-6.0.8-cluster/2-pid/redis-6371-master.pid
logfile /Users/chyzhong/01-worktools/08-redis-6.0.8-cluster/5-logs/redis-6371-master.log
appendfilename "appendonly-6371-master.aof"
dbfilename dump-6371-master.rdb
requirepass "gzst2022"
masterauth "gzst2022"
2.1.2 启动
/Users/chyzhong/01-worktools/08-redis-6.0.8/bin/redis-server /Users/chyzhong/01-worktools/08-redis-6.0.8-cluster/1-conf/redis-6371-master.conf
2.2 二从
2.2.1 从1配置
port 6372
bind 192.168.0.101
dir /Users/chyzhong/01-worktools/08-redis-6.0.8-cluster/3-data
pidfile /Users/chyzhong/01-worktools/08-redis-6.0.8-cluster/2-pid/redis-6372-slave.pid
logfile /Users/chyzhong/01-worktools/08-redis-6.0.8-cluster/5-logs/redis-6372-slave.log
appendfilename appendonly-6372-slave.aof
dbfilename dump-6372-slave.rdb
requirepass "gzst2022"
masterauth "gzst2022"
slaveof 192.168.0.101 6371 # IP与主机一致,才可以复制数据,运行后slaveof变为replicaof
2.2.2 从2配置
port 6373
bind 192.168.0.101
dir /Users/chyzhong/01-worktools/08-redis-6.0.8-cluster/3-data
pidfile /Users/chyzhong/01-worktools/08-redis-6.0.8-cluster/2-pid/redis-6373-slave.pid
logfile /Users/chyzhong/01-worktools/08-redis-6.0.8-cluster/5-logs/redis-6373-slave.log
appendfilename appendonly-6373-slave.aof
dbfilename dump-6373-slave.rdb
requirepass "gzst2022"
masterauth "gzst2022"
slaveof 192.168.0.101 6371 # IP与主机一致,才可以复制数据,运行后slaveof变为replicaof
2.2.3 启动
/Users/chyzhong/01-worktools/08-redis-6.0.8/bin/redis-server /Users/chyzhong/01-worktools/08-redis-6.0.8-cluster/1-conf/redis-6372-slave.conf
/Users/chyzhong/01-worktools/08-redis-6.0.8/bin/redis-server /Users/chyzhong/01-worktools/08-redis-6.0.8-cluster/1-conf/redis-6373-slave.conf
2.3 三哨兵
2.3.1 哨兵1配置
port 26371
bind 192.168.0.101
#requirepass "gzst2022" #不要设置密码
sentinel monitor mymaster 192.168.0.101 6371 2
sentinel auth-pass mymaster gzst2022 #放在monitor mymaster参数后面,否则报错:No such master with specified name
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 15000
protected-mode no
daemonize yes # 守护进程
pidfile /Users/chyzhong/01-worktools/08-redis-6.0.8-cluster/2-pid/redis-26371-sentinel.pid
dir /Users/chyzhong/01-worktools/08-redis-6.0.8-cluster/3-data
logfile /Users/chyzhong/01-worktools/08-redis-6.0.8-cluster/5-logs/redis-26371-sentinel.log
2.3.2 哨兵2配置
port 26372
bind 192.168.0.101
#requirepass "gzst2022" #不要设置密码
sentinel monitor mymaster 192.168.0.101 6371 2
sentinel auth-pass mymaster gzst2022 #放在monitor mymaster参数后面,否则报错:No such master with specified name
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 15000
protected-mode no
daemonize yes # 守护进程
pidfile /Users/chyzhong/01-worktools/08-redis-6.0.8-cluster/2-pid/redis-26372-sentinel.pid
dir /Users/chyzhong/01-worktools/08-redis-6.0.8-cluster/3-data
logfile /Users/chyzhong/01-worktools/08-redis-6.0.8-cluster/5-logs/redis-26372-sentinel.log
2.3.3 哨兵3配置
port 26373
bind 192.168.0.101
#requirepass "gzst2022" #不要设置密码
sentinel monitor mymaster 192.168.0.101 6371 2
sentinel auth-pass mymaster gzst2022 #放在monitor mymaster参数后面,否则报错:No such master with specified name
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 15000
protected-mode no
daemonize yes # 守护进程
pidfile /Users/chyzhong/01-worktools/08-redis-6.0.8-cluster/2-pid/redis-26373-sentinel.pid
dir /Users/chyzhong/01-worktools/08-redis-6.0.8-cluster/3-data
logfile /Users/chyzhong/01-worktools/08-redis-6.0.8-cluster/5-logs/redis-26373-sentinel.log
2.3.4 启动
/Users/chyzhong/01-worktools/08-redis-6.0.8/bin/redis-server /Users/chyzhong/01-worktools/08-redis-6.0.8-cluster/1-conf/redis-26371-sentinel.conf --sentinel
/Users/chyzhong/01-worktools/08-redis-6.0.8/bin/redis-server /Users/chyzhong/01-worktools/08-redis-6.0.8-cluster/1-conf/redis-26372-sentinel.conf --sentinel
/Users/chyzhong/01-worktools/08-redis-6.0.8/bin/redis-server /Users/chyzhong/01-worktools/08-redis-6.0.8-cluster/1-conf/redis-26373-sentinel.conf --sentinel
另外配置内部会自动生成 sentinel myid 值。
2.4 测试redis运行情况 2.4.1 测试主库cd /Users/chyzhong/01-worktools/08-redis-6.0.8/bin
##########################################################################################
->redis-cli -h 192.168.0.101 -p 6371 -a gzst2022
->info replication
或者:
-> redis-cli -h 192.168.0.101 -p 6371 -a gzst2022 info replication
# Replication
role:master
connected_slaves:2
slave0:ip=192.168.0.101,port=6372,state=online,offset=51471,lag=1
slave1:ip=192.168.0.101,port=6373,state=online,offset=51471,lag=1
master_replid:ed3f6f9e37f49953cfc89bb7957630414b3dd8e6
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:51626
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:51626
2.4.2 测试从库
->redis-cli -h 192.168.0.101 -p 6372 -a gzst2022 info replication
->redis-cli -h 192.168.0.101 -p 6373 -a gzst2022 info replication
# Replication
role:slave
master_host:192.168.0.101
master_port:6371
master_link_status:up
master_last_io_seconds_ago:0
master_sync_in_progress:0
slave_repl_offset:68503
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:ed3f6f9e37f49953cfc89bb7957630414b3dd8e6
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:68503
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:68503
###
# Replication
role:slave
master_host:192.168.0.101
master_port:6371
master_link_status:up
master_last_io_seconds_ago:0
master_sync_in_progress:0
slave_repl_offset:73057
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:ed3f6f9e37f49953cfc89bb7957630414b3dd8e6
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:73057
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:15
repl_backlog_histlen:73043
2.4.3 测试哨兵
##########################################################################################
->redis-cli -h 192.168.0.101 -p 26371 -a gzst2022
->info sentinel
或者:
--> redis-cli -h 192.168.0.101 -p 26371 -a gzst2022 info sentinel
异常:
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=sdown,address=192.168.0.101:6371,slaves=0,sentinels=1
正常:
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=192.168.0.101:6371,slaves=2,sentinels=3
##########################################################################################
->redis-cli -h 192.168.0.101 -p 26372 -a gzst2022
->info sentinel
或者:
-> redis-cli -h 192.168.0.101 -p 26372 -a gzst2022 info sentinel
异常:
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=sdown,address=192.168.0.101:6371,slaves=0,sentinels=1
正常:
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=192.168.0.101:6371,slaves=2,sentinels=3
##########################################################################################
->redis-cli -h 192.168.0.101 -p 26373 -a gzst2022
->info sentinel
或者:
-> redis-cli -h 192.168.0.101 -p 26373 -a gzst2022 info sentinel
异常:
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=sdown,address=192.168.0.101:6371,slaves=0,sentinels=1
正常:
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=192.168.0.101:6371,slaves=2,sentinels=3
2.4.4 telnet 测试端口
telnet 192.168.0.101 26371
telnet 192.168.0.101 26372
telnet 192.168.0.101 26373
2.5 异常
2.5.1 命令异常
1. status=sdown.....,slaves=0,sentinels=1
是因为哨兵配置文件没有配置sentinel auth-pass mymaster gzst2022
2. redis哨兵启动报错No such master with specified name
原因是配置的顺序,也就是我们监听的时候,是需要先配置监听master,给master取一个名字叫mymaster,才能配置这个认证节点的密码。但是认配置是密码在前面,监听配置在后面,这样就会报这个错,调整一下即可。
2.5.2 Java异常
1. NOAUTH Authentication required.. Trying next one.
解决:哨兵不要设置密码。
2. 警告: Cannot get master address from sentinel running @ 192.168.0.101:26372. Reason: redis.clients.jedis.exceptions.JedisDataException: NOAUTH Authentication required.. Trying next one.
Exception in thread "main" redis.clients.jedis.exceptions.JedisConnectionException: All sentinels down, cannot determine where is mymaster master is running...
2.6 应用
2.6.1 Java工具类
// 1.Redis连接池配置
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxTotal(10);
jedisPoolConfig.setMaxIdle(5);
jedisPoolConfig.setMinIdle(5);
// 2.设置sentinel 各个节点集合
Set<String> sentinelSet = new HashSet<>();
sentinelSet.add("192.168.0.101:26371");
sentinelSet.add("192.168.0.101:26372");
sentinelSet.add("192.168.0.101:26373");
// 3.创建连接池
//mymaster是我们配置给哨兵的服务名称, sentinelSet是哨兵集合, jedisPoolConfig是连接池配置, gzst2022是连接Redis服务器的密码
JedisSentinelPool pool = new JedisSentinelPool("mymaster", sentinelSet, jedisPoolConfig, "gzst2022");
// 4.获取客户端
Jedis jedis = pool.getResource();
// 5.执行两个命令
jedis.set("mykey", "myvalue");
String myvalue = jedis.get("mykey");
// 6.打印信息
System.out.println(myvalue);
2.6.2 SpringBoot配置
2.6.2.1 yaml配置
spring:
redis:
sentinel:
nodes: 192.168.0.101:26371,192.168.0.101:26372,192.168.0.101:26373
master: mymaster
database: 6
#连接超时时间
timeout: 10000
password: gzst2022
jedis:
pool:
#最大连接数
max-active: 8
#最大阻塞等待时间(负数表示没限制)
max-wait: -1
#最大空闲
max-idle: 8
#最小空闲
min-idle: 0
2.6.2.2 Java代码
2.6.2.2.1 配置类
注意:配置的密码。
package com.tiannan.demo.config;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.redisson.config.ReadMode;
import org.redisson.config.SentinelServersConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisNode;
import org.springframework.data.redis.connection.RedisSentinelConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisSentinelPool;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@Configuration
@EnableAutoConfiguration
public class RedisConfig {
@Autowired
RedisProperties redisProperties;
@Bean
public JedisPoolConfig getRedisPoolConfig() {
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxIdle(redisProperties.getJedis().getPool().getMaxIdle());
jedisPoolConfig.setMaxIdle(redisProperties.getJedis().getPool().getMinIdle());
jedisPoolConfig.setMaxWaitMillis(redisProperties.getJedis().getPool().getMaxWait().getSeconds());
return jedisPoolConfig;
}
@Bean
public JedisConnectionFactory jedisConnectionFactory(JedisPoolConfig jedisPoolConfig) {
RedisSentinelConfiguration redisSentinelConfiguration = new RedisSentinelConfiguration();
redisSentinelConfiguration.setMaster(redisProperties.getSentinel().getMaster());
redisSentinelConfiguration.setDatabase(redisProperties.getDatabase());
redisSentinelConfiguration.setSentinels(getSentinelNodes());
redisSentinelConfiguration.setPassword(redisProperties.getPassword());
JedisConnectionFactory objJedisConnectionFactory = new JedisConnectionFactory(redisSentinelConfiguration, jedisPoolConfig);
return objJedisConnectionFactory;
}
@Bean
public JedisSentinelPool getJedisPool() {
Set<String> newNodes = new HashSet<>();
for (int i = 0; i < redisProperties.getSentinel().getNodes().size(); i++) {
newNodes.add(redisProperties.getSentinel().getNodes().get(i));
}
// 创建连接池
JedisSentinelPool pool = new JedisSentinelPool(redisProperties.getSentinel().getMaster(), newNodes, getRedisPoolConfig(), Long.valueOf(redisProperties.getTimeout().toMillis()).intValue(), redisProperties.getPassword(), redisProperties.getDatabase());
return pool;
}
@Bean
public Set<RedisNode> getSentinelNodes() {
Set<RedisNode> nodos = new HashSet<>();
for (int i = 0; i < redisProperties.getSentinel().getNodes().size(); i++) {
String[] split = redisProperties.getSentinel().getNodes().get(i).split(":");
nodos.add(new RedisNode(split[0], Integer.parseInt(split[1])));
}
return nodos;
}
@Bean
public RedissonClient createSentinelRedissonClient() {
Config config = new Config();
List<String> newNodes = new ArrayList<>();
for (int i = 0; i < redisProperties.getSentinel().getNodes().size(); i++) {
newNodes.add("redis://" + redisProperties.getSentinel().getNodes().get(i));
}
SentinelServersConfig serverConfig = config.useSentinelServers()
.addSentinelAddress(newNodes.toArray(new String[0]))
.setMasterName(this.redisProperties.getSentinel().getMaster())
.setReadMode(ReadMode.SLAVE)
.setTimeout(60000)
.setRetryAttempts(3)
.setRetryInterval(60000)
//**此项务必设置为redisson解决之前bug的timeout问题关键*****
.setPingConnectionInterval(60000)
.setDatabase(redisProperties.getDatabase())
.setPassword(redisProperties.getPassword());
return Redisson.create(config);
}
}
2.6.2.2.2 服务类
package com.tiannan.demo.service;
import java.util.Arrays;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisSentinelPool;
@Service
public class JedisService {
Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
JedisSentinelPool jedisSentinelPool;
public Jedis getResource() {
return jedisSentinelPool.getResource();
}
public void returnResource(Jedis jedis) {
if(jedis != null){
//edisPool.returnResourceObject(jedis);
jedis.close();
}
}
public void set(String key, String value) {
Jedis jedis = null;
try{
jedis = getResource();
jedis.set(key, value);
logger.info("Redis set success - " + key + ", value:" + value);
} catch (Exception e) {
e.printStackTrace();
logger.error("Redis set error: "+ e.getMessage() +" - " + key + ", value:" + value);
}finally{
if(jedis!=null){
returnResource(jedis);
}
}
}
public String get(String key) {
String result = null;
Jedis jedis=null;
try{
jedis = getResource();
result = jedis.get(key);
} catch (Exception e) {
e.printStackTrace();
logger.error("Redis set error: "+ e.getMessage() +" - " + key + ", value:" + result);
}finally{
if(jedis!=null){
returnResource(jedis);
}
}
return result;
}
}
2.6.2.2.3 测试类
package com.tiannan.demo;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import com.tiannan.demo.service.JedisService;
@SpringBootTest
class SpringBootRedis04SentinelApplicationTests {
@Autowired
private JedisService jedisService;
@Test
public void test01() {
jedisService.set("username", "张三");
String sex = jedisService.get("username");
System.out.println(sex); // 打印信息:张三
}
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)