1. 程式人生 > >redis的一主二從三哨兵(Windows)

redis的一主二從三哨兵(Windows)

redis的一主二從三哨兵(Windows)

一、一主二從配置

  1. redis官網下載最新版,然後複製三份,slave redis與master redis是一樣的,只是配置不一樣而已。如下,為了更好區分,可以將資料夾的命名加上master和slave標識,以及埠號。
    在這裡插入圖片描述
  2. 配置檔案
    修改每個redis中的redis.conf配置檔案,一主二從的模式,就是配置一個master redis與兩個slave redis。
  • master需要修改redis.conf配置檔案引數有:

. bind 10.112.11.186 127.0.0.1 (繫結redis訪問地址,10.112.11.186是內網地址,即你cmd中ipconfig命令出來的ipv4ip地址,可以是公網ip,也可以是私網ip);
. port 6380(redis訪問埠號)
. protected-mode no(如果不配置哨兵,並且沒有設定連線密碼,那麼這個屬性一定要設定no,這是redis的安全模式,預設是yes,即開啟狀態,如果你沒有設定密碼,那麼你用redis的客戶端(如jedis)是無法訪問redis的)。報錯資訊如下:

Cannot get master address from sentinel running @ 10.112.11.186:26381

. 其他優化引數,自行配置

  • slave-6381 需要修改redis.conf配置檔案引數有:

. bind 10.112.11.186 127.0.0.1 (繫結redis訪問地址,10.112.11.186是內網地址,即你cmd中ipconfig命令出來的ipv4ip地址,可以是公網ip,也可以是私網ip);
. port 6381(redis訪問埠號)
. protected-mode no(如果不配置哨兵,並且沒有設定連線密碼,那麼這個屬性一定要設定no,這是redis的安全模式,預設是yes,即開啟狀態,如果你沒有設定密碼,那麼你用redis的客戶端(如jedis)是無法訪問redis的,報錯資訊如下:

Cannot get master address from sentinel running @ 10.112.11.186:26381)。

. slaveof 127.0.0.1 6380(設定master 的連線ip和port)
. 其他優化引數,自行配置

  • slave-6382 需要修改redis.conf配置檔案引數有:

. bind 10.112.11.186 127.0.0.1 (繫結redis訪問地址,10.112.11.186是內網地址,即你cmd中ipconfig命令出來的ipv4ip地址,可以是公網ip,也可以是私網ip);
. port 6382(redis訪問埠號)
. protected-mode no(如果不配置哨兵,並且沒有設定連線密碼,那麼這個屬性一定要設定no,這是redis的安全模式,預設是yes,即開啟狀態,如果你沒有設定密碼,那麼你用redis的客戶端(如jedis)是無法訪問redis的,報錯資訊如下:

Cannot get master address from sentinel running @ 10.112.11.186:26381)。

. slaveof 127.0.0.1 6380(設定master 的連線ip和port)
. 其他優化引數,自行配置

  1. 啟動配置,為了不用每次從cmd中輸入命令列啟動redis,可以為每一個redis建立啟動指令碼。
    在這裡插入圖片描述
    startRedisServer.bat指令碼如下:
@echo off
redis-server.exe redis.windows.conf
@pause
  1. 啟動後,先啟動master redis,然後啟動slave redis
    在這裡插入圖片描述

  2. 檢視redis資訊
    在這裡插入圖片描述
    注:使用redis.exe -p 6380連線redis,如果使用的redis port不是預設的埠6379,則必須加上埠號。

二、redis哨兵的配置

  1. 在每個redis中建立一個哨兵的配置檔案,sentinel.conf
    在這裡插入圖片描述
    sentinel.conf

