серия Redis: часовой

Redis задняя часть сервер GitHub

1. Введение

Sentinel — это решение высокой доступности для Redis: Sentinel позволяет создать распределенную систему, которая автоматически обновляет сервер с сервера до основного сервера при сбое основного сервера. Решена проблема, связанная с необходимостью вмешательства человека при сбое репликации master-slave.
В этой статье представлена ​​конструкция дозорного и то, как дозорный выполняет такие функции, как обнаружение дозорного и переключение ведущий-ведомый.

2 Подготовка

На основе исходного master-slave каждая машина запускает дозорный. Схема архитектуры выглядит следующим образом

2.1 Конфигурация

Файл конфигурации выглядит следующим образом

daemonize yes

bind 0.0.0.0

port 26379
dir "/usr/soft/redis"
loglevel notice
logfile "/usr/soft/redis/sentinel.log"

# 修改改成5秒
sentinel monitor learnSentinelMaster 192.168.17.101 6379 2
sentinel down-after-milliseconds learnSentinelMaster 5000
sentinel config-epoch learnSentinelMaster 1

2.2 Способ запуска

Есть два способа

src/redis-sentinel sentinel.conf
src/redis-server sentinel.conf --sentinel

3 Начать строительство

Процесс создания часового заключается в следующем.

После сборки кластера Sentinel содержимое журнала выглядит следующим образом.

После запуска конфигурационный файл sentinel.conf увеличит содержимое

daemonize yes

bind 0.0.0.0

port 26379
dir "/usr/soft/redis"
loglevel notice
logfile "/usr/soft/redis/sentinel.log"

# 修改改成5秒
sentinel myid b457cbbcda1991f540d56c6e8faea123a668b16c
sentinel monitor learnSentinelMaster 192.168.17.101 6379 2
sentinel down-after-milliseconds learnSentinelMaster 5000
# Generated by CONFIG REWRITE
sentinel config-epoch learnSentinelMaster 1
sentinel leader-epoch learnSentinelMaster 0
sentinel known-slave learnSentinelMaster 192.168.17.102 6379
sentinel known-slave learnSentinelMaster 192.168.17.103 6379
sentinel known-sentinel learnSentinelMaster 192.168.17.101 26379 f0230d4fdf1ffc7865852de71f16b3017cc1617c
sentinel known-sentinel learnSentinelMaster 192.168.17.102 26379 5b1099513713310eba94e69513dba76cf0ac2222
sentinel current-epoch 1

4 Начать процесс

Давайте посмотрим, что происходит внутри Redis во время запуска кластера Sentinel. Действуйте следующим образом

  1. Инициализировать сервер
  2. Используйте специальный код Sentinel
  3. Инициализировать состояние Sentinel
  4. Создайте сетевое подключение к главному серверу

4.1 Инициализировать сервер

Sentinel — это по сути просто сервер Redis, работающий в специальном режиме, поэтому инициализация мало чем отличается от инициализации разных серверов Redis. Отличие состоит в том, что дозорный сервер не загружает файлы RDB и AOF, а некоторые командные функции не используются дозорным сервером.

4.2 Использование специального кода Sentinel

После инициализации сервера сервер Sentinel заменит часть кода, используемого обычным сервером Redis, кодом, предназначенным для Sentinel. Ниже приведен список дозорных команд, файл кода находится вGitHub.com/Антиэнтузиазм/Горячие…

struct redisCommand sentinelcmds[] = {
    {"ping",pingCommand,1,"",0,NULL,0,0,0,0,0},
    {"sentinel",sentinelCommand,-2,"",0,NULL,0,0,0,0,0},
    {"subscribe",subscribeCommand,-2,"",0,NULL,0,0,0,0,0},
    {"unsubscribe",unsubscribeCommand,-1,"",0,NULL,0,0,0,0,0},
    {"psubscribe",psubscribeCommand,-2,"",0,NULL,0,0,0,0,0},
    {"punsubscribe",punsubscribeCommand,-1,"",0,NULL,0,0,0,0,0},
    {"publish",sentinelPublishCommand,3,"",0,NULL,0,0,0,0,0},
    {"info",sentinelInfoCommand,-1,"",0,NULL,0,0,0,0,0},
    {"role",sentinelRoleCommand,1,"l",0,NULL,0,0,0,0,0},
    {"client",clientCommand,-2,"rs",0,NULL,0,0,0,0,0},
    {"shutdown",shutdownCommand,-1,"",0,NULL,0,0,0,0,0}
};

4.3 Инициализация состояния Sentinel

После применения кода, специфичного для дозорного, дозорный инициализирует состояние.Эта структура дозорного состояния содержит все состояния, связанные с функцией дозорного на сервере. Расположение кода структуры также находится во всем файле.c, код структуры выглядит следующим образом

/* Main state. */
struct sentinelState {
    char myid[CONFIG_RUN_ID_SIZE+1]; /* 当前哨兵ID. */
    uint64_t current_epoch;         /* 当前纪元. */
    dict *masters;      /* 存放哨兵监视的主服务器,key是主服务器的名字,value是指向主服务器的指针tances. */
    int tilt;           /* 是否处于TILT模式? */
    int running_scripts;    /* 目前执正在执行的脚本数量 */
    mstime_t tilt_start_time;       /* 进入TITL开始的时间 */
    mstime_t previous_time;         /* 最后一次执行时间处理器的时间*/
    list *scripts_queue;            /* 包含了所有需要执行的用户脚本 */
    char *announce_ip;  /* 当配置文件中的announce_ip不为空时,记录着这些IP地址 */
    int announce_port;  /* 配置文件中的announce_port */
    unsigned long simfailure_flags; /* 故障模拟 */
    int deny_scripts_reconfig; /* 是否允许哨兵在运行时修改脚本位置? */
} sentinel;

Журнал, который появляется при запуске часового, выглядит следующим образом

# oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
# Redis version=4.9.103, bits=64, commit=00000000, modified=0, pid=2100, just started
# Configuration loaded
* Increased maximum number of open files to 10032 (it was originally set to 1024).
* Running mode=sentinel, port=26379.
# WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.

Идентификатор Sentinel выглядит следующим образом

# Sentinel ID is b457cbbcda1991f540d56c6e8faea123a668b16c

4.4 Создайте сетевое подключение к главному серверу

Последним шагом в инициализации дозорного является создание сетевого подключения к отслеживаемому главному серверу, который будет клиентом главного сервера. Sentinel создаст два асинхронных сетевых подключения к главному серверу.

  1. Командные соединения используются для отправки команд и получения команд от главного сервера.
  2. Соединение для подписки, предназначенное для подписки на канал _sentinel_:hello главного сервера.

Процесс запуска часового здесь завершен, и будет введен следующий шаг.

5 Получить информацию

На этапе сбора информации будет получена информация о главном сервере и подчиненном сервере, а также соответствующая информация о сигнальном устройстве.

5.1 Получить информацию о главном сервере

По умолчанию дозорный будет отправлять командное соединение для отправки команды INFO на отслеживаемый главный сервер с частотой 10 с и получать текущую информацию о главном сервере путем анализа ответа на команду INFO.

Мониторинг главного сервера

# +monitor master learnSentinelMaster 192.168.17.101 6379 quorum 2

Анализируя информацию, возвращаемую главным сервером, можно получить два аспекта информации.

  1. Информация о самом главном сервере
  2. информация с сервера

После получения информации о подчиненном сервере дозорный обновит словарь подчиненных, содержащий структуру экземпляра главного сервера.

5.2 Получить информацию о ведомом сервере

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

Когда будет найден новый подчиненный сервер, появится следующий журнал

* +slave slave 192.168.17.102:6379 192.168.17.102 6379 @ learnSentinelMaster 192.168.17.101 6379
* +slave slave 192.168.17.103:6379 192.168.17.103 6379 @ learnSentinelMaster 192.168.17.101 6379

После создания командного соединения отправляется команда INFO для получения информации. Из информации, полученной от сервера, можно получить следующее

  1. Идентификатор запуска подчиненного сервера run_id
  2. роль раба
  3. IP-адрес master_host подчиненного сервера и номер порта master_port главного сервера.
  4. Состояние подчиненного соединения matser_link_status
  5. Приоритет подчиненного устройства salve_pripority
  6. смещение реплики от ведомого slave_repl_offest

После получения этой информации ранее созданная структура экземпляра подчиненного сервера будет обновлена.

5.3 Получение другой информации Sentinel

Прежде чем получить информацию о других Стражах, узнайте向主服务器和从服务器发送信息и接收来自主服务器和从服务器的频道信息.

5.3.1 Отправка информации на главный и подчиненный серверы

Формат отправляемой команды следующий

PUBLISH __sentinel__:hello "<s_ip>,<s_port>,<s_runid>,<s_epoch>,<m_name>,<m_ip>,<m_port>,<m_epoch>"

PUBLISH — это команда для публикации сообщения,__sentinel__:helloэто имя канала, за которым следуют некоторые параметры, информация о параметрах выглядит следующим образом

5.3.2 Получение информации о канале от главного сервера и подчиненного сервера

Когда Sentinel устанавливает соединение по подписке с главным сервером или подчиненным сервером, Sentinel отправляет команды на сервер через соединение по подписке:

SUBSCRIBE __sentinel__:hello

Указывает дозорную подписку__sentinel__:helloЭтот канал, получать сообщения с этого канала.

Другие Стражи могут узнавать о существовании других Стражей, получая сообщения на этом канале.

5.3.3 Обнаружение Стражей

получив__sentinel__:helloСообщения канала могут обнаруживать присутствие других Стражей. Когда часовой получает сообщение от__sentinel__:helloСообщение канала появится ниже

  1. Определите, отправлено ли сообщение самостоятельно, если да, проигнорируйте сообщение
  2. Когда сообщение не отправляется само по себе, это означает, что есть новый дозорный
  3. Проверьте, есть ли у вас информация о дозорном, и обновите информацию о дозорном
  4. Если нет, создайте новую структуру экземпляра Sentinel и сохраните ее в словаре Sentinels.

Примечание. Словарь Sentinels предназначен для хранения информации Sentinels.

5.3.4 Создание командных подключений к другим Sentinels

Когда Sentinel находит новый Sentinel с помощью информации о канале, он не только создает структуру экземпляра для нового Sentinel в своем собственном словаре sentinels, но также создает командное соединение с новым Sentinel, а новый Sentinel также создает соединение с этим. Команды Sentinel связаны, и в конечном итоге несколько Sentinel образуют взаимосвязанную сеть.

Примечание. Между Sentinels не будет создано подписное соединение.

Журнал часового находится следующим образом

* +sentinel sentinel f0230d4fdf1ffc7865852de71f16b3017cc1617c 192.168.17.101 26379 @ learnSentinelMaster 192.168.17.101 6379
* +sentinel sentinel 5b1099513713310eba94e69513dba76cf0ac2222 192.168.17.102 26379 @ learnSentinelMaster 192.168.17.101 6379

6 Имитация 101 основного сервера, теряющего деньги

Процесс имитации проигрыша главного сервера 101 выглядит следующим образом

Содержимое журнала отключения и повторного подключения выглядит следующим образом.

Далее начните анализировать каждый шаг в процессе отключения

  1. Обнаружение субъективного автономного статуса
  2. Обнаружение объективного автономного статуса
  3. Ведущий страж выборов
  4. отказоустойчивость

6.1 Обнаружение субъективного автономного статуса

По умолчанию Sentinel отправляет команду PING всем экземплярам (ведущему, подчиненному, другому Sentinel), которые установили с ним командное соединение, с частотой один раз в секунду и определяет, находится ли он в сети, оценивая возвращаемый контент. делится на действительные ответы и недействительные ответы.

  • действительный ответ
    • +PING
    • -LOADING
    • -MASTERDOWN
  • неверный ответ
    • Контент, отличный от действительных ответов
    • Нет ответа в течение указанного времени

