Redis筆記(三)實驗部分:Redis Sentinel的配置與安裝&Java客戶端連接 Redis Sentinel&故障轉移演練

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信息發送給客戶端
在這裏插入圖片描述
客戶端接入流程:

  1. 獲取Sentinel地址集合
  2. 獲取masterName
  3. 需要注意這裏不是代理模式,客戶端並不是每次從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秒後 會重新連接成功

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章