За это время я узнаю о Redis и контейнерах, поэтому я хочу создать систему redis master-slave через докер, чтобы углубить свое понимание. Глядя на эту статью, вам может понадобиться определенная основа докеров и понимание механизма redis master-slave и sentinel.
В этом эксперименте были подготовлены три облачных хоста, система Debian и IP-адреса: 35.236.172.131, 35.201.200.251, 34.80.172.42.
Сначала установите докер на трех хостах соответственно, затем запустите контейнер Redis на каждом хосте, запустите службу redis-server, из которых 35.236.172.131 используется как мастер, две другие машины используются как подчиненные, и, наконец, запустите на три хоста соответственно Контейнер Redis, работающий с redis-sentinel. Почему это все еще контейнер Redis? Поскольку sentinel на самом деле является Redis-сервером, он выполняется только в режиме Sentinel и может обрабатывать только некоторые команды, требуемые Sentinel.
установить докер
Есть много способов установить докер, которые здесь не представлены. На этот раз мы используем скрипт для установки docker.Системный скрипт Debian устанавливается следующим образом.Для других систем, пожалуйста, обратитесь к методу установки на официальном сайте Docker:docs.docker.com/install/lin…. Однако следующая команда изменяет источник изображения на Alibaba Cloud на основе команды официального веб-сайта, поскольку внутренние изображения, как правило, работают быстрее.
Скрипт для установки докера
Выполните следующую команду на физическом хосте или облачном виртуальном хосте, чтобы завершить установку докера.Конечно, я нахожусь в системе Debian.Для других систем, пожалуйста, обратитесь к методу на официальном сайте.
$ curl -fsSL https://get.docker.com -o get-docker.sh
$ sudo sh get-docker.sh --mirror Aliyun
запустить докер СЕ
Docker работает в клиент-серверной модели, поэтому вам нужно сначала запустить сервер docker, а сервер работает в виде демона. docker CE — это версия docker для сообщества.
$ sudo systemctl enable docker
$ sudo systemctl start docker
Убедитесь, что докер успешно установлен
Следующая команда извлекает образ с именем hello-world из официального репозитория докеров и запускает контейнер через этот образ.
$ docker run hello-world
Если результат операции выглядит следующим образом, появляетсяHello from Docker!
, что указывает на то, что установка докера прошла успешно
$ docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
1b930d010525: Pull complete
Digest: sha256:6540fc08ee6e6b7b63468dc3317e3303aae178cb8a45ed3123180328bcc1d20f
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(amd64)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/
For more examples and ideas, visit:
https://docs.docker.com/get-started/
Запустите контейнер для сборки master-slave
После успешной установки докера вы можете приступить к развертыванию службы Redis. Сначала извлеките образ Redis из официального общедоступного хранилища докеров, затем измените файл конфигурации службы Redis и, наконец, запустите контейнер и запустите сервер Redis. Запустите сервер Redis на нескольких машинах и установите отношения ведущий-ведомый.
Ведущий-ведомый Redis является основой для реализации высокой доступности кластера Redis и Redis Sentinel.Структура master-slave Redis позволяет ведомому реплицировать данные на ведущем.Если сеть между ведомым и ведущим отключена , ведомое устройство автоматически переподключится к ведущему.
Получить образ Redis
Следующая команда загрузит последнюю официальную версию образа Redis.
$ docker pull redis
Посмотреть зеркало
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
redis latest bb0ab8a99fe6 7 days ago 95MB
hello-world latest fce289e99eb9 6 months ago 1.84kB
Получите и измените файл конфигурации Redis
Redis официально предоставляет пример файла конфигурации, который можно загрузить с помощью инструмента wget. Я использую пользователя root и загружаю его прямо в каталог /root.
$ wget http://download.redis.io/redis-stable/redis.conf
Открыв скачанный файл, вы увидите, что конфигураций много. Я только что создал сервис для тестирования, поэтому я изменил только необходимые элементы. Если он будет использоваться онлайн, все конфигурации должны быть изменены по мере необходимости.
Файлы конфигурации, используемые главной и подчиненной ролями сервера Redis, будут несколько отличаться, что будет объяснено ниже.
Для мастера файл конфигурации изменяет следующие элементы
# 注释这一行,表示Redis可以接受任意ip的连接
# bind 127.0.0.1
# 关闭保护模式
protected-mode no
# 让redis服务后台运行
daemonize yes
# 设定密码(可选,如果这里开启了密码要求,slave的配置里就要加这个密码. 只是练习配置,就不使用密码认证了)
# requirepass masterpassword
# 配置日志路径,为了便于排查问题,指定redis的日志文件目录
logfile "/var/log/redis/redis.log"
Для подчиненного устройства файл конфигурации изменяет следующие элементы:
# 注释这一行,表示Redis可以接受任意ip的连接
# bind 127.0.0.1
# 关闭保护模式
protected-mode no
# 让redis服务后台运行
daemonize yes
# 设定密码(可选,如果这里开启了密码要求,slave的配置里就要加这个密码)
requirepass masterpassword
# 设定主库的密码,用于认证,如果主库开启了requirepass选项这里就必须填相应的密码
masterauth <master-password>
# 设定master的IP和端口号,redis配置文件中的默认端口号是6379
# 低版本的redis这里会是slaveof,意思是一样的,因为slave是比较敏感的词汇,所以在redis后面的版本中不在使用slave的概念,取而代之的是replica
# 将35.236.172.131做为主,其余两台机器做从。ip和端口号按照机器和配置做相应修改。
replicaof 35.236.172.131 6379
# 配置日志路径,为了便于排查问题,指定redis的日志文件目录
logfile "/var/log/redis/redis.log"
запустить контейнер
Создайте файл конфигурации на хосте и подчиненном устройстве соответственно в соответствии с описанным выше методом и запустите контейнер после проверки правильности.
Мы указали псевдоним контейнера на каждой из трех машин какredis-1, redis-2, redis-3
, чтобы было легко различать и объяснять, докер проходит--name
параметр, чтобы указать псевдоним контейнера. redis-1 — это псевдоним контейнера на главном сервере, а redis-2 и redis-3 — псевдонимы на двух подчиненных устройствах.
Ниже приведен пример запуска контейнера redis-3, иллюстрирующий процесс запуска контейнера. Операции с контейнерами redis-1 и redis-2 на двух других машинах такие же, за исключением того, что файл конфигурации мастера отличается от файла конфигурации подчиненного. Но сначала запустите главный сервер, который является контейнером redis-1. Затем запустите Redis-2 и Redis-3.
# 首先以后台模式运行容器
$ docker run -it --name redis-3 -v /root/redis.conf:/usr/local/etc/redis/redis.conf -d -p 6379:6379 redis /bin/bash
# 容器成功启动后,会打印一个长串的容器ID
a3952342094dfd5a56838cb6becb5faa7a34f1dbafb7e8c506e9bd7bb1c2951b
# 通过ps命令查看容器的状态,可以看到redis-3已经启动
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a3952342094d redis "docker-entrypoint.s…" 8 minutes ago Up 8 minutes 0.0.0.0:6379->6379/tcp redis-3
Контейнер был запущен выше, а затем войдите в контейнер, чтобы запустить сервер Redis.
# 以交互模式进入容器redis-3
$ docker exec -it redis-3 bash
# 创建日志文件目录
$ mkdir /var/log/redis/
$ touch /var/log/redis/redis.log
# 启动redis服务器,如果没有任何输出,就说明成功了
$ redis-server /usr/local/etc/redis/redis.conf
# 在容器里启动一个redis客户端
$ redis-cli
# 执行info命令,查看服务器状态
127.0.0.1:6379> info
...
# 如果是主,这里的role的值会是master,如果是从,这里的role的值会是slave
role:slave
# 对于slave,还要查看master_link_status这个属性值。slave上这个属性值为up就说明主从复制是OK的,否者就有问题。如果从机状态不为up,首先排查主机的端口是否被限,然后查看redis日志排查原因
master_link_status:up
...
# 最后退出容器
$ exit
Проверка репликации master-slave
После успешного создания master-slave вы можете проверить, успешно ли прошла синхронизация master-slave, записав значение ключа на master, чтобы проверить, будет ли оно синхронизировано с slave.
# 以交互模式进入容器redis-1中
$ docker exec -it redis-1 bash
Запустите redis-cli, который записывает значение в test_key
$ redis-cli
127.0.0.1:6379> set test_key hello-world
OK
Войдите в контейнер на любой ведомой машине, а также запустите Redis-cli, чтобы запросить значение этого ключа. Если это значение можно запросить и оно совпадает со значением на хосте, синхронизация между ведущим и подчиненным выполнена успешно. После тестирования активная синхронизация прошла успешно.
127.0.0.1:6379> get test_key
"hello-world"
добавить часового
Структура master-slave успешно выстраивается, и доступность системы становится выше, но при отказе master необходимо вручную переключать slave на master. Эта работа по переключению не только тратит впустую человеческие ресурсы, но и оказывает большее влияние на тот факт, что Redis не может предоставлять внешние услуги в период переключения ведущий-ведомый. Поэтому была разработана дозорная система. Дозорный может автоматически переключаться после сбоя ведущего, выбирать одного из ведомых для обновления до ведущего и продолжать контролировать исходный ведущий. Когда первоначальный ведущий восстанавливается, он делает его ведомым для новый хозяин.
Sentinel сначала отслеживает ведущее устройство, получает информацию о ведомом устройстве, отправляя ему команду info, а затем также отслеживает ведомое устройство. Кроме того, Sentinel подпишется на канал __sentinel__:hello, как и мастер. Когда новый Sentinel присоединяется, он отправляет сообщение на этот канал. Это сообщение содержит IP-адрес и порт Sentinel. Sentinel получит это сообщение и знать, что новый часовой присоединился. Эти дозорные установят соединение с вновь добавленным и дозорным, и через это соединение нужно проголосовать за лидера. Эту связь можно описать следующей диаграммой
Получить и изменить файлы конфигурации Sentinel
Получите файл конфигурации Sentinel с помощью команды wget
wget http://download.redis.io/redis-stable/sentinel.conf
Измените следующие элементы в файле конфигурации
# 让sentinel服务后台运行
daemonize yes
# 修改日志文件的路径
logfile "/var/log/redis/sentinel.log"
# 修改监控的主redis服务器
# 最后一个2表示,两台机器判定主被动下线后,就进行failover(故障转移)
sentinel monitor mymaster 35.236.172.131 6379 2
запустить контейнер
Аналогично запуску контейнера Redis, запустите контейнер с псевдонимом Sentinel.
$ docker run -it --name sentinel -p 26379:26379 -v /root/sentinel.conf:/usr/local/etc/redis/sentinel.conf -d redis /bin/bash
бежать часовой
# 进入容器
$ docker exec -it sentinel bash
# 创建日志目录和文件
$ mkdir /var/log/redis
$ touch /var/log/redis/sentinel.log
# 启动哨兵
redis-sentinel /usr/local/etc/redis/sentinel.conf
# 查看日志,哨兵成功监听到一主和两从的机器
18:X 11 Jul 2019 13:25:55.416 # +monitor master mymaster 35.236.172.131 6379 quorum 2
18:X 11 Jul 2019 13:25:55.418 * +slave slave 35.201.200.251:6379 35.201.200.251 6379 @ mymaster 35.236.172.131 6379
18:X 11 Jul 2019 13:25:55.421 * +slave slave 34.80.172.42:6379 34.80.172.42 6379 @ mymaster 35.236.172.131 6379
Таким же образом запустите sentinel в контейнере на двух других машинах, используя один и тот же файл конфигурации.
Проверить отработку отказа (отказоустойчивость)
Чтобы проверить автоматическое переключение master-slave в рамках дозорного механизма, мы убили процесс redis на master.
После ожидания в течение нескольких секунд есть еще одна машина, обновленная с главной до главной.Во время эксперимента это была третья машина, то есть redis-3 был обновлен до главной.Используйте команду info для запроса, и вы можете видеть, что изменилась роль сервера redis-3 master. Автоматическое переключение ведущий-ведомый прошло успешно.
127.0.0.1:6379> info
...
# Replication
role:master
...
Затем перезапустите основной сервер, который был убит ранее, проверьте его командой info после запуска, и вы можете обнаружить, что он стал подчиненным сервером redis-3.
В следующем журнале описывается, что 35.236.172.131 запускается в качестве ведущего, выполняется выбор главного сигнального устройства для отработки отказа, выполняется отработка отказа и устанавливаются новые отношения ведущий-ведомый.
root@4355ca3260c5:/var/log/redis# cat sentinel.log
17:X 11 Jul 2019 13:25:55.395 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
17:X 11 Jul 2019 13:25:55.395 # Redis version=5.0.5, bits=64, commit=00000000, modified=0, pid=17, just started
17:X 11 Jul 2019 13:25:55.395 # Configuration loaded
18:X 11 Jul 2019 13:25:55.398 * Running mode=sentinel, port=26379.
18:X 11 Jul 2019 13:25:55.398 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
18:X 11 Jul 2019 13:25:55.416 # Sentinel ID is 7d9a7877d4cffb6fec5877f605b975e00e7953c1
18:X 11 Jul 2019 13:25:55.416 # +monitor master mymaster 35.236.172.131 6379 quorum 2
18:X 11 Jul 2019 13:25:55.418 * +slave slave 35.201.200.251:6379 35.201.200.251 6379 @ mymaster 35.236.172.131 6379
18:X 11 Jul 2019 13:25:55.421 * +slave slave 34.80.172.42:6379 34.80.172.42 6379 @ mymaster 35.236.172.131 6379
18:X 11 Jul 2019 13:26:25.460 # +sdown slave 35.201.200.251:6379 35.201.200.251 6379 @ mymaster 35.236.172.131 6379
18:X 11 Jul 2019 14:04:23.390 * +sentinel sentinel 09aa7d2098ad2dc52e6e07d7bc6670f00f5ff3e3 172.17.0.3 26379 @ mymaster 35.236.172.131 6379
18:X 11 Jul 2019 14:04:25.418 * +sentinel-invalid-addr sentinel 09aa7d2098ad2dc52e6e07d7bc6670f00f5ff3e3 172.17.0.3 26379 @ mymaster 35.236.172.131 6379
18:X 11 Jul 2019 14:04:25.418 * +sentinel sentinel 7d9a7877d4cffb6fec5877f605b975e00e7953c1 172.17.0.3 26379 @ mymaster 35.236.172.131 6379
18:X 11 Jul 2019 14:04:25.456 * +sentinel-address-switch master mymaster 35.236.172.131 6379 ip 172.17.0.3 port 26379 for 09aa7d2098ad2dc52e6e07d7bc6670f00f5ff3e3
18:X 11 Jul 2019 14:08:34.338 * +sentinel-invalid-addr sentinel 09aa7d2098ad2dc52e6e07d7bc6670f00f5ff3e3 172.17.0.3 26379 @ mymaster 35.236.172.131 6379
18:X 11 Jul 2019 14:08:34.338 * +sentinel sentinel 28d3c0e636fa29ac9fb5c3cc2be00432c1b0ead9 172.17.0.3 26379 @ mymaster 35.236.172.131 6379
18:X 11 Jul 2019 14:08:36.236 * +sentinel-address-switch master mymaster 35.236.172.131 6379 ip 172.17.0.3 port 26379 for 09aa7d2098ad2dc52e6e07d7bc6670f00f5ff3e3
18:X 11 Jul 2019 14:11:12.151 # +sdown master mymaster 35.236.172.131 6379
18:X 11 Jul 2019 14:11:12.214 # +odown master mymaster 35.236.172.131 6379 #quorum 4/2
18:X 11 Jul 2019 14:11:12.214 # +new-epoch 1
18:X 11 Jul 2019 14:11:12.214 # +try-failover master mymaster 35.236.172.131 6379
18:X 11 Jul 2019 14:11:12.235 # +vote-for-leader 7d9a7877d4cffb6fec5877f605b975e00e7953c1 1
18:X 11 Jul 2019 14:11:12.235 # 7d9a7877d4cffb6fec5877f605b975e00e7953c1 voted for 7d9a7877d4cffb6fec5877f605b975e00e7953c1 1
18:X 11 Jul 2019 14:11:12.235 # 28d3c0e636fa29ac9fb5c3cc2be00432c1b0ead9 voted for 7d9a7877d4cffb6fec5877f605b975e00e7953c1 1
18:X 11 Jul 2019 14:11:12.235 # 09aa7d2098ad2dc52e6e07d7bc6670f00f5ff3e3 voted for 7d9a7877d4cffb6fec5877f605b975e00e7953c1 1
18:X 11 Jul 2019 14:11:12.294 # +elected-leader master mymaster 35.236.172.131 6379
18:X 11 Jul 2019 14:11:12.294 # +failover-state-select-slave master mymaster 35.236.172.131 6379
18:X 11 Jul 2019 14:11:12.394 # -failover-abort-no-good-slave master mymaster 35.236.172.131 6379
18:X 11 Jul 2019 14:11:12.453 # Next failover delay: I will not start a failover before Thu Jul 11 14:17:12 2019
18:X 11 Jul 2019 14:11:13.050 # +config-update-from sentinel 28d3c0e636fa29ac9fb5c3cc2be00432c1b0ead9 172.17.0.3 26379 @ mymaster 35.236.172.131 6379
18:X 11 Jul 2019 14:11:13.050 # +switch-master mymaster 35.236.172.131 6379 34.80.172.42 6379
18:X 11 Jul 2019 14:11:13.050 * +slave slave 35.201.200.251:6379 35.201.200.251 6379 @ mymaster 34.80.172.42 6379
18:X 11 Jul 2019 14:11:13.050 * +slave slave 35.236.172.131:6379 35.236.172.131 6379 @ mymaster 34.80.172.42 6379
18:X 11 Jul 2019 14:11:43.077 # +sdown slave 35.236.172.131:6379 35.236.172.131 6379 @ mymaster 34.80.172.42 6379
18:X 11 Jul 2019 14:11:43.077 # +sdown slave 35.201.200.251:6379 35.201.200.251 6379 @ mymaster 34.80.172.42 6379
18:X 12 Jul 2019 01:54:05.142 # -sdown slave 35.236.172.131:6379 35.236.172.131 6379 @ mymaster 34.80.172.42 6379
18:X 12 Jul 2019 01:54:15.087 * +convert-to-slave slave 35.236.172.131:6379 35.236.172.131 6379 @ mymaster 34.80.172.42 6379
Суммировать
Redis обеспечивает высокую доступность за счет репликации master-slave, но в случае сбоя требуется ручное переключение master-slave, что неэффективно. Механизм Sentinel реализует автоматическое переключение главного и подчиненного компонентов Redis, повышает доступность кластера Redis и повышает эффективность аварийного переключения кластера Redis.