# 雖然你前面配置主從模式的時候,已經關閉了保護模式,但由於再配置了哨兵後,客戶端連線的是哨兵,而不是直接連線主節點(從而實現了客戶端與master redis的解耦,這也是為什麼哨兵模式能實現完全自動化進行故障轉移的原因),所以需要在哨兵中關閉保護模式。
protected-mode no
#當前Sentinel服務執行的埠(其他兩個sentinel.conf配置,只要這個地方埠改成26381,和26382就行)
port 26380
# 哨兵監聽的主伺服器
sentinel myid 41fff2d5fcefd3bd55ee99430ac53e07ec84a064
#
sentinel monitor master 127.0.0.1 6382 2
#如果10秒後,mysater仍沒啟動過來,則啟動failover
sentinel down-after-milliseconds master 3000
# 執行故障轉移時, 最多有1個從伺服器同時對新的主伺服器進行同步
sentinel failover-timeout master 10000

主要對第三行的配置引數解釋一下:
sentinel monitor [master-name] [ip] [port] [quorum]
master-name:master名稱,自定義。sentinel使用master name來標識哪個redis是master redis,為什麼是用 name而不是用ip來標識master redis,是因為,哨兵模式下,master redis如果出現故障了,可以動態配置另外一臺slave redis作為新的master redis,所以master ip是不固定的,也就沒法使用固定ip來確定哪個是master
ip port : IP地址和埠號
quorun:票數,Sentinel需要協商同意master是否可到達的數量。

  1. 啟動配置,為了不用每次從cmd中輸入命令列啟動sentinel,可以為每一個sentinel建立啟動指令碼startRedisSentinel.bat
    在這裡插入圖片描述
    配置檔案只需要配置master的資訊就好啦,不用配置slave的資訊,因為slave能夠被自動檢測到(master節點中有關於slave的訊息)。
@echo off
redis-server.exe sentinel.conf --sentinel
@pause
  1. 啟動三個哨兵,無先後關係
    在這裡插入圖片描述

  2. 客戶端jedis連線哨兵,程式碼

package com.redis;

import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisSentinelPool;

import java.util.HashSet;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * 請填寫類註釋
 * @since 2018年12月27日 15:30
 */
public class RedisCluster {
    //key的過期時間
    private final static Integer EXPIRE_DATE = 1800;
    //過期單位
    private final static TimeUnit TIME_UNIT = TimeUnit.MILLISECONDS;

    public static void main(String[] args) {
        //master name,我們在哨兵上配置過的別名maserName
        String maserName = "master";
        Set<String> sentinels = new HashSet<>();
        //設定所有的哨兵ip和port,不需要
        sentinels.add("127.0.0.1:26380");
        sentinels.add("127.0.0.1:26381");
        sentinels.add("127.0.0.1:26382");

        GenericObjectPoolConfig gPoolConfig=new GenericObjectPoolConfig();
        //idle:在池中,處於空閒狀態的最大連線數
        gPoolConfig.setMaxIdle(3);
        //Total:在池中,一共有多少連線數
        gPoolConfig.setMaxTotal(3);
        //MaxWaitMillis:從idle佇列裡面取物件時,若阻塞的話,則最大等待時長
        gPoolConfig.setMaxWaitMillis(10);
        //jmx是否開啟監控
        gPoolConfig.setJmxEnabled(true);

        JedisSentinelPool sentinelPool = new JedisSentinelPool(maserName,sentinels,gPoolConfig);

        //一個while死迴圈,每隔一秒往master塞入一個值,並且日誌列印
        Jedis jedis = null;
        while (true){
            try{
                jedis = sentinelPool.getResource();

                int index = new Random().nextInt(100000);
                String key = "k-" + index;
                String value = "v-" + index;
                jedis.set(key,value);
                jedis.expire(key,EXPIRE_DATE);
                System.out.printf("%s  value is %s\n",key,jedis.get(key));

                TimeUnit.MILLISECONDS.sleep(1000);
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                if(jedis != null){
                    jedis.close();
                }
            }
        }
        //sentinelPool.close();
    }
}

在這裡插入圖片描述