windows下的哨兵模式:
本地临时搭建个哨兵模式,1主1从2哨兵,就为了追求简单
redis下的master.conf:
port 6379
bind 172.20.61.25
requirepass 123456
redis下的slave.conf:
port 6380
bind 172.20.61.25
slaveof 172.20.61.25 6379
masterauth 123456
redis下下新建2个sentinel.conf,重命名为sentinel1.conf,sentinel2.conf
sentinel1.conf的配置如下:
port 26379
sentinel myid aec78af18a33e0ae9cb0df056bfbb3a36dc90c3d
sentinel monitor mymaster 172.20.61.25 6379 1
sentinel down-after-milliseconds mymaster 5000
sentinel auth-pass mymaster 123456
protected-mode no
bind 172.20.61.25
sentinel2.conf的配置如下:
port 26479
sentinel myid 3303268336b86fc62d1d4875810b77c3466bd36d
sentinel monitor mymaster 172.20.61.25 6380 1
sentinel down-after-milliseconds mymaster 5000
sentinel auth-pass mymaster 123456
sentinel config-epoch mymaster 37
protected-mode no
bind 172.20.61.25
如果觉得2个哨兵不够,可以自行添加哨兵,增加几个sentinel.conf,配置其他都一样,
sentinel monitor mymaster 172.20.61.25 6380 1 --这个ip改成你要监听的主reds或者从redis的ip和端口就行
说个遇到的坑
我之前的master.conf,slave.conf,sentinel1.conf,sentinel2.conf的ip都是用127.0.0.1,结果
All sentinels down, cannot determine where is mymaster master is running...
或者这个错
Could not get a resource from the pool
所以windows下把master.conf,slave.conf,sentinel1.conf,sentinel2.conf这些配置的ip全换成分配的ip,
windows下的cmd命令,ipconfig可疑查看一下自己电脑分配的ip。
我们的spring boot项目中定义了JedisPoolConfig 连接池, 配置redis的哨兵和jedis的配置工厂
@Bean
public JedisPoolConfig jedisPoolConfig() {
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;
}
@Bean
public RedisSentinelConfiguration sentinelConfiguration() {
if(redisType==1){
RedisSentinelConfiguration redisSentinelConfiguration = new RedisSentinelConfiguration();
// 配置redis的哨兵sentinel
RedisNode senRedisNode = new RedisNode(sentinelHostName, sentinelport);
Set redisNodeSet = new HashSet<>();
redisNodeSet.add(senRedisNode);
redisSentinelConfiguration.setSentinels(redisNodeSet);
redisSentinelConfiguration.setMaster(masterName);
redisSentinelConfiguration.setPassword(password);
return redisSentinelConfiguration;
}else {
return new RedisSentinelConfiguration();
}
@Bean
public JedisConnectionFactory jedisConnectionFactory(JedisPoolConfig jedisPoolConfig, RedisSentinelConfiguration sentinelConfig) {
if(redisType==1){
JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(sentinelConfig, jedisPoolConfig);
return jedisConnectionFactory;
}else {
JedisPoolConfig config = jedisPoolConfig();
JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(config);
jedisConnectionFactory.setHostName(host);
jedisConnectionFactory.setPassword(this.password);
jedisConnectionFactory.setPort(port);
jedisConnectionFactory.setTimeout(timeout);
return jedisConnectionFactory;
}
}
还有yml文件中的redis的一些配置
redis:
# 1:哨兵模式 其它数字:普通模式
type: 1
# 哨兵模式普通模式共用 最大空闲数
maxIdle: 200
# 哨兵模式普通模式共用 连接池的最大数据库连接数。设为0表示无限制,如果是jedis 2.4以后用redis.maxTotal
maxTotal: 1000
# 哨兵模式普通模式共用 最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。
maxWaitMillis : 1000
# 哨兵模式普通模式共用 连接的最小空闲时间 默认1800000毫秒(30分钟)
minEvictableIdleTimeMillis: 300000
# 哨兵模式普通模式共用 每次逐出检查时 逐出的最大数目 如果为负数就是 : 1/abs(n), 默认3
numTestsPerEvictionRun: 1024
# 哨兵模式普通模式共用 逐出扫描的时间间隔(毫秒) 如果为负数,则不运行逐出线程, 默认-1
timeBetweenEvictionRunsMillis: 30000
# 哨兵模式普通模式共用 是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个
testOnBorrow: true
# 哨兵模式普通模式共用 在空闲时检查有效性, 默认false
testWhileIdle: true
# 密码 哨兵模式普通模式共用
password: 123456
# 普通模式 地址
host: 127.0.0.1
# 普通模式 连接超时时间(毫秒)
timeout: 5000
# 普通模式 端口
port: 6379
# 哨兵模式 哨兵masterName
mymaster:
masterName: mymaster
# 哨兵模式 哨兵地址 端口
sentinel:
hostName: 172.20.61.25
port: 26379
为啥不能用127.0.0.1这个ip
我跟踪源码,发现中间调用了这个方法
public static String convertHost(String host) {
return !host.equals("127.0.0.1") && !host.startsWith("localhost") && !host.equals("0.0.0.0") && !host.startsWith("169.254") && !host.startsWith("::1") && !host.startsWith("0:0:0:0:0:0:0:1") ? host : LOCALHOST_STR;
}
这个方法内,如果你的配置文件ip是127.0.0.1,localhost,0.0.0.0等等上面中的某一个,那么他会LOCALHOST_STR代替你的ip
其实LOCALHOST_STR就是调用了getLocalHostQuietly方法,也就是InetAddress.getLocalHost().getHostAddress()得到ip来替换你配置文件的ip
public static String getLocalHostQuietly() {
String localAddress;
try {
localAddress = InetAddress.getLocalHost().getHostAddress();
} catch (Exception var2) {
log.logp(Level.SEVERE, HostAndPort.class.getName(), "getLocalHostQuietly", "cant resolve localhost address", var2);
localAddress = "localhost";
}
return localAddress;
}
所有会产生Could not get a resource from the pool这个错误