redis哨兵配置 總結


本文內容涵蓋

  1. windows下單機部署redis多實例 、linux下哨兵示例
  2. redis主從配置
  3. redis哨兵配置

以spring boot redis demo下一個存action,一個取action為例進行演示。

本文只講配置,不講原理(原理隨便都是,配置完整完善且簡潔的少)

redis 命令介紹

  1. 啟動實例 D:\Redis-6379> redis-server.exe redis.windows.conf
  2. 指定進入哪個redis實例,redis的默認客戶端是redis-cli, D:\Redis-6379> redis-cli -h 192.168.154.128 -p 6379 # 默認為localhost:6379
  3. 顯示某個redis實例信息,先用redis-cli進入到redis實例,192.168.154.128:6379 > info replication
  4. 設置主從關系。 只需要操作從庫,無需操作主庫。1. redis-cli 2. 192.168.154.128:6379 > slaveof 172.17.0.3 6379 # 192.168.154.128:6379就變成172.17.0.3 6379 的從庫了
  5. 取消主從關系。操作從庫,slaveof no one
  6. 啟動哨兵進程 D:\Redis-6379> redis-server.exe sentinel.conf --sentinel
  7. windows下將redis實例作為一個服務(name:redis6380),可隨機啟動,redis-server.exe --service-install redis.windows-service-6380.conf --service-name redis6380 --port 6380
  8. windows下刪除服務 sc delete redis6380

准備材料

Redis-x64-3.0.504.zip

1. windows下單機部署redis多實例

解壓后拷貝三份

redis主從配置

分別設置 redis.windows.conf, 這里以79為主庫,80,81位從庫

修改配置項:

79:
port 6379

80:
port 6380
slaveof 127.0.0.1 6379 # 表示此庫作為127.0.0.1 6379的從庫

81:
port 6381
slaveof 127.0.0.1 6379

此時主從的配置已經完成。

依次啟動三個實例

  1. D:\Redis-6379>redis-server.exe redis.windows.conf
  2. D:\Redis-6380>redis-server.exe redis.windows.conf
  3. D:\Redis-6381>redis-server.exe redis.windows.conf

再啟動一個redis-cli

D:\Redis-6379>redis-cli.exe -h 127.0.0.1 -p 6379

查看當前實例信息,可以看到,有兩個slave。connected_slaves:2

127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=6380,state=online,offset=133629,lag=1
slave1:ip=127.0.0.1,port=6381,state=online,offset=133895,lag=0
master_repl_offset:133895
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:133894

再來測試下主從,發個請求往79里塞值,看80,81是否能同步數據。(主庫讀寫,從庫只讀)

這里的程序demo不做展開,網上找下很多。

pom.xml

		 <dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-redis</artifactId>
		</dependency>

		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-pool2</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>

properties:

# Redis數據庫索引(默認為0)
spring.redis.database=0
# Redis服務器地址
spring.redis.host=localhost
# Redis服務器連接端口
# localhost master:6379  slaves: 6380 6381
spring.redis.port=6379
# Redis服務器連接密碼(默認為空)
spring.redis.password=
#連接池最大連接數(使用負值表示沒有限制)
spring.redis.pool.max-active=8
# 連接池最大阻塞等待時間(使用負值表示沒有限制)
spring.redis.pool.max-wait=-1
# 連接池中的最大空閑連接
spring.redis.pool.max-idle=8
# 連接池中的最小空閑連接
spring.redis.pool.min-idle=0
# 連接超時時間(毫秒)
spring.redis.timeout=5000
/**
 * RedisSerializer redisSerializer =new StringRedisSerializer();
 * 因為redisTemplate默認會序列化key,我們查看的時候,key就是序列化后的key,不方便查看.
 * 所以我們先序列化一把key,redisTemplate再序列化一把。當然存取的序列化要一致,不然匹配不到key
 */
