Docker создает кластерную среду Redis Cluster.

Docker
Docker создает кластерную среду Redis Cluster.

Используя Docker для сборки Redis Cluster, наиболее важной частью является проблема взаимодействия контейнеров, которую мы решили для вас в предыдущей статье "Подробное объяснение сетевого режима Docker и сетевого взаимодействия между контейнерами.", в этой статье в основном используется использование нескольких контейнеров для завершения построения кластерной среды Redis Cluster, и, кстати, она прокладывает путь к изучению Docker Compose. Как говорится, без сравнения нет вреда, только в сравнении можно ощутить преимущества Docker Compose 😄.

Для получения дополнительной информации о Redis Cluster, пожалуйста, прочитайтеСамый простой и понятный шаблон архитектуры Redis".

Согласно официальному сайту Redis:Redis.IO/topics/Closers…Напоминаем, что для того, чтобы Docker был совместим с Redis Cluster, вам необходимо использовать Docker'shostсетевой режим.

hostСетевой режим требует передачи параметров при создании контейнера--net hostили--network hostуточнить,hostсетевой режим позволяетКонтейнеры совместно используют сетевой стек хоста, контейнер не будет виртуализировать собственную сетевую карту, настраивать собственный IP и т. д., а будет использовать IP и порт хоста.

окрестности

Чтобы сделать окружающую среду более реалистичной, в этой статье используютсяМультимашинаокружающая обстановка:

  • 192.168.10.10
  • 192.168.10.11

Инфраструктурная среда, используемая каждой машиной, выглядит следующим образом:

  • CentOS 7.8.2003
  • Docker version 19.03.12

строить

Общие этапы строительства в основном делятся на следующие этапы:

  • Скачиваем образ Redis (на самом деле этот шаг можно опустить, т.к. при создании контейнера, если локального образа не существует, он будет подтянут удаленно);
  • Написать файлы конфигурации Redis;
  • Создайте контейнер Redis;
  • Создайте кластер Redis Cluster.

Напишите файл конфигурации Redis

Создавать каталоги и файлы

Соответственно192.168.10.10а также192.168.10.11Сделайте следующее на обеих машинах.

# 创建目录
mkdir -p /usr/local/docker-redis/redis-cluster
# 切换至指定目录
cd /usr/local/docker-redis/redis-cluster/
# 编写 redis-cluster.tmpl 文件
vi redis-cluster.tmpl

написать файл конфигурации

192.168.10.10машинаredis-cluster.tmplСодержимое файла следующее:

port ${PORT}
requirepass 1234
masterauth 1234
protected-mode no
daemonize no
appendonly yes
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 15000
cluster-announce-ip 192.168.10.10
cluster-announce-port ${PORT}
cluster-announce-bus-port 1${PORT}

192.168.10.11машинаredis-cluster.tmplСодержимое файла следующее:

port ${PORT}
requirepass 1234
masterauth 1234
protected-mode no
daemonize no
appendonly yes
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 15000
cluster-announce-ip 192.168.10.11
cluster-announce-port ${PORT}
cluster-announce-bus-port 1${PORT}
  • port: порт узла;
  • requirepass: добавить аутентификацию доступа;
  • masterauth: если на главном узле включена аутентификация доступа, подчиненному узлу требуется аутентификация для доступа к главному узлу;
  • protected-mode: Защищенный режим, значение по умолчанию да, то есть он включен. После включения защищенного режима необходимо настроитьbind ipИли установите пароль доступа, отключите защищенный режим, и внешняя сеть может получить доступ напрямую;
  • daemonize: следует ли запускать поток демона (запускать в фоновом режиме), по умолчанию — нет;
  • appendonly: следует ли включить режим сохранения AOF, по умолчанию — нет;
  • cluster-enabled: включать ли режим кластера, по умолчанию нет;
  • cluster-config-file: файл информации об узле кластера;
  • cluster-node-timeout: время ожидания соединения с узлом кластера;
  • cluster-announce-ip: IP-адрес узла кластера, введите IP-адрес хоста;
  • cluster-announce-port: порт сопоставления узлов кластера;
  • cluster-announce-bus-port: порт шины узла кластера.

Каждый узел кластера Redis должен быть включенДва TCP-соединения. Обычный TCP-порт Redis для обслуживания клиентов, например 6379. Существует также порт на основе порта 6379 плюс 10000, например 16379.

