1. 程式人生 > >Redis叢集:哨兵機制配置

Redis叢集:哨兵機制配置

前置redis單例基本搭建參考部落格:redis基礎服務搭建

redis叢集主要修改配置:主從複製 1. 主機配置 複製一份redis.conf成redis-6379.conf。修改配置:

	```
	#演示方便,開放ip連線
	bind 0.0.0.0
	#後臺執行
	daemonize yes
	#pid檔案
	pidfile /var/run/redis_6379.pid
	#日誌檔案
	logfile "6379.log"
	```



2. 從機配置
	複製一份redis.conf成redis-6380.conf。修改配置:
	```
		#設定所有ip都可訪問
		bind 0.0.0.0
		#埠
		port 6380
		#是否後臺方式啟動
		daemonize yes
		#每個服務一個pid,存放地址
		pidfile /var/run/redis_6380.pid
		#日誌檔案設定
		logfile "6380.log"
		#slaveof表示作為從庫的配置,設定主庫地址埠(主寫從複製讀)
		slaveof 127.0.0.1 6379
		#主庫密碼(沒有設定不用寫)
		requirepass 654321
		#從庫只能讀不能寫(主從配置)
		slave-read-only yes
		#單臺伺服器做叢集需要修改,名稱不能一致
		dbfilename dump-6379.rdb
	```

這裡注意如果有密碼需要配置requirepass屬性,否則redis日誌中會報錯許可權驗證問題

3. 啟動服務(進入redis根目錄)執行命令:我這裡檔名為redis-6379.conf、redis-6380.conf、redis-6381.conf存放在根目錄
	```
	[[email protected]_235_253_centos redis-4.0.9]# ./src/redis-server redis-6379.conf 
	[[email protected]_235_253_centos redis-4.0.9]# ./src/redis-server redis-6380.conf 
	[
[email protected]
_235_253_centos redis-4.0.9]# ./src/redis-server redis-6381.conf ``` 4. 檢視redis的資訊 檢視redis的資訊 主庫資訊 ``` [[email protected]_235_253_centos redis-4.0.9]# ./src/redis-cli -p 6379 -a 654321 info replication# Replication ``` 其中-p 6379表示指定埠 -a 654321表示指定埠的密碼,沒有可以不加此引數 replication表示主從的資訊 ``` # Replication #主庫 role:master #2從庫 connected_slaves:2 slave0:ip=119.29.76.169,port=6381,state=online,offset=207209,lag=1 slave1:ip=119.29.76.169,port=6380,state=online,offset=207209,lag=1 master_replid:59f3ac708c36d91887f61d92d48a0ea8ac397fe5 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:207209 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:207209 ``` 檢視6380從庫資訊 ``` [
[email protected]
_235_253_centos redis-4.0.9]# ./src/redis-cli -p 6380 -a 654321 info replication # Replication #從庫 role:slave #主庫地址 master_host:119.29.76.169 #主庫埠 master_port:6379 master_link_status:up master_last_io_seconds_ago:1 master_sync_in_progress:0 slave_repl_offset:233021 slave_priority:100 slave_read_only:1 connected_slaves:0 master_replid:59f3ac708c36d91887f61d92d48a0ea8ac397fe5 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:233021 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:233021 ```

配置哨兵:

  1. 複製根目錄下sentinel.conf配置檔案
  2. 修改主要配置
			#設定哨兵服務埠
			port 26379
			#設定後臺啟動
			daemonize yes
			#檔案地址存放地址
			dir /opt/redis-4.0.11/data
			#Sentinel去監視一個名為mymaster 的主redis例項,這個主例項的IP地址為本機地址127.0.0.1,埠號為6379,而將這個主例項判斷為失效至少需要2個 Sentinel程序的同意,只要同意Sentinel的數量不達標,自動failover就不會執行
			sentinel monitor mymaster 127.0.0.1  6379 2
			#設定連線master和slave時的密碼,注意的是sentinel不能分別為master和slave設定不同的密碼,因此master和slave的密碼應該設定相同。
			# sentinel auth-pass <master-name> <password>
			#指定了Sentinel認為Redis例項已經失效所需的毫秒數。當例項超過該時間沒有返回PING,或者直接返回錯誤,那麼Sentinel將這個例項標記為主觀下線。只有一個 Sentinel程序將例項標記為主觀下線並不一定會引起例項的自動故障遷移:只有在足夠數量的Sentinel都將一個例項標記為主觀下線之後,例項才會被標記為客觀下線,這時自動故障遷移才會執行
			sentinel down-after-milliseconds mymaster 30000
			#指定了在執行故障轉移時,最多可以有多少個從Redis例項在同步新的主例項,在從Redis例項較多的情況下這個數字越小,同步的時間越長,完成故障轉移所需的時間就越長
			sentinel parallel-syncs mymaster 1
			#如果在該時間(ms)內未能完成failover操作,則認為該failover失敗
			sentinel failover-timeout mymaster 180000
			#指定sentinel檢測到該監控的redis例項指向的例項異常時,呼叫的報警指令碼。該配置項可選,但是很常用
			# sentinel notification-script <master-name> <script-path>
  1. 啟動哨兵:兩個配置檔案在根目錄分別為sentinel-26379.conf、sentinel-26380.conf

     	```
     	[[email protected]_235_253_centos redis-4.0.9]# ./src/redis-sentinel sentinel-26379.conf 
     	[[email protected]_235_253_centos redis-4.0.9]# ./src/redis-sentinel sentinel-26380.conf 
     	```
    

Spring boot 配置:

  1. 引入redis包
 <dependency>
	            <groupId>org.springframework.boot</groupId>
	            <artifactId>spring-boot-starter-data-redis</artifactId>
 </dependency>
  1. application.yml Spring配置
spring:
  redis:
    #有密碼則需要設定
    password: 654321
	#這裡只需要配置哨兵即可
    sentinel:
      master: mymaster
      nodes: 119.xx.xx.xxx:26379,119.xx.xx.xxx:26380
  1. redis序列化
/**
 * redis序列化配置
 * @author 50238
 */
@Configuration
public class RedisConfig {
    /**
     * redisTemplate 序列化使用的jdkSerializeable, 儲存二進位制位元組碼, 所以自定義序列化類
     *
     * @param redisConnectionFactory
     * @return
     */
    @Bean
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        // 使用Jackson2JsonRedisSerialize 替換預設序列化
        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);

        // 設定value的序列化規則和 key的序列化規則
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }

}

這裡我比較好奇為什麼spring boot 可以直接裝配就覆蓋了預設的redis序列化(jdk自帶的序列化),可以檢視原始碼RedisAutoConfiguration中使用的是條件裝配,主要在於這個註解@ConditionalOnMissingBean( name = {“redisTemplate”} ),當不存在redisTemplate裝載時才會去裝載預設的模板,這也體現了boot 的約定大於配置吧,很多地方的裝配應該都是如此。

最後測試程式碼:

@RunWith(SpringRunner.class)
@SpringBootTest
public class BlogApplicationTests {

    @Autowired
    private RedisTemplate redisTemplate;

    @Test
    public void contextLoads() {
        ValueOperations valueOperations = redisTemplate.opsForValue();
        valueOperations.set("open", "String");
        System.out.println(valueOperations.get("open"));
    }
}

使用redis工具也可以看到確實主從做了複製,複製資訊等可以從redis日誌中也可以看到。 Redis哨兵-實現Redis高可用