简单明了搭建Redis哨兵模式

  • Redis镜像版本:docker.io/redis:6.2.5-alpine
  • docker版本:Docker version 1.13.1, build 7d71120/1.13.1
  • docker-compose版本:docker-compose version 1.24.1, build 4667896b
  • 环境:CentOS7.9:2009

单机模式(开启AOF)

docker run -d -p 6379:6379 -v ~/redisdata:/data redis:6.2.5 redis-server --appendonly yes

主从模式

建立文件目录如下

~/docker
└── redis-master-slave
    └── redis-master-slave.yml

redis-master-slave.yml配置如下

version: '3'
services:
  master:
    environment: 
      - TZ=Asia/Shanghai
    image: docker.io/redis:6.2.5-alpine
    container_name: redis-master
    restart: always
    command: redis-server --requirepass root --masterauth root
    ports:
      - 6379:6379

  slave1:
    environment: 
      - TZ=Asia/Shanghai
    image: docker.io/redis:6.2.5-alpine
    container_name: redis-slave-1
    restart: always
    command: redis-server --slaveof redis-master 6379 --requirepass root --masterauth root 
    ports:
      - 6380:6379

  slave2:
    environment: 
      - TZ=Asia/Shanghai
    image: docker.io/redis:6.2.5-alpine
    container_name: redis-slave-2
    restart: always
    command: redis-server --slaveof redis-master 6379 --requirepass root --masterauth root 
    ports:
      - 6381:6379

启动命令

docker-compose -f redis-master-slave.yml -p redis up -d

查看实例中的redis角色的命令

docker exec redis-master redis-cli -a root info replication

不用进到容器里看,直接在shell下执行即可, 其中redis-master为容器名, -a指定redis密码

哨兵模式

哨兵模式是基于主从的, 建立文件目录如下

~/docker
└── redis-sentinel
    ├── redis-master-slave.yml
    ├── redis-sentinel-sentinel.yml
    ├── s1
    │   └── sentinel.conf
    ├── s2
    │   └── sentinel.conf
    └── s3
        └── sentinel.conf

只需要准备三件事

1. redis-master-slave.yml

redis-master-slave.yml配置与主从模式一样,可直接拷贝

2. redis-sentinel-sentinel.yml

redis-sentinel-sentinel.yml配置如下

version: '3'
services:
  sentinel1:
    environment: 
      - TZ=Asia/Shanghai
    image: docker.io/redis:6.2.5-alpine
    container_name: redis-sentinel-1
    restart: always
    command: redis-sentinel /usr/local/etc/redis/conf/sentinel.conf
    ports:
      - 26379:26379
    volumes:
      - ./s1/:/usr/local/etc/redis/conf/
    
  sentinel2:
    environment: 
      - TZ=Asia/Shanghai
    image: docker.io/redis:6.2.5-alpine
    container_name: redis-sentinel-2
    restart: always
    command: redis-sentinel /usr/local/etc/redis/conf/sentinel.conf
    ports:
      - 26380:26379
    volumes:
      - ./s2/:/usr/local/etc/redis/conf/
    
  sentinel3:
    environment: 
      - TZ=Asia/Shanghai
    image: docker.io/redis:6.2.5-alpine
    container_name: redis-sentinel-3
    restart: always
    command: redis-sentinel /usr/local/etc/redis/conf/sentinel.conf
    ports:
      - 26381:26379
    volumes:
      - ./s3/:/usr/local/etc/redis/conf/

networks:
  default:
    external:
      name: redis_default
  • 注意networks配是主从模式的网络, 查看主从的任意一台实例可知网络, 查看命令
docker inspect redis-master |grep Networks -A 15

结果如下, 可知我的这台主服务器在网络redis_default上, ip为172.20.0.2

"Networks": {
                "redis_default": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": [
                        "master",
                        "f609a0389d8d"
                    ],
                    "NetworkID": "6b0ded54960c5d9244c6b8ad4070082e1529cf35ea51ba05b436e2c23aca8e72",
                    "EndpointID": "26553cf90ca66458069b2f89500e535aecc9211c6923e36b0c552bf07597e0b3",
                    "Gateway": "172.20.0.1",
                    "IPAddress": "172.20.0.2",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,

3. sentinel.conf

以下的是s1下的sentinel.conf

port 26379
dir "/tmp"
sentinel monitor mymaster 172.20.0.2 6379 2
sentinel auth-pass mymaster root
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
sentinel deny-scripts-reconfig yes

s2与s3下的配置文件的port分别改为26380, 26381, 其它一样

注意其中的172.20.0.2是master的docker网络的ip

启动命令

docker-compose -f redis-sentinel-sentinel.yml -p redis up -d

完成后查看容器运行情况