@Service
public class RedisService {
    @Resource
    private RedisTemplate<String,Object> redisTemplate;

    public void set(String key, Object value) {
        //更改在redis里面查看key編碼問題
        RedisSerializer redisSerializer =new StringRedisSerializer();
        redisTemplate.setKeySerializer(redisSerializer);

        ValueOperations<String,Object> vo = redisTemplate.opsForValue();
        vo.set(key, value);

    }

    public Object get(String key) {
        RedisSerializer redisSerializer =new StringRedisSerializer();
        redisTemplate.setKeySerializer(redisSerializer); 

        ValueOperations<String,Object> vo = redisTemplate.opsForValue();
        return vo.get(key); 
    }

}
@RestController
public class CityController {

    @Autowired
    private RedisService redisService;

    //http://localhost:8888/saveCity?cityName=北京&cityIntroduce=中國首都&cityId=1
    @GetMapping(value = "saveCity")
    public String saveCity(int cityId, String cityName, String cityIntroduce) {
        City city = new City(cityId, cityName, cityIntroduce);
        redisService.set(cityId + "", city);
        return "success";
    }

    //http://localhost:8888/getCityById?cityId=1
    @GetMapping(value = "getCityById")
    public City getCity(String cityId) {
        City city = (City) redisService.get(cityId + "");
        return city;
    }
}

如上配置完spring boot demo for redis 后

  1. 塞值 http://localhost:8888/saveCity?cityName=北京&cityIntroduce=中國首都&cityId=1

  2. 用redis-cli(如果你有別的redis客戶端也一樣)分別進到三個實例中進行數據獲取:

可以看到三個實例數據已經同步。

主從測試通過。

redis哨兵配置

  1. 三個實例目錄下分別新建sentinel.conf, 端口為26379,26380,26381,其他一致
port 26379
sentinel monitor mymaster 127.0.0.1 6379 2
daemonize yes

最后的2: [quorum]是一個數字,指明當有多少個sentinel認為一個master失效時,master才算真正失效

(哨兵就是個獨立的進程,用來監聽實例信息的變化,且對相關操作做出反應,這里對每個實例都配一個哨兵進程)

  1. 啟動三個哨兵進程

  2. D:\Redis-6379>redis-server.exe sentinel.conf --sentinel

  3. D:\Redis-6380>redis-server.exe sentinel.conf --sentinel

  4. D:\Redis-6381>redis-server.exe sentinel.conf --sentinel

至此,哨兵配置且啟動完成。

測試,停掉主庫79的進程,這里就是在79實例的cmd(非哨兵cmd)下ctrl+c

觀察另外兩個實例在cmd中輸出的日志

81的日志

簡單分析下日志

  1. 老大下線了
  2. 瘋狂的發送心跳進行詢問(老大,你死了沒?沒回答,就應該是死了,哨兵進程輔助slave(s)建立新的老大)
  3. 自己成為老大 MASTER MODE enabled
  4. 其他小弟進行數據請求
  5. 新的主從建立