Параметр down-after-milliseconds в конфигурационном файле может задавать определенное время.Если в течение этого периода времени не получен ответ, определяется, что сервер находится в субъективном автономном состоянии.

sentinel down-after-milliseconds learnSentinelMaster 5000

Теперь введите следующую команду на клиенте 101, чтобы позволить серверу спать в течение 30 секунд.

debug sleep 30

Проверьте журнал Sentinel на этом этапе, подождите 5 секунд, и появится следующее

# +sdown master learnSentinelMaster 192.168.17.101 6379

6.2 Обнаружение объективного автономного статуса

Когда дозорный определяет, что главный сервер субъективно находится в автономном режиме, он запрашивает другие дозорные, контролирующие главный сервер.Когда достаточное количество дозорных определит, что главный сервер отключен, будет выполнена операция аварийного переключения.

Примечание. Сообщения, отправляемые друг другу между часовыми, здесь не описываются.

В конфигурации вы можете указать количество серверов, необходимое для определения основного сервера для перехода в целевое автономное состояние Последний параметр, настроенный ниже, — это необходимое количество часовых, которое заполняется здесь.

sentinel monitor learnSentinelMaster 192.168.17.101 6379 2

В следующем журнале показано, что главный сервер 101 перешел в объективное автономное состояние.

# +odown master learnSentinelMaster 192.168.17.101 6379 #quorum 2/2

Текущая эпоха обновляется, пытаясь вернуться назад

# +new-epoch 2
# +try-failover master learnSentinelMaster 192.168.17.101 6379

На этом этапе начинается подготовка к выбору ведущего сигнального устройства для аварийного переключения.

6.3 Выборы ведущего стража

Когда главный сервер будет объективно отключен, каждый дозорный сервер выберет ведущего дозорного, и этот ведущий дозорный будет выполнять операции аварийного переключения на автономном сервере. Правила выбора ведущего дозорного таковы:

  1. Все онлайн-Стражи могут быть выбраны в качестве ведущих Стражей;
  2. После каждых выборов, независимо от того, были они успешными или нет, все эпохи конфигурации Sentinel будут увеличиваться один раз;
  3. В эпоху конфигурации все Sentinels имеют возможность установить Sentinel в качестве локального лидера Sentinel, и после того, как локальный лидер установлен, он не будет изменен в эту эпоху конфигурации;
  4. Каждый Страж, который обнаружит, что основной сервер перешел к цели в автономном режиме, попросит других Стражей установить себя в качестве локального лидера Стражей;
  5. Когда один Sentinel отправляет команду запроса другому Sentinel, а runid в команде не *, а runid, это означает, что Sentinel-источник просит целевого Sentinel установить первого в качестве локального лидера Sentinel второго.
  6. Принцип установки локального лидера Sentinel осуществляется в порядке очереди, после чего все запросы на настройку будут отклонены;
  7. После того, как целевой Sentinel получит команду, он вернет ответ.Параметры Leader_runid и Leader_epoch в ответе соответственно записывают текущий идентификатор и эпоху конфигурации локального лидера Sentinel целевого Sentinel;
  8. После того, как Sentinel-источник получит ответ, он проверит, равна ли эпоха конфигурации самой себе, если она такая же, и Leader_runid такой же, как он сам, значит, он стал локальным лидером цели;
  9. Если Sentinel назначен местным лидером Sentinel более чем половиной Sentinels, он становится лидером Sentinel;
  10. Поскольку для создания ведущего требуется поддержка половины дозорных, и каждый дозорный может установить локальный дозорный дозор только один раз в каждую эпоху конфигурации, в эпоху конфигурации появляется только один дозорный лидер;
  11. Если ведущий Страж не будет избран в течение заданного периода времени, то отдельные Стражи будут переизбраны через определенный период времени, пока они не будут избраны.

Ниже приводится содержание журнала избрания ведущего стража.

# +vote-for-leader b457cbbcda1991f540d56c6e8faea123a668b16c 2
# 5b1099513713310eba94e69513dba76cf0ac2222 voted for b457cbbcda1991f540d56c6e8faea123a668b16c 2
# f0230d4fdf1ffc7865852de71f16b3017cc1617c voted for b457cbbcda1991f540d56c6e8faea123a668b16c 2

6.4 Отказоустойчивость

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

  1. Выбор нового главного сервера
  2. Изменить цель репликации подчиненного сервера
  3. Превратите старого хозяина в раба

6.4.1 Выбор нового главного сервера

В этот момент ведущий дозорный должен выбрать новый главный сервер, а затем отправить команду SLAVEOF no one на новый главный сервер, чтобы преобразовать подчиненный сервер в главный сервер.

Процесс отбора отфильтровывает несовместимые серверы:

  1. Подчиненный сервер находится в автономном режиме или отключен
  2. Подчиненный сервер, который не ответил на сообщение INFO ведущего часового за последние 5 секунд.
  3. Ведомые устройства, которые были отключены от ведущего в автономном режиме более (down-after-milliseconds * 10) миллисекунд. (Сравните с объективным временем автономной работы основного сервера)

Новые мастера отбираются только для прохождения вышеуказанных тестов и заказываются на основе вышеуказанных критериев:

  1. Подчиненные устройства упорядочиваются по приоритету подчиненных, настроенному в файле redis.conf экземпляра Redis. Чем ниже приоритет, тем выше приоритет.
  2. Если приоритет тот же, проверьте смещение репликации ведомого устройства и выберите ведомое устройство, которое получит больше данных.
  3. Если несколько ведомых устройств имеют одинаковый приоритет и одинаковый процесс обработки данных, выполняется дополнительная проверка и выбирается ведомое устройство с более коротким идентификатором запуска. Идентификатор запуска не очень полезен для ведомых устройств, но он очень полезен для процесса выбора ведомых устройств вместо случайного выбора ведомых устройств.

Выберите подходящий подчиненный узел в качестве нового главного узла.

2101:X 31 Jul 19:13:35.709 # +failover-state-select-slave master learnSentinelMaster 192.168.17.101 6379
2101:X 31 Jul 19:13:35.793 # +selected-slave slave 192.168.17.102:6379 192.168.17.102 6379 @ learnSentinelMaster 192.168.17.101 6379

Начните говорить о конверсии 102 в основной узел

* +failover-state-send-slaveof-noone slave 192.168.17.102:6379 192.168.17.102 6379 @ learnSentinelMaster 192.168.17.101 6379
* +failover-state-wait-promotion slave 192.168.17.102:6379 192.168.17.102 6379 @ learnSentinelMaster 192.168.17.101 6379
# +promoted-slave slave 192.168.17.102:6379 192.168.17.102 6379 @ learnSentinelMaster 192.168.17.101 6379
# +failover-state-reconf-slaves master learnSentinelMaster 192.168.17.101 6379

6.4.2 Изменить цель репликации подчиненного сервера

Когда появится новый главный сервер, ведущий дозорный отправит команду slaveof другим подчиненным серверам для репликации нового главного сервера.

Следующее записывает, как ведущий дозорный отправляет команду SALVEOF ведомому для репликации нового ведущего.

* +slave-reconf-sent slave 192.168.17.103:6379 192.168.17.103 6379 @ learnSentinelMaster 192.168.17.101 6379
* +slave-reconf-inprog slave 192.168.17.103:6379 192.168.17.103 6379 @ learnSentinelMaster 192.168.17.101 6379
* +slave-reconf-done slave 192.168.17.103:6379 192.168.17.103 6379 @ learnSentinelMaster 192.168.17.101 6379

6.4.3 Замена старого мастера на ведомый

В настоящее время, что мне делать, если автономный главный сервер перезапущен? Это также последний шаг в переходе на другой ресурс, который устанавливает автономный главный сервер в качестве подчиненного сервера для нового главного сервера. Когда автономный главный сервер возвращается в оперативный режим, часовой отправит ему команду SLAVEOF, чтобы сделать его подчиненным сервером нового главного сервера.

В это время сервер 101 онлайн.

# -odown master learnSentinelMaster 192.168.17.101 6379

Отработка отказа успешно завершена. Все ведомые перенастроены как ведомые нового мастера.

# +failover-end master learnSentinelMaster 192.168.17.101 6379
# +switch-master learnSentinelMaster 192.168.17.101 6379 192.168.17.102 6379

Статус перехода 101

* +slave slave 192.168.17.101:6379 192.168.17.101 6379 @ learnSentinelMaster 192.168.17.102 6379
# +sdown slave 192.168.17.101:6379 192.168.17.101 6379 @ learnSentinelMaster 192.168.17.102 6379
# -sdown slave 192.168.17.101:6379 192.168.17.101 6379 @ learnSentinelMaster 192.168.17.102 6379
* +convert-to-slave slave 192.168.17.101:6379 192.168.17.101 6379 @ learnSentinelMaster 192.168.17.102 6379

В это время, если вы снова посмотрите на файл конфигурации, вы найдете дополнительную строку sentinel current-epoch 2.

#后台启动
daemonize yes

bind 0.0.0.0

port 26379
dir "/usr/soft/redis"
loglevel notice
logfile "/usr/soft/redis/sentinel.log"

# 修改改成5秒
sentinel myid f0230d4fdf1ffc7865852de71f16b3017cc1617c
sentinel monitor learnSentinelMaster 192.168.17.102 6379 2
sentinel down-after-milliseconds learnSentinelMaster 5000
# Generated by CONFIG REWRITE
sentinel config-epoch learnSentinelMaster 2
sentinel leader-epoch learnSentinelMaster 2
sentinel known-slave learnSentinelMaster 192.168.17.103 6379
sentinel known-slave learnSentinelMaster 192.168.17.101 6379
sentinel known-sentinel learnSentinelMaster 192.168.17.103 26379 b457cbbcda1991f540d56c6e8faea123a668b16c
sentinel known-sentinel learnSentinelMaster 192.168.17.102 26379 5b1099513713310eba94e69513dba76cf0ac2222
sentinel current-epoch 2

7 Связанная конфигурация

# Example sentinel.conf

# 绑定IP地址
# bind 127.0.0.1 192.168.1.1
# 保护模式(是否禁止外部链接,除绑定的ip地址外)
# protected-mode no

# 当前Sentinel服务运行的端口
port 26379

# 
# sentinel announce-ip <ip>
# sentinel announce-port <port>

# Sentinel服务运行时使用的临时文件夹
dir /tmp

# 监听地址为ip:port的一个master
sentinel monitor mymaster 127.0.0.1 6379 2

# 设置连接master和slave时的密码,注意的是sentinel不能分别为master和slave设置不同的密码,因此master和slave的密码应该设置相同。
# sentinel auth-pass mymaster MySUPER--secret-0123passw0rd

# 指定了Sentinel认为Redis实例已经失效所需的毫秒数
sentinel down-after-milliseconds mymaster 30000

# 指定了在执行故障转移时,最多可以有多少个从Redis实例在同步新的主实例,在从Redis实例较多的情况下这个数字越小,同步的时间越长,完成故障转移所需的时间就越长
sentinel parallel-syncs mymaster 1

# 如果在该时间(ms)内未能完成故障转移操作,则认为该故障转移失败
sentinel failover-timeout mymaster 180000

# 指定sentinel检测到该监控的redis实例指向的实例异常时,调用的报警脚本。该配置项可选,但是很常用
# sentinel notification-script mymaster /var/redis/notify.sh

# 当一个master由于failover而发生改变时,这个脚本将会被调用,通知相关的客户端关于master地址已经发生改变的信息。
# sentinel client-reconfig-script mymaster /var/redis/reconfig.sh



Конфигурационный файл Sentinel:GitHub.com/радуга большая/приходите…, при необходимости можно скачать.