首頁 > 軟體

docker搭建redis哨兵叢集並且整合springboot的實現

2022-07-11 14:00:28

1、建立兩個資料夾redis和sentinel資料夾用於存放docker-compose.yml檔案

2、redis下的docker-compose.yml

version: "3"
services:
  master:
    image: redis:latest
    container_name: my_redis_master
    command: redis-server --requirepass root  # 在連線容器時需要密碼
    ports:
      - 6379:6379
  slave1:
    image: redis:latest
    depends_on:  # 這裡目的是需要先啟動master,隨後再啟動slave節點
      - master
    container_name: my_redis_slave1
    command: redis-server --slaveof my_redis_master 6379 --requirepass root --masterauth root # 再容器啟動後,通過這裡命令來指定主節點ip地址
    ports:
      - 6380:6379
  slave2:
    image: redis:latest
    depends_on:
      - master
    container_name: my_redis_slave2
    ports:
     - 6381:6379
    command: redis-server --slaveof my_redis_master 6379 --requirepass root --masterauth root
networks:   # 這裡是設定網路環境,目的是讓容器之間能夠相互連線,如果不設定,哨兵將獲取不到從節點的資訊,並且無法轉換master節點
  default:
    external:
      name: redis_net

3、sentinel下的docker-compose.yml檔案以及sentinel.conf組態檔

version: '3'
services:
  sentinel1:
    image: redis
    container_name: redis-sentinel-1
    networks:
      - redis_net
    ports:
      - 26379:26379
    command: redis-sentinel /usr/local/etc/redis/sentinel.conf  # 啟動哨兵,並且指定組態檔
    volumes:
      - ./sentinel1.conf:/usr/local/etc/redis/sentinel.conf

  sentinel2:
    image: redis
    container_name: redis-sentinel-2
    networks:
      - redis_net
    ports:
      - 26380:26379
    command: redis-sentinel /usr/local/etc/redis/sentinel.conf
    volumes:
      - ./sentinel2.conf:/usr/local/etc/redis/sentinel.conf

  sentinel3:
    image: redis
    container_name: redis-sentinel-3
    networks:
      - redis_net
    ports:
      - 26381:26379
    command: redis-sentinel /usr/local/etc/redis/sentinel.conf
    volumes:
      - ./sentinel3.conf:/usr/local/etc/redis/sentinel.conf
networks:  # 這裡指定網路跟redis在同一個網路環境下
  redis_net:
    external:
      name: redis_net

sentinel組態檔,將下面的組態檔 cp成三分就行
port 26379
dir /tmp
sentinel monitor mymaster 192.168.16.2 6379 2  #指定叢集的名字以及叢集中master的ip地址,這裡是容器地址,如果是用的虛擬機器器地址我這邊會導致master轉換不了。2就是指哨兵有多少個哨兵認為失效master就失效,保證超過50%就行
sentinel auth-pass mymaster root # 重點:我就是在這裡忘了設定master需要密碼登陸 導致一直獲取不到master節點下的從資訊
sentinel down-after-milliseconds mymaster 30000 #這裡是指定master在失效之後多久就認為失效
sentinel parallel-syncs mymaster 1 # failover進行主備切換時最多可以有多少個slave對新的master進行同步,值越小完成failover的時間就越長,設定為1就是每次只有一個slave處於不能處理命令的狀態
sentinel failover-timeout mymaster 180000 

sentinel deny-scripts-reconfig yes

4、spring boot整合redis哨兵

依賴

<dependency>

      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-redis</artifactId>
      <!-- 排除lettuce包,使用jedis代替-->
      <exclusions>
        <exclusion>
          <groupId>io.lettuce</groupId>
          <artifactId>lettuce-core</artifactId>
        </exclusion>
      </exclusions>
    </dependency>

    <dependency>
      <groupId>redis.clients</groupId>
      <artifactId>jedis</artifactId>
      <version>3.0.1</version>
    </dependency>

設定

spring:
  redis:
    sentinel:
      master: mymaster
      nodes: 192.168.16.5:26379,192.168.16.6:26380,192.168.16.7:26381  # 這裡是連線的docker容器中哨兵的ip
    jedis:
      pool:
        max-idle: 8
        min-idle: 0
        max-wait: -1
        max-active: 8
    password: root

如果使用的虛擬機器器中的docker ip地址 先設定路由表,這樣宿主機才能存取docker容器中的哨兵
route add -p 容器的網路地址 mask 子網掩碼 虛擬機器器ip地址 切記一定要關閉虛擬機器器的防火牆

