1. Введение
В этой статье в основном описывается функция репликации master-slave в Redis. Он будет представлен по очереди с аспектов построения окружения, функционального тестирования и принципиального анализа.
2 Подготовка
Схема архитектуры сервера выглядит следующим образом
Запустите мастер-сервер 101, используйтеinfo replication
Командой для просмотра статуса видно, что роль master (то есть роль main master server), а значениеconnected_saloves равно 0 (количество slave серверов равно 0)
Затем, изменив файл конфигурации, добавьте 102 машины в репликацию master-slave.
Затем используйте команду, чтобы также добавить машину 103 к репликации ведущий-ведомый.
2.1 Добавьте 102 машины в master-slave, изменив файл конфигурации
Добавьте slaveof 192.168.17.101 6379 в файл конфигурации Redis машины с IP-адресом 192.168.17.102.
Запускаем 102 redis, статус такой
Вы можете видеть, что роль становится slave (роль — подчиненный сервер), master_host (IP-адрес главного сервера) — 192.168.17.101, а master_port (порт главного сервера) — 6379.
В это время состояние master-slave главного сервера 101 выглядит следующим образом: вы можете видеть, что значение connect_saloves становится равным 1, и добавляется строка slave0 (статус подчиненного сервера).
2.2 Добавить 103 машины в ведущие и подчиненные по команде
Статус master-slave без выполнения команды slaveof выглядит следующим образом
Начать выполнение команды slaveof
192.168.17.103:6379> slaveof 192.168.17.101 6379
OK
Проверьте статус еще раз, вы можете увидеть, что роль стала подчиненным сервером.
Теперь смотрим на состояние мастер сервера, видно что количество слейв серверов стало 2, и есть еще информация об одном слейве
Среда master-slave настроена здесь, теперь давайте протестируем волну
2.3 Тестирование
Теперь главный сервер 101 вводит команду
192.168.17.101:6379> set 101 101
OK
Затем проверяем все ключи на подчиненном сервере 102 и обнаруживаем, что есть ключ 101, а затем устанавливаем ключ 102
192.168.17.102:6379> keys *
1) "101"
192.168.17.102:6379> get 101
"101"
192.168.17.102:6379> set 102 102
(error) READONLY You can't write against a read only slave.
нашел ошибку(error) READONLY You can't write against a read only slave.
Причина ошибки будет описана позже
Теперь просмотрите все ключи на ведомом сервере 103 и обнаружите, что там также есть101
192.168.17.103:6379> keys *
1) "101"
Затем введите команду на главный сервер 101
192.168.17.101:6379> set ip ip
OK
Затем перейдите на подчиненный сервер 103, чтобы увидеть все ключи.
192.168.17.103:6379> keys *
1) "101"
2) "ip"
Вы можете видеть, что есть еще один ключ, указывающий на то, что данные основного сервиса синхронизируются с подчиненным сервером, процесс работы см. на рисунке ниже.
2.4 Другое
2.4.1 (error) READONLY You can't write against a read only slave.
Произошла ошибка(error) READONLY You can't write against a read only slave.
Потому что
Ведомый узел по умолчанию доступен только для чтения.Если вам нужно изменить его, вы можете изменить следующее свойство в файле конфигурации
slave-read-only yes
2.4.2 Пароль настройки главного сервера
Когда основной сервис устанавливает пароль, в файле конфигурации необходимо добавить необходимые параметры
masterauth <master-password>
3 Принцип реализации
Когда я ввожу команду slaveof на подчиненном сервере 103, появляется следующий журнал
В целом подробные шаги функции репликации master-slave можно разделить на 7 шагов:
- Установите адрес и порт главного сервера
- установить сокетное соединение
- Отправить команду PING
- Аутентификация
- Отправить информацию о порте
- Синхронизировать
- распространение команды
Далее каждый шаг описывается отдельно
3.1 Установите адрес и порт основного сервера
Первым шагом репликации master-slave является установка адреса и порта главного сервера.При вводе команды slaveof или настройке информации в файле конфигурации подчиненный сервер сохранит IP-адрес и номер порта главного сервера. сервер к свойствам состояния сервера.
3.2 Установка сокетного соединения
После выполнения команды slaveof подчиненный сервер возобновит сокетное соединение с главным сервером в соответствии с установленными IP-адресом и портом.
3.3 Отправить команду PING
После успешного подключения к сокету подчиненный сервер отправит команду PING на главный сервер.
В это время команда PING может проверить, является ли состояние чтения и записи сокета нормальным и может ли главный сервер нормально обработать командный запрос.
Ситуация, с которой подчиненный сервер может столкнуться при отправке команды PING, выглядит следующим образом.
3.4 Аутентификация
После того, как подчиненный сервер получит ответ PONG от главного сервера, он проверит, установлен ли подчиненный сервер masterauth.Если он установлен, будет выполнена аутентификация.Если он не установлен, этот шаг будет пропущен. Во время аутентификации с сервера могут возникнуть следующие ситуации
3.5 Отправка информации о порте
После прохождения аутентификации подчиненный сервер отправит свой собственный номер порта прослушивания на главный сервер. После того, как главный сервер получит его, он запишет номер порта в атрибуте состояния, соответствующем подчиненному серверу. вызов на главный серверinfo replication
Вы можете увидеть порт подчиненного сервера, как показано ниже.
3.6 Синхронизация
После отправки информации о порте подчиненный сервер отправит команду PSYNC на главный сервер, выполнит операцию синхронизации и синхронизирует свою собственную базу данных с текущим состоянием базы данных главного сервера.
Синхронизация будет подробно описана позже
3.7 Распространение команд
Когда операция синхронизации будет завершена, главный и подчиненный серверы перейдут к фазе распространения команды. В это время данные главного и подчиненного серверов согласованы.Когда главный сервер получает новую команду записи, он отправляет измененную команду на подчиненный сервер.Подчиненный сервер получает и выполняет команду, чтобы гарантировать, что данные соответствует главному серверу.
Так как же Redis обеспечивает постоянное подключение главного и подчиненного серверов и не теряются ли команды?
О: На этапе распространения команды подчиненный сервер будет использовать механизм обнаружения пульса для периодической отправки сообщений в главную службу.
Команда, отправленная с сервера, выглядит следующим образом
REPLCONF ACK <replication_offset>
replication_offset представляет текущее смещение репликации от сервера
Далее рассмотрим механизм сердцебиения.
3.7.1 Механизм обнаружения сердцебиения
Механизм обнаружения сердцебиения выполняет три функции:
- Проверьте состояние сетевого подключения главного и подчиненного серверов.
- Помогает реализовать опцию min-slaves
- Обнаружение потери команды
3.7.1.1 Проверка состояния сетевого подключения главного и подчиненных серверов
В информации о главном сервере вы можете увидеть информацию о подключении подчиненного сервера, которому он принадлежит, состояние представляет собой состояние подчиненного сервера, смещение представляет собой смещение репликации, а отставание представляет собой значение задержки (существовал механизм обнаружения сердцебиения в течение нескольких секунд). тому назад)
3.7.1.2 Вспомогательная реализация опции min-slave
В файле конфигурации Redis.conf есть следующие два параметра.
# 未达到下面两个条件时,写操作就不会被执行
# 最少包含的从服务器
# min-slaves-to-write 3
# 延迟值
# min-slaves-max-lag 10
Если два параметра раскомментированы, то если количество подчиненных серверов меньше 3, или задержка (лаг) трех подчиненных серверов больше или равна 10 секундам, мастер-сервер откажется выполнять команду записи.
3.7.1.3 Обнаружение потери команды
Смещение репликации можно увидеть в информации о подключении подчиненного сервера.Если смещение репликации главного сервера несовместимо со смещением репликации подчиненного сервера, главный сервер повторно выдаст недостающие данные.
4 Принцип синхронизации
Синхронизация делится на полную повторную синхронизацию и частичную повторную синхронизацию. Итак, что решает выполнить операцию полной или частичной повторной синхронизации?
4.1 Полная повторная синхронизация
Шаги для полной ресинхронизации следующие:
- Когда главный узел получает запрос на полную ресинхронизацию от подчиненного сервера, главный сервер начинает выполнять команду bgsave и использует буфер для записи всех команд записи, выполняемых с этого момента.
- При выполнении команды bgsave главного сервера сгенерированный файл RDB будет отправлен на подчиненный сервер. Когда файл RDB получен с сервера, файл данных сохраняется на жесткий диск, а затем загружается в память.
- Главный сервер буферизует все буферизованные команды подчиненному серверу, получает и выполняет эти команды от подчиненного сервера, синхронизируя подчиненный сервер с тем же состоянием, что и главный сервер.
4.2 Частичная ресинхронизация
Чтобы понять шаги частичной ресинхронизации, вам необходимо понять несколько свойств, необходимых для частичной ресинхронизации.
- копирование смещения
- буфер копирования
- идентификатор запуска
4.2.1 Смещение копирования
Из информации о репликации главного сервера мы видим, что оба подчиненных сервера slave0 и slave1 имеют смещение параметра, которое является смещением репликации подчиненного сервера. Параметр master_repl_offset — это смещение главного сервера. Как показано ниже
Смещение репликации ведущего содержит байты, отправленные ведомому.
Смещение реплики ведомого устройства содержит байты данных, полученных от ведущего устройства.
Сравнивая смещения репликации главного сервера и подчиненного сервера, вы можете узнать, потеряна ли команда.Если она потеряна, будет повторно выдана байтовая команда с разницей в смещении репликации.
Так где же хранятся эти байты данных?
4.2.2 Буфер копирования
Эти байты данных хранятся в буфере репликации главного сервера. Буфер копирования — это очередь фиксированного размера по принципу «первым поступил — первым обслужен» (FIFO) с размером по умолчанию 1 МБ. Размер по умолчанию может быть изменен параметрами ниже
# repl-backlog-size 1mb
Итак, когда добавляются данные в буфер копирования?
О: Во время фазы распространения команды, в дополнение к отправке команды записи на подчиненный узел, главный узел также отправляет копию в буфер невыполненной репликации.
Буфер копирования будет содержать подмножество наиболее распространенных команд записи и соответствующее смещение копии для каждого байта.
Поскольку размер буфера копирования ограничен, объем сохраняемых данных также ограничен. Частичная ресинхронизация также не будет выполнена, если смещение реплик подчиненного сервера и главного сервера отличается более чем на данные, хранящиеся в буфере репликации.
Например, смещение репликации главного сервера равно 20 000, данные, которые может хранить буфер, — только 5 000, а смещение репликации подчиненного сервера — 10 000. В это время между подчиненным сервером и главным сервером копируется смещение 10000, а буфер составляет всего 5000, поэтому полная ресинхронизация все равно будет выполнена. Частичная ресинхронизация будет выполняться только в том случае, если разница в смещении репликации меньше 5000.
4.2.3 Идентификатор запуска
Когда каждый сервер Redis запускается, он автоматически генерирует свой собственный рабочий идентификатор.
Когда подчиненный сервер реплицирует главный сервер в первый раз, главный сервер отправляет подчиненному серверу свой собственный идентификатор запуска.
Когда подчиненный сервер отключается и снова подключается, текущий идентификатор предыдущего главного сервера будет отправлен на текущий подключенный главный сервер. В это время произойдут следующие две ситуации
- Если текущий идентификатор совпадает с идентификатором главного сервера, главный сервер может попытаться выполнить частичную повторную синхронизацию.
- Если текущий идентификатор не соответствует главному серверу, это означает, что главный сервер, подключенный ранее, отличается от этого соединения, и начинается операция полной ресинхронизации.
5 Связанная конфигурация
################################# REPLICATION #################################
# slaveof <主服务器ip> <主服务器端口>
# slaveof <masterip> <masterport>
# masterauth <主服务器Redis密码>
# masterauth <master-password>
# 当slave丢失master或者同步正在进行时,如果发生对slave的服务请求
# yes则slave依然正常提供服务
# no则slave返回client错误:"SYNC with master in progress"
slave-serve-stale-data yes
# 指定slave是否只读
slave-read-only yes
# 无硬盘复制功能
repl-diskless-sync no
# 无硬盘复制功能间隔时间
repl-diskless-sync-delay 5
# 从服务器发送PING命令给主服务器的周期
# repl-ping-slave-period 10
# 超时时间
# repl-timeout 60
# 是否禁用socket的NO_DELAY选项
repl-disable-tcp-nodelay no
# 设置主从复制容量大小,这个backlog 是一个用来在 slaves 被断开连接时存放 slave 数据的 buffer
# repl-backlog-size 1mb
# master 不再连接 slave时backlog的存活时间。
# repl-backlog-ttl 3600
# slave的优先级
slave-priority 100
# 未达到下面两个条件时,写操作就不会被执行
# 最少包含的从服务器
# min-slaves-to-write 3
# 延迟值
# min-slaves-max-lag 10
Эпилог
Файл конфигурации master-slave: [https://github.com/rainbowda/learnWay/tree/master/learnRedis/replication, вы можете скачать его, если вам это нужно.
Здесь представлена функция репликации master-slave Redis. Несмотря на то, что ведущий-ведомый решает проблему разделения операций чтения и записи и балансировки нагрузки при чтении данных, после сбоя узла он не может автоматически восстанавливаться, переключаться между ведущими и подчиненными и выполнять другие функции. Итак, есть функция часового.