一个简单的小开发
首页
分类
标签
归档
关于

YDS

30岁大龄程java程序员,心不老,神不灭
首页
分类
标签
归档
关于
  • NoSql概念
  • Docker环境下安装redis哨兵模式
    • 环境
    • 目录结构
    • 配置文件
    • 启动redis
    • 查看集群信息
    • 触发选举
    • 选举后的服务状态
    • 网络恢复
    • 过程中可能遇到的问题
  • 使用docker-compose安装mysql
  • DB
yds
2022-03-11
目录

Docker环境下安装redis哨兵模式

# 环境

docker
docker-compse

# 目录结构

.
├── docker-compose.yaml
├── redis01
│   └── conf
│       └── redis.conf
├── redis02
│   └── conf
│       └── redis.conf
├── redis03
│   └── conf
│       └── redis.conf
├── sentinel01
│   └── conf
│       └── redis.conf
├── sentinel02
│   └── conf
│       └── redis.conf
└── sentinel03
    └── conf
        └── redis.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 配置文件

docker-compose.yaml
version: '3'
services:
  redis01:
    image: redis
    container_name: redis01
    restart: always
    ports:
      - 6379:6379
    volumes:
    - ./redis01/data:/data
    - ./redis01/conf/:/usr/local/etc/redis/conf/
    command: ["redis-server","/usr/local/etc/redis/conf/redis.conf"]
    networks:
      redis-cluster-net:
        ipv4_address: 172.18.0.21
          
  redis02:
    image: redis
    container_name: redis02
    restart: always
    ports:
      - 6380:6379
    volumes:
    - ./redis02/data:/data
    - ./redis02/conf/:/usr/local/etc/redis/conf/
    command: ["redis-server","/usr/local/etc/redis/conf/redis.conf"]
    networks:
      redis-cluster-net:
        ipv4_address: 172.18.0.22
    depends_on:
      - 'redis01'

  redis03:
    image: redis
    container_name: redis03
    restart: always
    ports:
      - 6381:6379
    volumes:
    - ./redis03/data:/data
    - ./redis03/conf/:/usr/local/etc/redis/conf/
    command: ["redis-server","/usr/local/etc/redis/conf/redis.conf"]
    networks:
      redis-cluster-net:
        ipv4_address: 172.18.0.23
    depends_on:
      - 'redis01'

  redis-sentinel-01:
    image: redis
    container_name: redis-sentinel-01
    volumes:
    - ./sentinel01/data:/data
    - ./sentinel01/conf/:/etc/redis/conf/
    command: redis-sentinel /etc/redis/conf/redis.conf
    restart: always
    depends_on:
      - 'redis01'
      - 'redis02'
      - 'redis03'
    networks:
      redis-cluster-net:
        ipv4_address: 172.18.0.24

  redis-sentinel-02:
    image: redis
    container_name: redis-sentinel-02
    volumes:
    - ./sentinel02/data:/data
    - ./sentinel02/conf/:/etc/redis/conf/
    command: redis-sentinel /etc/redis/conf/redis.conf
    restart: always
    depends_on:
      - 'redis01'
      - 'redis02'
      - 'redis03'
    networks:
      redis-cluster-net:
        ipv4_address: 172.18.0.25

  redis-sentinel-03:
    image: redis
    container_name: redis-sentinel-03
    volumes:
    - ./sentinel03/data:/data
    - ./sentinel03/conf/:/etc/redis/conf/
    command: redis-sentinel /etc/redis/conf/redis.conf
    restart: always
    depends_on:
      - 'redis01'
      - 'redis02'
      - 'redis03'
    networks:
      redis-cluster-net:
        ipv4_address: 172.18.0.26

networks:
  redis-cluster-net: 
    driver: bridge
    ipam:
      config:
      - subnet: 172.18.0.0/16
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
redis01的配置文件conf/redis.conf
port 6379
bind 0.0.0.0
save 900 1
save 300 10
save 60 10000
dbfilename dump.rdb
dir /data
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
auto-aof-rewrite-min-size 10M
auto-aof-rewrite-percentage 100

# 使用docker的方式时不设置这个不能同步数据
repl-diskless-load on-empty-db

logfile "redis.log"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
redis02、redis03的配置文件conf/redis.conf
port 6379
bind 0.0.0.0
save ""
dbfilename "dump.rdb"
dir "/data"
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
auto-aof-rewrite-min-size 10000000
auto-aof-rewrite-percentage 100

# 使用docker的方式时不设置这个不能同步数据
repl-diskless-load on-empty-db

replica-read-only yes
replicaof redis01 6379

logfile "redis.log"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
sentinel01的配置文件conf/redis.conf
port 6379
bind 0.0.0.0
logfile "sentinel.log"
sentinel monitor mymaster 172.18.0.21 6379 2
sentinel down-after-milliseconds mymaster 10000

sentinel resolve-hostnames yes
sentinel announce-ip "redis-sentinel-01"
sentinel announce-port 6379