$ docker ps
CONTAINER ID        IMAGE                          COMMAND                  CREATED             STATUS              PORTS                                      NAMES
14307b04cf81        docker.io/redis:6.2.5-alpine   "docker-entrypoint..."   2 minutes ago       Up 2 minutes        6379/tcp, 0.0.0.0:26381->26379/tcp         redis-sentinel-3
c2230ea26e4c        docker.io/redis:6.2.5-alpine   "docker-entrypoint..."   2 minutes ago       Up 2 minutes        6379/tcp, 0.0.0.0:26380->26379/tcp         redis-sentinel-2
c64f3eb4c017        docker.io/redis:6.2.5-alpine   "docker-entrypoint..."   2 minutes ago       Up 2 minutes        6379/tcp, 0.0.0.0:26379->26379/tcp         redis-sentinel-1
7f603f09c7fe        docker.io/redis:6.2.5-alpine   "docker-entrypoint..."   46 minutes ago      Up 46 minutes       0.0.0.0:6381->6379/tcp                     redis-slave-2
c31c68676299        docker.io/redis:6.2.5-alpine   "docker-entrypoint..."   46 minutes ago      Up 46 minutes       0.0.0.0:6380->6379/tcp                     redis-slave-1
f609a0389d8d        docker.io/redis:6.2.5-alpine   "docker-entrypoint..."   46 minutes ago      Up 46 minutes       0.0.0.0:6379->6379/tcp                     redis-master

为方便试错, 将常用命令写成脚本

vim run

设想使用时方便程度如下

启动主从docker-compose: ./run up1
启动哨兵docker-compose: ./run up2
启动主从容器: ./run start1
启动哨兵容器: ./run start2
停止主从与哨兵所有容器: ./run stop
停止主从容器: ./run stop1
停止哨兵容器: ./run stop2
清除主从与哨兵所有容器: ./run clear
清除主从所有容器: ./run clear1
清除哨兵所有容器: ./run clear2

于是编写run文件内容如下(写完后用看需要使用chmod改可执行权限)

#!/bin/bash
if [ $# -gt 1 ]
then
  echo 'wrong arg numbers'
  exit
fi
op=$1
if test -z "$op"
then
  echo "null arg"
elif [ $op == 'stop' ]
then
  docker stop redis-master redis-slave-1 redis-slave-2 redis-sentinel-1 redis-sentinel-2 redis-sentinel-3
elif [ $op == 'stop1' ]
then
  docker stop redis-master redis-slave-1 redis-slave-2
elif [ $op == 'stop2' ]
then
  docker stop redis-sentinel-1 redis-sentinel-2 redis-sentinel-3
elif [ $op == 'clear' ]
then
  docker container rm redis-master redis-slave-1 redis-slave-2 redis-sentinel-1 redis-sentinel-2 redis-sentinel-3
elif [ $op == 'clear1' ]
then
  docker container rm redis-master redis-slave-1 redis-slave-2
elif [ $op == 'clear2' ]
then
  docker container rm redis-sentinel-1 redis-sentinel-2 redis-sentinel-3
elif [ $op == 'start1' ]
then
  docker start redis-master redis-slave-1 redis-slave-2
elif [ $op == 'start2' ]
then
  docker start redis-sentinel-1 redis-sentinel-2 redis-sentinel-3
elif [ $op == 'up1' ]
then
  docker-compose -f redis-master-slave.yml -p redis up -d
elif [ $op == 'up2' ]
then
  docker-compose -f redis-sentinel-sentinel.yml -p redis up -d
elif [ $op == 'info-master' ]
then
  docker exec redis-master redis-cli -a root info replication
elif [ $op == 'info-slave-1' ]
then
  docker exec redis-slave-1 redis-cli -a root info replication
elif [ $op == 'info-slave-2' ]
then
  docker exec redis-slave-2 redis-cli -a root info replication
elif [ $op == 'test' ]
then
  echo 'test pass'
else
  echo "arg invalid: $1"
fi

现在可以很方便地试错了~

搭建哨兵模式过程中的常见问题

  • 指定sentinel.conf配置文件映射到容器内时直接使用文件映射, 这么做有可能导致哨兵没有写入配置文件的权限, 表现为WARNING: Sentinel was not able to save the new configuration on disk!!!: Device or resource busy. 解决方案:使用文件夹映射
  • 看似搭建起来了, 可当stop掉master后哨兵却不会选举新的主节点, 可能是哨兵改写了sentinel.conf后使用了一样的myid. 解决方案: stop掉哨兵, 删掉myid那一行, 重新启动哨兵. myid会自动重新生成.
  • 从库没有权限打开临时文件, 表现为同步时大量出现 Opening the temp file needed for MASTER <-> REPLICA synchronization: Permission denied 的log记录. 解决方案: sudo -u root ./redis-server [配置文件] 方式启动
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335