Второй порт предназначен для кластерной шины, которая представляет собой канал связи между узлами с использованием двоичного протокола. Узлы используют шину кластера для обнаружения сбоев, обновления конфигурации, авторизации аварийного переключения и т. д. Клиенты никогда не должны пытаться взаимодействовать с портом шины кластера, только с обычным командным портом Redis, но убедитесь, что оба порта в брандмауэре открыты, иначе узлы кластера Redis не смогут взаимодействовать.

существует192.168.10.10машинаredis-clusterВыполните следующие команды в каталоге:

for port in `seq 6371 6373`; do \
  mkdir -p ${port}/conf \
  && PORT=${port} envsubst < redis-cluster.tmpl > ${port}/conf/redis.conf \
  && mkdir -p ${port}/data;\
done

существует192.168.10.11машинаredis-clusterВыполните следующие команды в каталоге:

for port in `seq 6374 6376`; do \
  mkdir -p ${port}/conf \
  && PORT=${port} envsubst < redis-cluster.tmpl > ${port}/conf/redis.conf \
  && mkdir -p ${port}/data;\
done

Приведенные выше два оператора оболочки for означают, что каталоги и файлы, относящиеся к 6371 ~ 6376, создаются в цикле.

существует192.168.10.10Результат выполнения команды представления машины следующий, если неtreeкоманда для установки в первую очередьyum install -y tree.

существует192.168.10.11Результат выполнения команды представления машины следующий.

Ниже приведены сведения о файле конфигурации каждого узла.

============================== 192.168.10.10 ==============================
[root@localhost redis-cluster]# cat /usr/local/docker-redis/redis-cluster/637{1..3}/conf/redis.conf
port 6371
requirepass 1234
masterauth 1234
protected-mode no
daemonize no
appendonly yes
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 15000
cluster-announce-ip 192.168.10.10
cluster-announce-port 6371
cluster-announce-bus-port 16371

port 6372
requirepass 1234
masterauth 1234
protected-mode no
daemonize no
appendonly yes
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 15000
cluster-announce-ip 192.168.10.10
cluster-announce-port 6372
cluster-announce-bus-port 16372

port 6373
requirepass 1234
masterauth 1234
protected-mode no
daemonize no
appendonly yes
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 15000
cluster-announce-ip 192.168.10.10
cluster-announce-port 6373
cluster-announce-bus-port 16373
============================== 192.168.10.10 ==============================

============================== 192.168.10.11 ==============================
[root@localhost redis-cluster]# cat /usr/local/docker-redis/redis-cluster/637{4..6}/conf/redis.conf
port 6374
requirepass 1234
masterauth 1234
protected-mode no
daemonize no
appendonly yes
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 15000
cluster-announce-ip 192.168.10.11
cluster-announce-port 6374
cluster-announce-bus-port 16374

port 6375
requirepass 1234
masterauth 1234
protected-mode no
daemonize no
appendonly yes
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 15000
cluster-announce-ip 192.168.10.11
cluster-announce-port 6375
cluster-announce-bus-port 16375

port 6376
requirepass 1234
masterauth 1234
protected-mode no
daemonize no
appendonly yes
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 15000
cluster-announce-ip 192.168.10.11
cluster-announce-port 6376
cluster-announce-bus-port 16376
============================== 192.168.10.11 ==============================

Создайте контейнер Redis

Создать контейнер

поставить хозяина6371 ~ 6376Порты между ними сопоставляются с 6 контейнерами Redis, а каталог хоста сопоставляется с каталогом в контейнере (подключение каталога). Не забудьте указать режим сети, используйтеhostсетевой режим.

существует192.168.10.10Машина выполняет следующие команды:

for port in $(seq 6371 6373); do \
  docker run -di --restart always --name redis-${port} --net host \
  -v /usr/local/docker-redis/redis-cluster/${port}/conf/redis.conf:/usr/local/etc/redis/redis.conf \
  -v /usr/local/docker-redis/redis-cluster/${port}/data:/data \
  redis redis-server /usr/local/etc/redis/redis.conf; \
done

существует192.168.10.11Машина выполняет следующие команды:

for port in $(seq 6374 6376); do \
  docker run -di --restart always --name redis-${port} --net host \
  -v /usr/local/docker-redis/redis-cluster/${port}/conf/redis.conf:/usr/local/etc/redis/redis.conf \
  -v /usr/local/docker-redis/redis-cluster/${port}/data:/data \
  redis redis-server /usr/local/etc/redis/redis.conf; \
done

существует192.168.10.10машинное исполнениеdocker ps -n 3Проверьте, успешно ли создан контейнер.

существует192.168.10.11машинное исполнениеdocker ps -n 3Проверьте, успешно ли создан контейнер.

Создайте кластер Redis Cluster

Введите любой узел контейнера по желанию и введите/usr/local/bin/содержание:

# 进入容器
docker exec -it redis-6371 bash
# 切换至指定目录
cd /usr/local/bin/

Затем мы можем создать кластер Redis Cluster с помощью следующих команд.

redis-cli -a 1234 --cluster create 192.168.10.10:6371 192.168.10.10:6372 192.168.10.10:6373 192.168.10.11:6374 192.168.10.11:6375 192.168.10.11:6376 --cluster-replicas 1

Появится запрос выбора, введитеyes, результат выглядит так:

Кластер успешно создан следующим образом:

Ниже приведены сведения, возвращаемые при создании кластера, то есть все, что показано на двух предыдущих рисунках.

root@localhost:/usr/local/bin# redis-cli -a 1234 --cluster create 192.168.10.10:6371 192.168.10.10:6372 192.168.10.10:6373 192.168.10.11:6374 192.168.10.11:6375 192.168.10.11:6376 --cluster-replicas 1
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 192.168.10.11:6376 to 192.168.10.10:6371
Adding replica 192.168.10.10:6373 to 192.168.10.11:6374
Adding replica 192.168.10.11:6375 to 192.168.10.10:6372
M: 299cf79ddafc83dced27f628f1f82dac483fbc4e 192.168.10.10:6371
   slots:[0-5460] (5461 slots) master
M: ac805b90b6e20e26dc4268454bb2855beea6cc19 192.168.10.10:6372
   slots:[10923-16383] (5461 slots) master
S: db35494fcc5db0c88d27da7885c817e6cdcc9373 192.168.10.10:6373
   replicates 7013270480d37eeab79b9cd0272e934d4548136a
M: 7013270480d37eeab79b9cd0272e934d4548136a 192.168.10.11:6374
   slots:[5461-10922] (5462 slots) master
S: 8435e1b0d51f2690c5f94f9a5682a4ac34e94326 192.168.10.11:6375
   replicates ac805b90b6e20e26dc4268454bb2855beea6cc19
S: 7b13c16fa6fe8e13cdc0b4846b87edffed55c62e 192.168.10.11:6376
   replicates 299cf79ddafc83dced27f628f1f82dac483fbc4e
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join
.
>>> Performing Cluster Check (using node 192.168.10.10:6371)
M: 299cf79ddafc83dced27f628f1f82dac483fbc4e 192.168.10.10:6371
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
S: 8435e1b0d51f2690c5f94f9a5682a4ac34e94326 192.168.10.11:6375
   slots: (0 slots) slave
   replicates ac805b90b6e20e26dc4268454bb2855beea6cc19
S: db35494fcc5db0c88d27da7885c817e6cdcc9373 192.168.10.10:6373
   slots: (0 slots) slave
   replicates 7013270480d37eeab79b9cd0272e934d4548136a
S: 7b13c16fa6fe8e13cdc0b4846b87edffed55c62e 192.168.10.11:6376
   slots: (0 slots) slave
   replicates 299cf79ddafc83dced27f628f1f82dac483fbc4e
M: 7013270480d37eeab79b9cd0272e934d4548136a 192.168.10.11:6374
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
M: ac805b90b6e20e26dc4268454bb2855beea6cc19 192.168.10.10:6372
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

На данный момент построен высокодоступный кластер Redis Cluster, как показано на рисунке ниже, Кластер содержит 6 узлов Redis, 3 ведущих и 3 подчиненных. Три главных узла будут выделять слоты для обработки командных запросов клиентов, в то время как подчиненные узлы могут заменить главный узел после отказа главного узла.

Просмотр состояния кластера

Мы сначала входим в контейнер, а затем проверяем состояние кластера через некоторые общие команды кластера.