sentinel deny-scripts-reconfig yes
1
2
3
4
5
6
7
8
9
10
11
sentinel02的配置文件conf/redis.conf
port 6379
bind 0.0.0.0
logfile "sentinel.log"
sentinel monitor mymaster 172.18.0.21 6379 2
sentinel down-after-milliseconds mymaster 10000

sentinel resolve-hostnames yes
sentinel announce-ip "redis-sentinel-02"
sentinel announce-port 6379

sentinel deny-scripts-reconfig yes
1
2
3
4
5
6
7
8
9
10
11
sentinel03的配置文件conf/redis.conf
port 6379
bind 0.0.0.0
logfile "sentinel.log"
sentinel monitor mymaster 172.18.0.21 6379 2
sentinel down-after-milliseconds mymaster 10000

sentinel resolve-hostnames yes
sentinel announce-ip "redis-sentinel-03"
sentinel announce-port 6379

sentinel deny-scripts-reconfig yes
1
2
3
4
5
6
7
8
9
10
11

# 启动redis

~/docker/redis$ docker-compose up -d

Creating network "redis_redis-cluster-net" with driver "bridge"
Creating redis01 ... done
Creating redis02 ... done
Creating redis03 ... done
Creating redis-sentinel-02 ... done
Creating redis-sentinel-03 ... done
Creating redis-sentinel-01 ... done
1
2
3
4
5
6
7
8
9
~/docker/redis$ docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS                                       NAMES
e4024697bd4f   redis     "docker-entrypoint.s…"   4 seconds ago   Up 3 seconds   6379/tcp                                    redis-sentinel-01
c8640976e687   redis     "docker-entrypoint.s…"   4 seconds ago   Up 3 seconds   6379/tcp                                    redis-sentinel-03
aaa145ee38af   redis     "docker-entrypoint.s…"   4 seconds ago   Up 3 seconds   6379/tcp                                    redis-sentinel-02
7cd618c968a8   redis     "docker-entrypoint.s…"   4 seconds ago   Up 4 seconds   0.0.0.0:6381->6379/tcp, :::6381->6379/tcp   redis03
f97cb04149d0   redis     "docker-entrypoint.s…"   4 seconds ago   Up 4 seconds   0.0.0.0:6380->6379/tcp, :::6380->6379/tcp   redis02
782250c395ce   redis     "docker-entrypoint.s…"   5 seconds ago   Up 4 seconds   0.0.0.0:6379->6379/tcp, :::6379->6379/tcp   redis01
1
2
3
4
5
6
7
8

# 查看集群信息

~/docker/redis$ docker exec -it 782250c395ce bash
root@782250c395ce:/data# redis-cli
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=172.18.0.23,port=6379,state=online,offset=59780,lag=0
slave1:ip=172.18.0.22,port=6379,state=online,offset=59638,lag=1
master_failover_state:no-failover
master_replid:d295101efb7dc5bac96f98e8d0b40cc209271f29
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:59780
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:59780
127.0.0.1:6379> set foo bar
OK
127.0.0.1:6379> get foo
"bar"
127.0.0.1:6379>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

以上在master节点上的操作证明redis的主从服务已经可用。

~/docker/redis$ docker exec -it f97cb04149d0 bash
root@f97cb04149d0:/data# redis-cli
127.0.0.1:6379> get foo
"bar"
127.0.0.1:6379> 
1
2
3
4
5

redis02,从库的服务也可以正确获取数据。

# 触发选举

我们模拟master宕机

~/docker/redis$ docker stop 2cd84318537b
2cd84318537b
yds@yds:~/docker/redis$ sudo tail -f sentinel01/data/sentinel.log 
1:X 11 Mar 2024 10:15:52.794 # +try-failover master mymaster 172.18.0.21 6379
1:X 11 Mar 2024 10:15:52.825 * Sentinel new configuration saved on disk
1:X 11 Mar 2024 10:15:52.825 # +vote-for-leader 4ad9233dcaafe88d16dd011eb2cd2a55dea48f5d 1
1:X 11 Mar 2024 10:15:52.831 * 9caa482bc52fdb5d8253fab554c1195d22413e35 voted for 9caa482bc52fdb5d8253fab554c1195d22413e35 1
1:X 11 Mar 2024 10:15:52.841 * 89e3f7246033a1a4cb7c9415ec2af98d8e15cf2d voted for 9caa482bc52fdb5d8253fab554c1195d22413e35 1
1:X 11 Mar 2024 10:15:53.744 # +config-update-from sentinel 9caa482bc52fdb5d8253fab554c1195d22413e35 172.18.0.25 6379 @ mymaster 172.18.0.21 6379
1:X 11 Mar 2024 10:15:53.744 # +switch-master mymaster 172.18.0.21 6379 172.18.0.23 6379
1:X 11 Mar 2024 10:15:53.744 * +slave slave 172.18.0.22:6379 172.18.0.22 6379 @ mymaster 172.18.0.23 6379
1:X 11 Mar 2024 10:15:53.744 * +slave slave 172.18.0.21:6379 172.18.0.21 6379 @ mymaster 172.18.0.23 6379
1:X 11 Mar 2024 10:15:53.754 * Sentinel new configuration saved on disk
1:X 11 Mar 2024 10:16:03.775 # +sdown slave 172.18.0.21:6379 172.18.0.21 6379 @ mymaster 172.18.0.23 6379
1
2
3
4
5
6
7
8
9
10
11
12
13
14