[15112] 09 Sep 14:57:23.699 # Connection with master lost.
[15112] 09 Sep 14:57:23.700 * Caching the disconnected master state.
[15112] 09 Sep 14:57:24.420 * Connecting to MASTER 127.0.0.1:6379
[15112] 09 Sep 14:57:24.420 * MASTER <-> SLAVE sync started
[15112] 09 Sep 14:57:25.421 * Non blocking connect for SYNC fired the event.
[15112] 09 Sep 14:57:25.421 # Sending command to master in replication handshake: -Writing to master: Unknown error
[15112] 09 Sep 14:57:25.423 * Connecting to MASTER 127.0.0.1:6379
[15112] 09 Sep 14:57:25.423 * MASTER <-> SLAVE sync started
[15112] 09 Sep 14:57:26.424 * Non blocking connect for SYNC fired the event.
[15112] 09 Sep 14:57:26.424 # Sending command to master in replication handshake: -Writing to master: Unknown error
[15112] 09 Sep 14:57:26.426 * Connecting to MASTER 127.0.0.1:6379
[15112] 09 Sep 14:57:26.426 * MASTER <-> SLAVE sync started
[15112] 09 Sep 14:57:27.427 * Non blocking connect for SYNC fired the event.
[15112] 09 Sep 14:57:27.427 # Sending command to master in replication handshake: -Writing to master: Unknown error
。。。。。。。。。。。。。。。。。。。。
[15112] 09 Sep 14:57:53.517 * Connecting to MASTER 127.0.0.1:6379
[15112] 09 Sep 14:57:53.517 * MASTER <-> SLAVE sync started
[15112] 09 Sep 14:57:54.006 * Discarding previously cached master state.
[15112] 09 Sep 14:57:54.007 * MASTER MODE enabled (user request from 'id=8 addr=127.0.0.1:51668 fd=14 name=sentinel-efc4be2b-cmd age=70 idle=0 flags=x db=0 sub=0 psub=0 multi=3 qbuf=0 qbuf-free=32768 obl=36 oll=0 omem=0 events=rw cmd=exec')
[15112] 09 Sep 14:57:54.009 # CONFIG REWRITE executed with success.
[15112] 09 Sep 14:57:54.855 * Slave 127.0.0.1:6380 asks for synchronization
[15112] 09 Sep 14:57:54.855 * Full resync requested by slave 127.0.0.1:6380
[15112] 09 Sep 14:57:54.856 * Starting BGSAVE for SYNC with target: disk
[15112] 09 Sep 14:57:54.863 * Background saving started by pid 15712
[15112] 09 Sep 14:57:55.125 # fork operation complete
[15112] 09 Sep 14:57:55.126 * Background saving terminated with success
[15112] 09 Sep 14:57:55.129 * Synchronization with slave 127.0.0.1:6380 succeeded

觀察哨兵cmd也會有相關的日志輸出,這里就不展開了。

現在我們要確定哨兵進程是否幫我們建立新的master節點了。

redis-cli進入到81中

info replication

127.0.0.1:6381> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=127.0.0.1,port=6380,state=online,offset=17573,lag=1
master_repl_offset:17839
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:17838

role從slave變成了master

哨兵測試通過。

最后剩下spring boot中進行相關的設置。

properties新增

# name of Redis server  哨兵監聽的Redis server的名稱
spring.redis.sentinel.master=mymaster
# comma-separated list of host:port pairs  哨兵的配置列表
spring.redis.sentinel.nodes=127.0.0.1:26379,127.0.0.1:26380,127.0.0.1:26381
package com.myredis.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisNode;
import org.springframework.data.redis.connection.RedisSentinelConfiguration;

import java.lang.reflect.Method;


@Configuration
@EnableCaching//開啟緩存
public class RedisConfig extends CachingConfigurerSupport {

    @Value("${spring.redis.sentinel.nodes}")
    private String redisNodes;

    @Value("${spring.redis.sentinel.master}")
    private String master;

    /**
     * 自定義生成redis-key
     *
     * @return
     */
    @Bean
    public KeyGenerator keyGenerator() {
        return new KeyGenerator() {
            @Override
            public Object generate(Object target, Method method, Object... params) {
                StringBuilder sb = new StringBuilder();
                sb.append(target.getClass().getName());
                sb.append(method.getName());
                for (Object obj : params) {
                    sb.append(obj.toString());
                }
                return sb.toString();
            }
        };
    }
    @Bean
    public RedisSentinelConfiguration redisSentinelConfiguration(){
        RedisSentinelConfiguration configuration = new RedisSentinelConfiguration();
        String[] host = redisNodes.split(",");
        for(String redisHost : host){
            String[] item = redisHost.split(":");
            String ip = item[0];
            String port = item[1];
            configuration.addSentinel(new RedisNode(ip, Integer.parseInt(port)));
        }
        configuration.setMaster(master);
        return configuration;
    }  
}