# 进入容器
docker exec -it redis-6371 bash
# 切换至指定目录
cd /usr/local/bin/

Проверить состояние кластера

redis-cli -a 1234 --cluster check 192.168.10.11:6375

Просмотр информации о кластере и информации об узле

# 连接至集群某个节点
redis-cli -c -a 1234 -h 192.168.10.11 -p 6376
# 查看集群信息
cluster info
# 查看集群结点信息
cluster nodes

SET/GET

Для выполнения записи и чтения в узле 6371 команды следующие:

# 进入容器并连接至集群某个节点
docker exec -it redis-6371 /usr/local/bin/redis-cli -c -a 1234 -h 192.168.10.10 -p 6371
# 写入数据
set name mrhelloworld
set aaa 111
set bbb 222
# 读取数据
get name
get aaa
get bbb

Не волнуйтесь, позвольте мне объяснить процесс работы на картинке выше:

  • Сначала войдите в контейнер и подключитесь к узлу в кластере;
  • затем выполнитьПервыйустановить командуset name mrhelloworld,nameЗначение ключа, полученное после работы хеш-функции, равно[5798]. Распределение слотов в текущей среде кластера:[0-5460] 6371节点,[5461-10922] 6374节点,[10923-16383] 6372节点, поэтому хранилище для ключа выделяется6374на узле;
  • увидеть сновавторойустановить командуset aaa, здесь у вас могут возникнуть вопросы, почему вы не видитеaaaЗначение, полученное после вычисления ключа по хеш-функции? потому что он был просто перенаправлен на6374Узел вставил данные.Если в это время все еще вставлены данные, значение, полученное после вычисления ключа в соответствии с хеш-функцией, все еще находится в пределах диапазона узла, тогда данные могут быть вставлены напрямую;
  • с последующимТретийустановить командуset bbb,bbbЗначение ключа, полученное после работы хеш-функции, равно[5287], поэтому хранилище для ключа выделяется6371на узле;
  • Затем операция чтения,четвертыйЗаказget name,nameЗначение ключа, полученное после работы хеш-функции, равно[5798], перенаправлено на6374чтение узла;
  • пятыйЗаказget aaa,aaaЗначение, полученное после вычисления ключа по хеш-функции, также6374узел, читать напрямую;
  • шестойЗаказget bbb,bbbЗначение ключа, полученное после работы хеш-функции, равно[5287], перенаправлено на6371Узел читает.

Благодаря вышеперечисленным операциям мы знаем, чтоnameХранилище для ключа выделено на узле 6374, что, если я напрямую подключусь к узлу 6374 и получу значение? Правильно, нет необходимости перенаправлять узел, потому что данные есть, поэтому читайте и возвращайтесь напрямую.

Подключение клиента

Наконец, волна операций подключения клиента, любой узел, посмотрите, можно ли получить доступ к кластеру Redis Cluster извне.

До сих пор использование многомашинной среды и нескольких контейнеров для построения кластерной среды Redis Cluster здесь, На самом деле, общий процесс построения не представляет особых проблем, потому что:

  • Ruby требуется для создания кластера Redis, в противном случае вам придется связывать узлы для построения кластера и самостоятельно выделять слоты;
  • Если вы используете Ruby для создания кластера Redis, вам необходимо установить среду Ruby;
  • И Redis можно использовать прямо с версии 5redis-cliкоманда для создания кластера, избавляет от многих проблем;
  • Мы также использовали циклы оболочки для упрощения процесса сборки, иначе было бы неудобно выполнять их один за другим.

В заключение, есть ли более простой способ? Конечно есть, иначе я не имею к вам тут никакого отношения.

Docker Compose может решить эту проблему. Позже давайте узнаем, что такое Docker Compose, а затем воспользуемся Docker Compose для повторного создания кластерной среды Redis Cluster и почувствуем разницу до и после.

Этот документ принимает知识共享「署名-非商业性使用-禁止演绎 4.0 国际」许可协议.

Каждый может пройти分类увидеть больше оDockerстатья.

🤗 твой点赞а также转发моя самая большая поддержка.

📢 Отсканируйте код, чтобы следовать哈喽沃德先生Каждая статья «Документ+Видео» снабжена специальным видео-пояснением, облегчающим обучение~