redis的sentinel主從切換(failover)與Jedis執行緒池自動重連
阿新 • • 發佈:2022-05-02
本文介紹如何通過sentinel監控redis主從叢集,並通過jedis自動切換ip和埠。
1、配置redis主從例項
10.93.21.21:6379
10.93.21.21:6389
10.93.21.21:6399
主從同步關係
master:10.93.21.21:6379
slave:10.93.21.21:6389,10.93.21.21:6399
master配置如下:
# 例項ip和埠 bind 10.93.21.21 port 6379 # pid檔案 pidfile redis_6379.pid # 日誌檔案 logfile "/home/data_monitor/redis-3.2.9/log/6379.log" # 持久化資料檔案dir dir /home/data_monitor/redis-3.2.9/data # rdb 檔案地址 dbfilename 6379.rdb # aof 檔案地址 appendfilename "6379.aof"
slave配置如下(以6389為例)
# 例項ip和埠
bind 10.93.21.21
port 6389
# master節點配置
slaveof 10.93.21.21 6379
# pid檔案
pidfile redis_6389.pid
# 日誌檔案
logfile "/home/data_monitor/redis-3.2.9/log/6389.log"
# 持久化資料檔案dir
dir /home/data_monitor/redis-3.2.9/data
# rdb 檔案地址
dbfilename 6389.rdb
# aof 檔案地址
appendfilename "6389.aof"
啟動redis
bin/redis-server conf/6379.conf
bin/redis-server conf/6389.conf
bin/redis-server conf/6399.conf
驗證一下
master
$ bin/redis-cli -h 10.93.21.21 -p 6379 10.93.21.21:6379> info replication # Replication role:master connected_slaves:2 slave0:ip=10.93.21.21,port=6389,state=online,offset=571888,lag=1 slave1:ip=10.93.21.21,port=6399,state=online,offset=571888,lag=1 master_repl_offset:571888 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:2 repl_backlog_histlen:571887
slave
$ bin/redis-cli -h 10.93.21.21 -p 6389
10.93.21.21:6389> info replication
# Replication
role:slave
master_host:10.93.21.21
master_port:6379
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_repl_offset:530211
slave_priority:100
slave_read_only:1
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
2、配置sentinel叢集
10.93.21.21:26379
10.93.21.21:26389
10.93.21.21:26399
啟動所有的節點,只要監控同一個redis master,啟動的話自動連線成叢集
# sentinel註冊的IP和埠
bind 10.93.21.21
port 26379
# working目錄
dir /home/data_monitor/redis-3.2.9/sentinel
# sentinel監控哪個主節點
sentinel monitor mymaster 10.93.21.21 6379 1
# 主節點掛掉多長時間,判定為掛掉,開始failover
sentinel down-after-milliseconds mymaster 10000
# failover交由幾個sentinel執行
sentinel parallel-syncs mymaster 1
# failover多長時間沒完成,超時失敗
sentinel failover-timeout mymaster 180000
啟動sentinel叢集
bin/redis-sentinel conf/s26379.conf
bin/redis-sentinel conf/s26389.conf
bin/redis-sentinel conf/s26399.conf
3、jedis自動切換ip和埠
先解決依賴:pom.xml
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.7.0</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
連線池程式碼
public class JedisPoolUtil {
private static JedisSentinelPool pool = null;
public static Properties getJedisProperties() {
Properties config = new Properties();
InputStream is = null;
try {
is = JedisPoolUtil.class.getClassLoader().getResourceAsStream("cacheConfig.properties");
config.load(is);
} catch (IOException e) {
logger.error("", e);
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
logger.error("", e);
}
}
}
return config;
}
/**
* 建立連線池
*
*/
private static void createJedisPool() {
// 建立連線池配置引數
JedisPoolConfig config = new JedisPoolConfig();
Properties prop = getJedisProperties();
// 設定最大連線數
config.setMaxTotal(StringUtil.nullToInteger(prop.getProperty("MAX_ACTIVE")));
// 設定最大阻塞時間,記住是毫秒數milliseconds
config.setMaxWaitMillis(StringUtil.nullToInteger(prop.getProperty("MAX_WAIT")));
// 設定空間連線
config.setMaxIdle(StringUtil.nullToInteger(prop.getProperty("MAX_IDLE")));
// jedis例項是否可用
boolean borrow = prop.getProperty("TEST_ON_BORROW") == "false" ? false : true;
config.setTestOnBorrow(borrow);
// 建立連線池
// pool = new JedisPool(config, prop.getProperty("ADDR"), StringUtil.nullToInteger(prop.getProperty("PORT")), StringUtil.nullToInteger(prop.getProperty("TIMEOUT")));// 執行緒數量限制,IP地址,埠,超時時間
//獲取redis密碼
String password = StringUtil.nullToString(prop.getProperty("PASSWORD"));
String masterName = "mymaster";
Set<String> sentinels = new HashSet<String>();
sentinels.add("192.168.137.128:26379");
sentinels.add("192.168.137.128:26380");
sentinels.add("192.168.137.128:26381");
pool = new JedisSentinelPool(masterName, sentinels, config);
}
/**
* 在多執行緒環境同步初始化
*/
private static synchronized void poolInit() {
if (pool == null)
createJedisPool();
}
/**
* 獲取一個jedis 物件
*
* @return
*/
public static Jedis getJedis() {
if (pool == null)
poolInit();
return pool.getResource();
}
/**
* 釋放一個連線
*
* @param jedis
*/
public static void returnRes(Jedis jedis) {
pool.returnResource(jedis);
}
/**
* 銷燬一個連線
*
* @param jedis
*/
public static void returnBrokenRes(Jedis jedis) {
pool.returnBrokenResource(jedis);
}
public static void main(String[] args){
Jedis jedis=getJedis();
}
}