設定bean

@Bean
    public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory redisConnectionFactory){
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);

        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);

        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();

        // key採用String的序列化方式
        redisTemplate.setKeySerializer(stringRedisSerializer);
        // hash的key也採用String的序列化方式
        redisTemplate.setHashKeySerializer(stringRedisSerializer);
        // value序列化方式採用jackson
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
        // hash的value序列化方式採用jackson
        redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }

5、哨兵工作方式

1、特點:

  • 每個哨兵程序會每秒一次向叢集中的所有redis傳送ping命令
  • 如果距離最近的一次ping命令的時間超過了 down-after-milliseconds設定的時間,那麼當前哨兵就會將起標記為主觀下線(SDOWN)
  • 如果Master被標記為了主觀下線,那麼其餘的哨兵會以每秒一次的頻率確認Master是否進入了主觀下線狀態
  • 如果有足夠的哨兵(組態檔中設定)程序在指定的範圍內確認Master進入主觀下線,則Master就會被改為客觀下線(ODWON)
  • 如果沒有的哨兵同意Master主伺服器下線,master的客觀下線狀態就會被移除

2、故障轉移(Raft演演算法):

  • 先選擇優先順序最高的(slave-priority)
  • 複製偏移量大的從節點(資料最新的)
  • runid最小的

3、缺點:

  • redis較難支援線上擴容,如果叢集容量達到上限時線上擴容會變的很複雜
  • 每個節點存入的資料都是相同的,容器造成資源的浪費
  • 容易導致資料的丟失
    • redis組態檔中
    • min-slaves-to-write 1
    • min-slaves-max-lag 10 表示至少要有1個salve節點與master資料同步超過10秒,就拒絕其它的請求
  • 腦裂 (網路分割區變化時,master和slave出現無法通訊時,sentinel會選擇新的master,那麼此時client一直在向之前的master傳送資料,將原master進行恢復成新master的slave時,就會丟失後來傳送的資料)

6、Redis-Cluster叢集

1、特點:

  • 節點連線是使用二進位制連線的
  • 節點fail是超過半數的節點檢測時才會失效
  • 使用者端只需要連線叢集中任何一個節點即可

2、工作方式

每個節點上都有slot槽的概念,取值範圍是0-16383,還有一個就是cluster用於叢集管理的外掛。當存取的key值到達時 redis會根據crc16進行計算,然後把計算的結果對16384取餘數,這樣就每個key就會有對應的編號在0-16383之間的雜湊槽,通過這個值跳轉到對應的節點中。
redis-cluster引入了主從模式,一個主節點對應多個從節點,當超過半數的從節點ping主節點超時時,就會認為主節點宕機了。

3、缺點:

  • 資料通過非同步複製,不保證資料的強一致性
  • 不支援多資料庫空間,叢集模式下只能使用1個資料庫空間 0

7、redis常見問題

1、快取雪崩
    描述:在同一時間段,快取集中過期。所有的請求都去查詢資料庫
    解決方案:
        解鎖或者佇列的方式防止大量執行緒對資料庫的一次性獨寫
        協調redis的過期時間,隨機時間
        做二級快取,一級快取為短期,二級快取為長期
        依賴隔離元件為後端限流並且降級

2、快取穿透
    描述:在redis中沒有查詢到並且資料庫中也沒有查詢到,下一次進來還是會到redis中查詢,就沒有查詢的意義了
    解決方案:
        布隆過濾器
        將空物件記錄在快取中

3、快取擊穿
    描述:查詢的某個key恰好失效,剛好又有大量的並行過來,造成DB壓力
    解決方案:
        通過加鎖或者佇列防止大量請求透過redis到DB中
        對於熱點key可以無限調長
        也可以做二級快取

4、快取降級
    描述:存取量劇增、服務出現問題,非核心的服務影響到核心流程的效能,但是仍需要服務還是可用

5、快取預熱
    描述:先將資料直接載入到redis中,防止使用者在請求時先查資料庫
    解決方案:
        定時重新整理快取

6、快取更新
    描述:維護大量快取,自定義快取淘汰的策略
    解決方案:定時清理過期的快取,先判斷快取是否過期,如果過期就去資料庫獲取新的資料然後再更新

到此這篇關於docker搭建redis哨兵叢集並且整合springboot的實現的文章就介紹到這了,更多相關docker搭建redis哨兵叢集內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com