程序起來后,kill掉某個主庫或從庫,看數據是否依然能讀取。

簡潔版配置過程(linux)

當前系統redis(v5.0.5)部署采用一主二從三哨兵

下面舉例說明

服務器地址

10.136.55.30: 默認為主實例(master)(下文中30替代,依次如是)
10.136.55.31: 默認為從實例(slave)
10.136.55.32: 默認為從實例(slave)
10.136.55.33: 默認為哨兵(sentinel)
10.136.55.34: 默認為哨兵(sentinel)
10.136.55.35: 默認為哨兵(sentinel)

1、將對應版本的redis拷貝到6台服務器的相關目錄下

(建議目錄一致,如/home/vlog/redis/redis-5.0.5/)

2、啟動30、31、32實例

(1)$ cd /home/vlog/redis/redis-5.0.5/src

(2)$ ./redis-server ../redis.conf # 以redis.conf配置啟動實例

3、分別配置30、31、32實例

修改redis-conf 文件
注釋掉bind 127.0.0.1
protected-mode yes 修改為 protected-mode no
daemonize no修改為daemonize yes
stop-writes-on-bgsave-error yes改為stop-writes-on-bgsave-error no

(1)$ ./redis-cli # 用默認客戶端進入redis

(2)127.0.0.1:6379> config get requirepass # 查看當前redis有沒有設置密碼

(3)127.0.0.1:6379> config set requirepass 123456 # 設置密碼

(4)127.0.0.1:6379> auth 123456 # 有密碼了后,主動輸入密碼

4、分別配置31、32為slave(主從配置)

(1)127.0.0.1:6379> slaveof 10.136.55.30 --設置當前庫為10.136.55.30 6379的從庫
(2)127.0.0.1:6379>config set masterauth 123456 # 主redis服務的訪問密碼

5、查看主從配置是否成功

(1)進到30:6379> info replication

--Replication
role:master
connected_slaves:2
slave0:ip=10.136.55.31,port=6379,state=online,offset=133629,lag=1
slave1:ip=10.136.55.32,port=6379,state=online,offset=133895,lag=0 master_repl_offset:133895
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2 repl_backlog_histlen:133894
...
可以看到30作為master,有兩個slave
(2)進到31、32> info replication
--Replication
role:slave
Master_host:10.136.55.30
Master_port:6379
...
可以看到31、32作為slave

至此,主從配置完成。

6、進行哨兵配置

sentinel.conf(復制一樣的三份)

port 26379
sentinel monitor mymaster 10.136.55.30 6379 1
daemonize yes
sentinel auth-pass mymaster 123456
protected-mode no

--哨兵的端口
port 26379
--初次配置時的狀態,這個sentinel會自動更新 最后的1表示有n個哨兵確認master是否真正宕機,mymaster 為哨兵配置的定義名稱
sentinel monitor mymaster 10.136.55.30 6379 1
--redis是否要用守護線程的方式啟動
daemonize yes
--哨兵監聽的主從集群密碼
sentinel auth-pass mymaster 123456
--保護模式關閉
protected-mode no

將其拷貝到33、34、35 /home/vlog/redis/redis-5.0.5/sentinel.conf

7、啟動哨兵

(1)$ cd /home/vlog/redis/redis-5.0.5/src

(2)$ ./redis-server ../sentinel.conf --sentinel

8、查看哨兵配置情況(33、34、35)

$ ./redis-cli -h 127.0.0.1 -p 26379 --這里要指定端口,redis-cli默認進入6379的實例
127.0.0.1:26379> info sentinel
-- Sentinel
Sentinel_masters:1
...

Master0:name=mymaster,status=ok,address=10.136.55.30:6379,slaves=2,sentinels=1

若配置成功,則可看到以上信息。

至此哨兵配置完成。

that's all!!!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM