Кластер Redis часто используется в качестве инструмента для хранения данных их кэширования, брокера сообщений и других задач. Он стал популярным инструментом благодаря возможности масштабирования и высокой скорости работы. В этой статье представлены инструкции по созданию кластера на трех серверах для организации разделения данных (sharding) и высокой доступности за счет репликации. В данной конфигурации в случае отказа узла master, slave-сервер автоматически заменяет его.
Данная статья является переводом и адаптацией англоязычной статьи.
Redis как хранилище, размещаемое в памяти, обеспечивает высокоскоростную обработку таких операций, как подсчет, кэширование, организация очередей и др. Установка кластера значительно увеличивает надежность Redis за счет устранения единой точки отказа.
Установка Redis на каждый сервер
В зависимости от используемой версии Linux, может быть доступна установка Redis через менеджер пакетов. В данном руководстве мы рассмотрим установку текущей стабильной версии из исходного кода.
Сначала установите зависимости необходимые для сборки зависимости:
sudo apt-get update && sudo apt-get upgrade sudo apt install make gcc libc6-dev tcl
Скачайте текущую стабильную ветку и извлеките исходный код из архива:
wget http://download.redis.io/redis-stable.tar.gz tar xvzf redis-stable.tar.gz cd redis-stable sudo make install
Убедитесь, что тесты сборки проходят успешно:
make test
При успешном завершении, в консоли будет ответ:
\o/ All tests passed without errors!
Необходимо повторить установку для каждого сервера, который будет входить в кластер.
Настройка узлов Master и Slave
В данной инструкции каждый master будет подключен к одному slave.
Для более удобной работы с несколькими терминалами рекомендуем использовать tmux.
Официальная документация рекомендует использовать 6 узлов — по одному экземпляру Redis на узле, что позволяет обеспечить большую надежность, но возможно использовать три узла со следующей топологией соединений:
В установке используется три сервера, на каждом из которых запущено по два экземпляра Redis. Убедитесь, что каждый хост независим от других и не выйдет из строя совместно с другим. Далее выполните следующие шаги:
Подключитесь по SSH к серверу 1. Перейдите в redis-stable/
и скопируйте redis.conf
. В нашей инструкции имена файлов конфигураций соответствуют именам на изображении выше.
cp redis.conf c_slave.conf mv redis.conf a_master.conf
В a_master.conf
, определите директиву bind
и активируйте режим кластера. Порты в данном случае будут варьироваться в диапазоне от 6379 до 6381.
# bind 127.0.0.1 protected-mode no port 6379 pidfile /var/run/redis_6379.pid cluster-enabled yes cluster-config-file nodes-6379.conf cluster-node-timeout 15000
Для каждого узла в проектируемом кластере Redis требуется доступность не только определенного порта, но и порта выше 10000. На сервере 1 оба порта TCP 6379 и 16379 должны быть открыты. Убедитесь, что файрвол настроен корректно.
В c_slave.conf
настройки будут аналогичны, кроме номера порта. Позднее для его настройки режима slave, соответствующего определенному узлу master, будет использоваться сценарий redis-trib.rb
, а не директива slaveof
.
# bind 127.00.1 protected-mode no port 6381 pidfile /var/run/redis_6381.pid cluster-enabled yes cluster-config-file nodes-6381.conf cluster-node-timeout 15000
Повторите процедуру для оставшихся двух серверов, определив порты для всех пар master-slave.
Server | Master | Slave |
1 | 6379 | 6381 |
2 | 6380 | 6379 |
3 | 6381 | 6380 |
Запуск узлов Master и Slave
Подключитесь по SSH к серверу 1 и запустите оба экземпляра Redis:
redis-server redis-stable/a_master.conf redis-server redis-stable/c_slave.conf
Для других двух серверов замените a_master.conf
и c_slave.conf
соответствующим конфигурационным файлом. Все узлы master будут запущены в режиме кластера.
Создание кластера с использованием встроенного скрипта Ruby
На этом этапе на каждом сервере запущены по два независимых узла master. Дальнейшая установка кластера происходит с помощью скрипта Ruby, который хранится в ~/redis-stable/src/
, позволяет создать кластер и управлять им.
Если Ruby еще не установлен, установите его:
sudo apt install ruby
Установите пакет Redis для Ruby:
gem install redis
Чтобы запустить скрипт, перейдите в каталог, где находится исходный код Redis и выполните настройку серверов кластера, передав список пар ip:port серверов, которые будут играть роль master:
redis-stable/src/redis-trib.rb create ip.of.server1:6379 ip.of.server2:6380 ip.of.server3:6381
При успешной установке кластера вернется ответ:
>>>Creating cluster >>>Performing hash slots allocation on 3 nodes... 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. [OK] All nodes agree about slots configuration. >>> Check for open slots... >>> Check slots coverage... [OK] All 16384 slots covered.
Теперь мы можем получить все связанные с кластером узлы с помощью redis-cli
. Флаг -c
определяет соединение с кластером:
redis-cli -c -h ip.of.server1 -p 6379 ip.of.server1>CLUSTER NODES
Эта команда возвращает список узлов в кластере, идентифицированных по ID. Для выхода из интерфейса нажмите exit
.
ip.of.server1>exit
Команды Redis не чувствительны к регистру. Однако для ясности, в данной инструкции мы их пишем заглавными буквами.
На данном этапе в кластере только 3 master-сервера, данные будут распределяться по кластеру, но не реплицироваться. Присоединим к каждому серверу master один сервер slave, чтобы обеспечить репликацию данных.
Добавление узлов Slave
Для добавления новых узлов в кластер опять воспользуемся утилитой redis-trib
. Для присоединения сервера slave к master будем использовать команду:
./redis-trib.rb add-node --slave --master-id [master_id_c] ip.of.server1:6381 ip.of.server3:6381
В результате должен вернуться ответ:
>>> Adding node ip.of.server1:6381 to cluster ip.of.server3:6381 >>> Performing Cluster Check (using node ip.of.server3:6381) M: [master_id_c] ip.of.server3:6381 slots:10923-16383 (5461 slots) master 0 additional replica(s) M: [master_id_a] ip.of.server1:6379 slots:0-5460 (5461 slots) master 0 additional replica(s) M: [master_id_b] ip.of.server2:6380 slots:5461-10922 (5462 slots) master 0 additional replica(s) [OK] All nodes agree about slots configuration. >>> Check for open slots... >>> Check slots coverage... [OK] All 16384 slots covered. >>> Send CLUSTER MEET to node ip.of.server1:6381 to make it join the cluster. Waiting for the cluster to join... >>> Configure node as replica of ip.of.server3:6381.
Повторите это действие для двух оставшихся узлов:
./redis-trib.rb add-node --slave --master-id [master_id_a] ip.of.server2:6379 ip.of.server1:6379 ./redis-trib.rb add-node --slave --master-id [master_id_b] ip.of.server3:6380 ip.of.server2:6380
Распределение данных
Интерфейс командной строки Redis позволяет задать и просмотреть ключи с помощью SET
и GET
и других команд. Вы можете присоединиться к любому из узлов master и получить свойства кластера Redis.
redis-cli -c -h ip.of.server1 -p 6379
Используйте команду CLUSTER INFO
для просмотра информации о состоянии кластера, например, его размер, хэш слоты, ошибки, если они есть.
ip.of.server1:6379>CLUSTER INFO cluster_state:ok cluster_slots_assigned:16384 cluster_slots_ok:16384 cluster_slots_pfail:0 cluster_slots_fail:0 cluster_known_nodes:6 cluster_size:3 cluster_current_epoch:6 cluster_my_epoch:1 cluster_stats_messages_ping_sent:8375 cluster_stats_messages_pong_sent:9028 cluster_stats_messages_meet_sent:1 cluster_stats_messages_sent:17404 cluster_stats_messages_ping_received:9022 cluster_stats_messages_pong_received:8376 cluster_stats_messages_meet_received:6 cluster_stats_messages_received:17404
Для проверки репликации master/slave используйте INFO replication
, которая возвращает информацию об узлах slave.
ip.of.server1:6379>INFO replication role:master connected_slaves:1 slave0:ip=ip.of.server1,port=6381,state=online,offset=213355,lag=1 master_replid:cd2e27cba094f2e7ed38b0313dcd6a979ab29b7a master_replid2:0000000000000000000000000000000000000000 master_repl_offset:213355 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:197313 repl_backlog_histlen:16043
Для проверки распределения данных можно установить несколько пар ключ-значение.
ip.of.server1:6379> SET John Adams -> Redirected to slot [6852] located at ip.of.server2:6380 OK ip.of.server2:6380> SET James Madison -> Redirected to slot [2237] located at ip.of.server1:6379 OK ip.of.server1:6379> SET Andrew Jackson -> Redirected to slot [15768] located at ip.of.server3:6381 OK ip.of.server3:6381> GET John -> Redirected to slot [6852] located at ip.of.server2:6380 "Adams" ip.of.server2:6380>
Поведение Slave при отказе Master
При использовании данной топологии, при отказе одного из серверов кластер будет полностью работоспособен — узел оставшийся без master-а узел slave станет master-ом.
Для проверки добавим пару ключ-значение:
ip.of.server1:6379> SET foo bar -> Redirected to slot [12182] located at ip.of.server3:6381 OK ip.of.server3:6381> GET foo "bar"
Ключ foo
добавлен в master на сервере 3 и скопирован в slave на сервере 1.
В случае, если сервер 3 станет недоступен, slave на сервере 1 станет master и кластер останется доступным.
ip.of.server1:6379> CLUSTER NODES [slave_id_b] ip.of.server3:6380@16380 slave,fail [master_id_b] 1502722149010 1502722147000 6 connected [slave_id_a] ip.of.server2:6379@16379 slave [master_id_a] 0 1502722242000 5 connected [slave_id_c_promoted] ip.of.server1:6381@16381 master - 0 1502722241651 7 connected 10923-16383 [master_id_b] ip.of.server2:6380@16380 master - 0 1502722242654 2 connected 5461-10922 [master_id_c] ip.of.server3:6381@16381 master,fail - 1502722149010 1502722145402 3 connected [master_id_a] ip.of.server1:6379@16379 myself,master - 0 1502722241000 1 connected 0-5460
Для ключа, который был в хэш слоте на сервере 3, пара ключ-значение теперь хранится на сервере 1.
ip.of.server1:6379> GET foo -> Redirected to slot [12182] located at ip.of.server1:6381 "bar"
Дополнительная функциональность, например, добавление узлов, создание нескольких узлов slave, или resharding данных не описана в данном руководстве. Подробнее о том, как использовать эти возможности, читайте в официальной документации Redis.
Дополнительные ресурсы
Возможно, вам будут полезны ссылки ниже для получения более подробной информации по теме: