sentinel的主要配置
port ${port}
dir "/opt/soft/redis/data/"
logfile "${port}.log"
# 表示有兩個sentinel認爲master有問題的時候就進行故障轉移
sentinel monitor mymaster 127.0.0.1 7000 2
#當ping master不通30秒之後則認爲master掛掉了
sentinel down-after-milliseconds mymaster 30000
#故障轉移之後salve 對 master的複製是並行還是串行,1表示串行
sentinel parallel-syncs mymaster 1
# 故障轉移時間
sentinel failover-timeout mymaster 180000
主從節點的準備
在redis config目錄下創建 redis-7000.conf
vim redis-7000.conf
填寫如下配置:
port 7000
daemonize yes
pidfile /var/run/redis-7000.pid
logfile "7000.log"
dir "/opt/soft/redis/data/" #沒有該目錄記得要創建
上面是主節點的配置 下面將快速生成從節點的配置
sed "s/7000/7001/g" redis-7000.conf> redis-7001.conf
sed "s/7000/7002/g" redis-7000.conf > redis-7002.conf
添加配置
echo "slaveof 127.0.0.1 7000">>redis-7002.conf
echo "slaveof 127.0.0.1 7000">>redis-7001.conf
配置檢驗
cat redis-7000.conf
cat redis-7001.conf
cat redis-7002.conf
啓動
[root@localhost config]# redis-server redis-7000.conf
[root@localhost config]# redis-cli -p 7000 ping
PONG
redis-server redis-7001.conf
[root@localhost config]# redis-server redis-7002.conf
[root@localhost config]# ps -ef | grep redis-server | grep 700
root 5091 1 0 20:27 ? 00:00:00 redis-server *:7000
root 5097 1 0 20:28 ? 00:00:00 redis-server *:7001
root 5101 1 0 20:28 ? 00:00:00 redis-server *:7002
查看從節點是否配置成功
[root@localhost config]# redis-cli -p 7000 info replication
# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=7001,state=online,offset=57,lag=1
slave1:ip=127.0.0.1,port=7002,state=online,offset=57,lag=1
master_repl_offset:57
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:56
Redis Sentinel的配置安裝
將redis 目錄下的配置 複製到 config下
cp sentinel.conf config
查看該配置(去掉所有註釋和空行)
cat sentinel.conf | grep -v "#" | grep -v "^$"
創建新的文件
cat sentinel.conf | grep -v "#" | grep -v "^$" > redis-sentinel-26379.conf
進行編輯
vim redis-sentinel-26379.conf
需要更改的地方
dir /opt/soft/redis/redis/data/
daemonize yes
logfile "26379.log"
sentinel monitor mymaster 127.0.0.1 7000 2
進行啓動並查看狀態:
[root@localhost config]# redis-sentinel redis-sentinel-26379.conf
[root@localhost config]# ps -ef | grep redis-sentinel
root 1336 1 0 20:58 ? 00:00:00 redis-sentinel *:26379 [sentinel]
root 1340 1250 0 20:58 pts/0 00:00:00 grep --color=auto redis-sentinel
使用redis進行連接
[root@localhost config]# redis-cli -p 26379
127.0.0.1:26379> ping
PONG
127.0.0.1:26379> info
其中使用 info是查看該sentinel的信息
其中 sentinel 能夠能夠自動通過主節點去發現他的從節點 可以通過配置文件進行查看:
[root@localhost config]# cat redis-sentinel-26379.conf
port 26379
daemonize yes
dir "/opt/soft/redis/redis/data"
logfile "26379.log"
sentinel monitor mymaster 127.0.0.1 7000 2
sentinel config-epoch mymaster 0
sentinel leader-epoch mymaster 0
sentinel known-slave mymaster 127.0.0.1 7002 #這裏
# Generated by CONFIG REWRITE
sentinel known-slave mymaster 127.0.0.1 7001 #和這裏
sentinel current-epoch 0
再添加兩個sentinel的配置:
sed "s/26379/26381/g" redis-sentinel-26379.conf > redis-sentinel-26381.conf
sed "s/26379/26380/g" redis-sentinel-26379.conf > redis-sentinel-26380.conf
啓動和查看狀態
redis-sentinel redis-sentinel-26381.conf
redis-sentinel redis-sentinel-26380.conf
[root@localhost config]# ps -ef | grep redis-sentinel
root 1336 1 0 20:58 ? 00:00:01 redis-sentinel *:26379 [sentinel]
root 1386 1 0 21:09 ? 00:00:00 redis-sentinel *:26380 [sentinel]
root 1396 1 0 21:11 ? 00:00:00 redis-sentinel *:26381 [sentinel]
root 1400 1250 0 21:11 pts/0 00:00:00 grep --color=auto redis-sentinel
連接一個 sentinel 並執行info
[root@localhost config]# redis-cli -p 26380
127.0.0.1:26380> info
最後一行表示 它也發下了master 和slaves 並且 sentine之間彼此連接上了
master0:name=mymaster,status=ok,address=127.0.0.1:7000,slaves=2,sentinels=3
Java 客戶端連接Redis Sentinel
第一個問題 客戶端是否能使用直連。
答案是否定的,搞可用僅存在與服務端 ,客戶端需要及時獲取故障轉移之後的服務端地址纔行。
客戶端實現的基本原理:首先 要遍歷Sentinel節點集合
獲取一個可用的Sentinel節點,同時 如果要獲取master 就要獲取masterName
第二步:同過上面獲取的兩個參數,去請求能夠ping 通的 sentinel-k 然後返回 sentinel 自動獲取到的 master節點信息
第三步:驗證 獲取到的節點是否是真正的master節點:
第四步:客戶端訂閱服務端 ,當master發生變化之後 由sentinel將新的master信息發送給客戶端
客戶端接入流程:
- 獲取Sentinel地址集合
- 獲取masterName
- 需要注意這裏不是代理模式,客戶端並不是每次從sentinel那裏獲取數據。
public static void main(String[] args) {
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(10);
config.setMaxWaitMillis(10000);
String masterName = "mymaster";
Set<String> sentinelSet = new HashSet<>();
sentinelSet.add("127.0.0.1:26379");
sentinelSet.add("127.0.0.1:26380");
sentinelSet.add("127.0.0.1:26381");
JedisSentinelPool pool = new JedisSentinelPool(masterName, sentinelSet, config);
Jedis jedis = null;
try {
jedis = pool.getResource();
String value = jedis.get("hello");
System.out.println(value);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (jedis != null) {
jedis.close();
}
}
}
故障轉移演練
創建項目添加倚賴:
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.6</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.1</version>
</dependency>
編寫代碼 啓動
public class RedisSentinelFailoverTest {
private static Logger logger = LoggerFactory.getLogger(RedisSentinelFailoverTest.class);
public static void main(String[] args) {
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(10);
config.setMaxWaitMillis(10000);
String masterName = "mymaster";
Set<String> sentinelSet = new HashSet<>();
sentinelSet.add("192.168.5.129:26379");
sentinelSet.add("192.168.5.129:26380");
sentinelSet.add("192.168.5.129:26381");
JedisSentinelPool pool = new JedisSentinelPool(masterName, sentinelSet);
int counter = 0;
while (true){
counter++;
Jedis jedis = null;
try {
jedis = pool.getResource();
int i = new Random().nextInt(100000);
String key = "key-"+i;
String value = "value-"+i;
jedis.set(key,value);
if (counter %100 == 0)
logger.info("{} value is {}",key,jedis.get(key));
TimeUnit.MILLISECONDS.sleep(10);
} catch (Exception e) {
logger.error( e.getMessage(),e);
} finally {
if (jedis != null) {
jedis.close();
}
}
}
}
}
查詢 7000節點的 process_id:2140
127.0.0.1:7000> info server
然後執行
[root@localhost config]# kill -9 2140
[root@localhost config]# ps -ef | grep redis-server | grep 7000
執行後會拋出大量的異常
但根據之前的配置 30秒後 會重新連接成功