docker compose搭建redis7.0.4高可用一主二從三哨兵集群並整合SpringBoot【圖文完整版】

一、前言

redis在我們企業級開發中是很常見的,但是單個redis不能保證我們的穩定使用,所以我們要建立一個集群。
redis有兩種高可用的方案:

  • High availability with Redis Sentinel
  • Scaling with Redis Cluster

第一個就是我們本次的要搭建的,就是高可用的哨兵,主redis掛掉,哨兵會進行投票進行故障轉移
第二個就是分片集群,哨兵的一個缺點就是只能存在一個master節點,寫的效率太低。分片集群就是解決哨兵的問題,可以水平擴展,提高redis的性能!

哨兵最低配是三哨兵,以奇數遞增。
分片集群最低配是三主三從。
本次以一台虛擬機進行搭建,小編也是搭建了一星期,主從沒啥問題,就是故障轉移不行,根本原因就是docker網絡的問題,redis和哨兵不在一個網段中。很多教學都是用host,但是不知道現在不能啟動成功,所以還是要在一個網絡中!

本次一體驗為主,太多知識性的問題,大家可以去官網看一下。

redis官網

二、docker和docker compose安裝

docker和docker compose安裝使用【最新版】

三、啟動redis主從

1. 創建一個redis-sentinel-test文件夾

mkdir redis-sentinel-test

2. 在裏面創建兩個文件夾

cd redis-sentinel-test/
mkdir redis
mkdir sentinel

3. 在redis創建compose文件

必須以docker-compose.yml命名,本次測試redis就不掛載目錄到宿主機了,需要的可以使用volumes掛載到宿主機!

vim docker-compose.yml

4. 編輯compose文件

這裡為了測試方便,就不設置密碼了!
protected-mode no:關閉就可以其他地方連接使用了
slave-announce-ip:使用宿主機的ip

version: "4.1"
services:
  master:
    image: redis:7.0.4
    container_name: redis-master
    command: bash -c "redis-server --protected-mode no --slave-announce-ip 192.168.84.143 --slave-announce-port 6379"
    ports:
      - 6379:6379
  slave1:
    image: redis:7.0.4
    container_name: redis-slave-1
    ports:
      - 6380:6379
    command:  bash -c "redis-server --protected-mode no --slaveof redis-master 6379 --slave-announce-ip 192.168.84.143 --slave-announce-port 6380"
  slave2:
    image: redis:7.0.4
    container_name: redis-slave-2
    ports:
      - 6381:6379
    command: bash -c "redis-server --protected-mode no --slaveof redis-master 6379 --slave-announce-ip 192.168.84.143 --slave-announce-port 6381"

5. 啟動redis主從

compose更新了,啟動由原來的-變成了空格

docker compose up -d

在這裡插入圖片描述

6. 重點提醒

我們啟動後,docker compose會自動創建一個網絡,就是以文件夾的名稱+_default命名!
我們在編寫sentinel的compose文件時,要使用這個默認的網絡,不然就不在一個網段,故障轉移無法切換!!

docker network ls

在這裡插入圖片描述

7. 查看主從狀態

進入主redis:

e77為容器id

docker exec -it e77 /bin/bash
redis-cli

在這裡插入圖片描述
查看狀態信息:

info

在這裡插入圖片描述

8. 測試主從

在這裡插入圖片描述
在這裡插入圖片描述

四、啟動三個哨兵

1. 切換到sentinel文件夾

cd ..
cd sentinel/

2. 創建sentinel.conf文件

我們去官網找一個最低配的文件:

redis官網

因為這是兩個實例,咱們只需要一個,所有隻需要前四行即可:

protected-mode no
sentinel monitor mymaster 192.168.84.143 6379 2
sentinel down-after-milliseconds mymaster 60000
sentinel failover-timeout mymaster 180000
sentinel parallel-syncs mymaster 1

第一行:Redis 監控一個名為mymaster的redis集群,我們可以隨意寫;後面就是ip,我們宿主機的ip即可,端口為主redis的端口;2為哨兵投票的票數,當主redis宕機,三個哨兵必須兩個哨兵都投票的redis才會變為主!!
第二行:Sentinel判斷實例進入主觀下線所需的時間,毫秒單位。
第三行:在指定的時間內未能完成failover故障轉移,則任務故障轉移失敗。
第四行:限制在一次故障轉移之後,每次向新的主節點同時發起複制操作節點個數,越大效率越慢。