可以看到日志中已经重新选举出了master节点

# 选举后的服务状态

sentinel的配置文件

~/docker/redis$ sudo cat sentinel01/conf/redis.conf 
port 6379
bind 0.0.0.0
logfile "sentinel.log"
sentinel monitor mymaster 172.18.0.23 6379 2
sentinel down-after-milliseconds mymaster 10000

sentinel resolve-hostnames yes
sentinel announce-ip "redis-sentinel-01"
sentinel announce-port 6379

sentinel deny-scripts-reconfig yes

# Generated by CONFIG REWRITE
dir "/data"
latency-tracking-info-percentiles 50 99 99.9
user default on nopass sanitize-payload ~* &* +@all
sentinel myid 4ad9233dcaafe88d16dd011eb2cd2a55dea48f5d
sentinel config-epoch mymaster 1
sentinel leader-epoch mymaster 1
sentinel current-epoch 1

sentinel known-sentinel mymaster 172.18.0.25 6379 9caa482bc52fdb5d8253fab554c1195d22413e35

sentinel known-sentinel mymaster 172.18.0.26 6379 89e3f7246033a1a4cb7c9415ec2af98d8e15cf2d

sentinel known-replica mymaster 172.18.0.22 6379

sentinel known-replica mymaster 172.18.0.21 6379
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

可以看到sentinel的配置文件自动被修改了。

~/docker/redis$ docker exec -it c20b1fd56403 bash
root@c20b1fd56403:/data# redis-cli
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=172.18.0.22,port=6379,state=online,offset=68805,lag=1
master_failover_state:no-failover
master_replid:4cbae7f9ac3fd43866f51443946889d385000768
master_replid2:1c32eda737790ea747eeb517b274478b53a0696e
master_repl_offset:68947
second_repl_offset:6905
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:876
repl_backlog_histlen:68072
127.0.0.1:6379> get foo
"bar"
127.0.0.1:6379> 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

redis03已经被选举成了master,数据也没有问题。

# 网络恢复

~/docker/redis$ docker start 2cd84318537b
2cd84318537b
yds@yds:~/docker/redis$ docker exec -it c20b1fd56403 bash
root@c20b1fd56403:/data# redis-cli
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=172.18.0.22,port=6379,state=online,offset=114278,lag=0
slave1:ip=172.18.0.21,port=6379,state=online,offset=114278,lag=0
master_failover_state:no-failover
master_replid:4cbae7f9ac3fd43866f51443946889d385000768
master_replid2:1c32eda737790ea747eeb517b274478b53a0696e
master_repl_offset:114278
second_repl_offset:6905
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:876
repl_backlog_histlen:113403
127.0.0.1:6379> 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

可以看到原来宕机的redis01恢复过来以后,是以slave的身份加入了集群。

# 过程中可能遇到的问题

could not rename tmp config file (device or resource busy)
1

这个问题是因为配置文件挂载的时候,可能在docker-compose.yaml是文件和文件之间的直接映射,修改成文件夹和文件夹的映射就好了。
❌./sentinel03/conf/redis.conf:/etc/redis/conf/redis.conf
✅./sentinel03/conf/:/etc/redis/conf/

关于docker内部容器之间的网络访问

docker容器在同一个网络下是可以通过服务名来访问的,
如从机的配置“replicaof redis01 6379”,这里的“redis01”就是master节点的服务名。

但是在文章中可以看到在docker-compose中使用了静态ip的方式,这是因为在配置sentinel时,
“sentinel monitor mymaster 172.18.0.21 6379 2”该项配置中的master主机ip“172.18.0.21”
我尝试过使用“redis01”来代替,如果发生了选举的行为,日志中会显示不能解析到它,
尽管我设置了“sentinel resolve-hostnames yes”,
但是“sentinel announce-ip "redis-sentinel-01"”该项配置倒是没有出现问题。
1
2
3
4
5
6
7
8
#REDIS#SENTINEL
上次更新: 2024/09/30, 01:34:11
NoSql概念
使用docker-compose安装mysql

← NoSql概念 使用docker-compose安装mysql→

最近更新
01
使用docker-compose安装mysql
09-30
02
鸿蒙app开发中的数据驱动ui渲染问题
08-01
03
LINUX连接openvpn
07-02
更多文章>
Theme by Vdoing | Copyright © 2020-2024 YDS
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式