在這裡插入圖片描述

創建sentinel1.conf文件,把上面四行粘貼進來!

vim sentinel1.conf

在這裡插入圖片描述

複製兩份,不需任何修改:

cp sentinel1.conf sentinel2.conf
cp sentinel1.conf sentinel3.conf

3. 編寫conpose文件

version: "4.2"
services:
  sentinel1:
    image: redis:7.0.4
    container_name: redis-sentinel-1
    ports:
      - 26379:26379
    command: redis-sentinel /usr/local/etc/redis/sentinel.conf
    volumes:
      - /mydata/redis-sentinel-test/sentinel/sentinel1.conf:/usr/local/etc/redis/sentinel.conf
  sentinel2:
    image: redis:7.0.4
    container_name: redis-sentinel-2
    ports:
    - 26380:26379
    command: redis-sentinel /usr/local/etc/redis/sentinel.conf
    volumes:
      - /mydata/redis-sentinel-test/sentinel/sentinel2.conf:/usr/local/etc/redis/sentinel.conf
  sentinel3:
    image: redis:7.0.4
    container_name: redis-sentinel-3
    ports:
      - 26381:26379
    command: redis-sentinel /usr/local/etc/redis/sentinel.conf
    volumes:
      - /mydata/redis-sentinel-test/sentinel/sentinel3.conf:/usr/local/etc/redis/sentinel.conf
networks:
  default:
      name: redis_default
      external: true

networks:是呼應上面說的sentinel要和redis在一個網絡里,這樣才可以完成故障轉移!

4. 查看文件樹

tree

如果沒有可以安裝一下:

yum -y install tree

在這裡插入圖片描述

5. 啟動哨兵

docker compose up -d

在這裡插入圖片描述

6. 查看哨兵信息

進入哨兵容器:

docker exec -it c8 /bin/bash

連接哨兵:

redis-cli -p 26379
info

在這裡插入圖片描述
一主二從三哨兵完成

在這裡插入圖片描述

7. 故障轉移測試

我們把master給停掉:

docker stop e77

8. 故障轉移日誌

docker compose logs -f

在這裡插入圖片描述

9. 查看哨兵狀態

在這裡插入圖片描述
此時主節點已自動切換為6381端口。

10. 重啟6379服務

docker restart e77

我們發現剛剛新加入的6379會以從節點加入到主節點中!!

在這裡插入圖片描述

五、整合SpringBoot

1. 導入依賴

小編的springboot版本為:2.3.7.RELEASE

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

2. yml配置

server:
  port: 8084
spring:
  redis:
    sentinel:
      # sentinel.conf里的集群名稱
      master: mymaster
      # 我們只需要連哨兵即可,哨兵內部會幫我們找到redis
      nodes:
        - 192.168.84.143:26379
        - 192.168.84.143:26380
        - 192.168.84.143:26381

3. json序列化配置

/**
 * @author wangzhenjun
 * @date 2022/8/18 16:37
 */
@Configuration
public class RedisConfig {

    @Bean
    @SuppressWarnings(value = { "unchecked", "rawtypes" })
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory)
    {
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(connectionFactory);
        Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer(Object.class);

        // 使用StringRedisSerializer來序列化和反序列化redis的key值
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(serializer);

        // Hash的key也採用StringRedisSerializer的序列化方式
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setHashValueSerializer(serializer);

        template.afterPropertiesSet();
        return template;
    }
}

4. 新建controller測試

/**
 * @author wangzhenjun
 * @date 2022/8/18 17:48
 */
@RestController
public class TestController {

    @Autowired
    private RedisTemplate redisTemplate;

    @GetMapping("/test")
    public void saveRedis(){
        redisTemplate.opsForValue().set("name","看到我就成功了");
    }

5. 項目結構

在這裡插入圖片描述

6. 測試

在這裡插入圖片描述

在這裡插入圖片描述

7. 查看redis是否有值

在這裡插入圖片描述

在這裡插入圖片描述

六、總結

小編經過一個星期的搭建終於完成了 ,最大的問題就是網絡問題,最後終於解決了!!看了很多視頻和教學,有的太模糊,小編特地花一天時間整體一個無坑版,希望能夠幫到後來人!!

看到這裡還不一鍵三連走起來!!謝謝大家了!!


有緣人才可以看得到的哦!!!

點擊訪問!小編自己的網站,裏面也是有很多好的文章哦!