Кластерные технологии
Обзор
13
Авторские права
© Postgres Professional, 2018–2022
Авторы: Егор Рогов, Павел Лузанов, Илья Баштанов
Использование материалов курса
Некоммерческое использование материалов курса (презентации,
демонстрации) разрешается без ограничений. Коммерческое
использование возможно только с письменного разрешения компании
Postgres Professional. Запрещается внесение изменений в материалы
курса.
Обратная связь
Отзывы, замечания и предложения направляйте по адресу:
Отказ от ответственности
Компания Postgres Professional не несет никакой ответственности за
любые повреждения и убытки, включая потерю дохода, нанесенные
прямым или непрямым, специальным или случайным использованием
материалов курса. Компания Postgres Professional не предоставляет
каких-либо гарантий на материалы курса. Материалы курса
предоставляются на основе принципа «как есть» и компания Postgres
Professional не обязана предоставлять сопровождение, поддержку,
обновления, расширения и изменения.
2
Темы
Ожидания от кластера
Средства реализации
Решения с реализацией внутри PostgreSQL
Решения с внешними системами управления
3
Ожидания от кластера
Высокая доступность системы
в том числе отказоустойчивость
Масштабируемость
Согласованность данных
4
Высокая доступность
Обеспечение минимального времени простоя системы
вызванного как сбоями, так и плановыми работами
Различные характеристики
отношение времени работы системы к общему времени → 100 %
время наработки на отказ → ∞
RTO — целевое время восстановления → 0
RPO — целевая точка восстановления → 0
и другие
Доступность системы — отношение времени, в течении которого
система сохраняет доступность, к общему времени эксплуатации.
Понятие доступности более широкое, чем отказоустойчивость,
поскольку простои могут быть вызваны не только отказами, но и
плановыми работами.
Часто говорят о доступности
- «одна девятка» 90 % — 36,5 дней простоя в год,
- «две девятки» 99 % — 3,65 дней простоя в год,
- «три девятки» 99,9 % — 8,76 часов простоя в год,
- «четыре девятки» 99,99 % — 52,56 минут простоя в год,
- «пять девяток» 99,999 % — 5,26 минут простоя в год, и т. д.
Высокая доступность предполагает цифры, близкие к 100 %.
Для примера: облачный сервис для реляционных СУБД Amazon RDS
обещает (https://aws.amazon.com/rds/sla/) доступность узлов на уровне
99,95 %.
Другими характеристиками доступности могут быть:
- время наработки на отказ;
- целевое время восстановления (Recovery Time Objective) — время,
за которое система должна восстановиться;
- целевая точка восстановления (Recovery Point Objective) — период,
за который можно потерять данные при сбое) и др.
5
Масштабируемость
Масштабируемость
изменение характеристики системы при одновременном увеличении
объема данных, нагрузки и числа узлов в N раз
идеальная масштабируемость времени отклика
время отклика не должно увеличиваться
идеальная масштабируемость пропускной способности
число обрабатываемых запросов должно расти линейно
Ускорение
отношение времени отклика на одном узле ко времени отклика
в кластере из N узлов
Важным понятием для кластера является масштабируемость: это
свойство показывает, как меняется какая-либо характеристика системы
с увеличением числа узлов, объема данных и нагрузки.
Масштабируемость времени отклика показывает, как меняется время
отклика (в контексте СУБД — время выполнения запроса) с ростом
объема данных и числа запросов при добавлении узлов кластера.
В идеале время отклика не должно увеличиваться.
Можно говорить не только о масштабируемости времени отклика, но и
об ускорении, которое показывает, как при той же нагрузке и том же
объеме данных время отклика меняется с увеличением числа узлов.
Эта характеристика особенно важна для OLTP-систем.
Масштабируемость пропускной способности показывает, как
меняется число обрабатываемых запросов с ростом объема данных
при добавлении узлов кластера. В идеале число обрабатываемых
запросов должно увеличиваться линейно с ростом числа узлов.
Идеальная масштабируемость (увы, не достижимая на практике)
позволяет решать проблемы роста простым добавлением новых узлов
в кластер.
6
Согласованность
Локальные транзакции
практически никаких гарантий при переключении между узлами
согласованность обеспечивает приложение
Глобальные (распределенные) транзакции
ACID-согласованность
проблема атомарности транзакций
Чем более строгие гарантии согласованности данных предоставляет
кластер, тем больше он похож на «единой целое», тем проще с ним
работать, тем меньше надо учитывать особенности в прикладном коде.
Но тем дороже это обходится в смысле производительности.
Если кластер основан на схеме «мастер-реплика» с одним пишущим
узлом, и транзакции выполняются локально на одном из узлов,
гарантии могут оказаться очень слабыми. Например, один узел мог
успеть применить запись о фиксации транзакции и ее результат уже
доступен клиентам, а другой узел — еще нет. В таком случае у клиента,
в частности, нет гарантии, что он не прочитает старое значение
(на одном узле) уже после того, как прочитал новое (на другом узле).
Обработка таких ситуаций ложится на приложение, которое должно
быть рассчитано на работу в этой конфигурации.
Если кластер предоставляет глобальные (распределенные)
транзакции, то можно говорить о согласованности в обычном смысле
ACID: глобальная транзакция должна переводить базу данных из
одного согласованного состояния в другое согласованное (C), при
условии, что транзакция полностью выполняется на всех узлах (A) при
отсутствии помех со стороны других конкурентных транзакций (I).
В этом случае требуется обеспечить атомарность транзакций: все
узлы кластера должны выполнить одинаковое действие — либо
применить, либо отменить транзакцию. PostgreSQL предоставляет для
этого относительно простой протокол двухфазной фиксации (2PC),
который, однако, не устойчив к сбоям.
7
Средства реализации
Обеспечение высокой доступности
Виды сбоев и их обнаружение
Распределенные протоколы консенсуса
Обеспечение масштабируемости
8
Высокая доступность
Плановые работы без прерывания обслуживания
средствами PostgreSQL
временный вывод узла из кластера
Дублирование компонентов, исключение точек отказа
серверы PostgreSQL (и другие необходимые системы)
сетевое оборудование
электропитание
Обнаружение сбоев и управление восстановлением
Время простоя может быть вызвано не только возникающими
неполадками, но и плановыми работами, которые невозможно
выполнить без прерывания обслуживания. С каждой версией
PostgreSQL уменьшается число действий, требующий перезагрузки
сервера. Кроме того, кластер должен уметь отрабатывать плановый
останов одного из серверов с минимальными проблемами для
пользователей.
Основа обеспечения отказоустойчивости — дублирование всех узлов
системы. Речь не только о серверах баз данных, но и о сетевом
оборудовании, обеспечении электропитания и пр.
Разумеется, недостаточно просто дублировать компоненты системы.
Надо обеспечить обнаружение сбоев в работе системы и их
обработкукорректное переключение на резервные узлы и
возвращение узлов в строй после устранения неисправности.
Большая часть необходимых средств отсутствует в стандартном
PostgreSQL или вообще относится к другим компонентам. В целом, чем
более доступной должна быть система, тем сложнее она будет
устроена.
9
Отказ узла
обнаружение отказа:
периодический обмен сообщениями
(heartbeat)
Чтобы говорить об обнаружении и управлении сбоями, нужно
определиться, что считать сбоем. С точки зрения программного
обеспечения кластера обычно рассматривают два вида сбоев: отказ
узла и разделение сети (network partitioning).
При отказе узла этот узел перестает функционировать как часть
кластера. Отказ может быть вызван остановом или сбоем сервера
СУБД, сбоем операционной системы, выключением сервера и т. п.
Для обнаружения сбоев узлы кластера периодически обмениваются
короткими сообщениями (heartbeat). Если какой-либо из узлов не
отвечает в течении определенного времени, фиксируется и
отрабатывается сбой этого узла.
Процедура отработки отказа зависит от архитектуры кластера.
Например, в кластере, построенном на схеме «мастер-реплика», при
сбое мастера какая-то из реплик должна занять его место (должно
произойти переключение ролей).
10
Разделение сети
split-brain: кластер распадается
на независимые, одновременно работающие
части, принимающие запросы на запись
отказ узла, задержка или отказ сети
неотличимы друг от друга
Разделение сети происходит при сбое сетевого оборудования. При этом
все узлы могут сохранить работоспособность, но одна группа теряет
связь с другой группой узлов кластера.
Самая неприятная ситуация возникает в случае, когда обе группы
сохраняют связь с клиентами. Это может привести к проблеме split-
brain: кластер распадается на две части, каждая из которых начинает
работать автономно и при этом принимать запросы на запись.
Возникает рассогласование данных, и при восстановлении данные
одной из групп будут вынуждено потеряны.
Заметим, что сеть может выйти из строя, а может временно начать
терять пакеты или доставлять их с задержкой (более того, в некоторых
ОС обычная загруженность процессора тоже может приводить
к сетевым задержкам). Все эти случаи неотличимы от сбоя узла: если
от узла вовремя не поступит подтверждение, кластер должен считать
такую ситуацию сбоем. Узел может сохранять работоспособность или
нет, но узнать это невозможно, если с ним нет связи.
Многие системы будут нестабильно работать в условиях ненадежного
сетевого подключения. Чтобы уменьшить вероятность ложных
срабатываний, можно увеличить пороговое значение, но тогда
увеличится и время обнаружения настоящего сбоя, а это приведет
к снижению доступности. Для примера: etcd предлагает устанавливать
порог в 10 раз выше, чем время нормального отклика узла.
11
Проблема консенсуса
Узлы кластера должны уметь приходить к общему мнению
общее представление о текущем состоянии всех узлов кластера
атомарная фиксация глобальных транзакций
Консенсус через обмен сообщениями
нет общей памяти (shared nothing)
используются специальные распределенные протоколы,
учитывающие возможность сбоев на каждом этапе переговоров
построение, доказательство корректности и тестирование реализации —
сложная задача!
Кластер, составленный из независимых узлов, должен работать
в некотором смысле — как единое целое. Чтобы управлять сбоями,
узлы должны разделять общее представление о состоянии всех узлов
кластера. Чтобы принять решение о фиксации глобальной транзакции,
все узлы кластера должны согласиться, что это возможно, и в итоге
выполнить фиксацию атомарно.
Поскольку никакого общего устройства хранения у узлов нет (мы
рассматриваем системы класса shared nothing), то единственный
способ прийти к общему мнению — договориться, используя какой-
либо протокол распределенного консенсуса. Протокол определяет,
какими сообщениями и в каком порядке должны обменяться узлы,
чтобы прийти к соглашению.
Важный момент: распределенные алгоритмы очень сложны, поскольку
учитывают множество граничных случаев. Например, они должны
корректно работать в ситуациях, когда на любом этапе переговоров
происходит какой-либо сбой. Доказательство корректности таких
алгоритмов и тестирование их реализаций — также очень сложная
задача. Поэтому не стоит пытаться создать собственный алгоритм или
доверять неизвестному.
12
Протоколы 2PC, 3PC
Двухфазная фиксация
prepare: координатор проводит голосование;
commit: если все «за», координатор сообщает о фиксации.
поддерживается PostgreSQL (PREPARE TRANSACTION + COMMIT)
Трехфазная фиксация
prepare: координатор проводит голосование;
precommit: если все «за», координатор сообщает всем о намерении;
commit: если все успешно, координатор сообщает о фиксации.
Свойства
возможны ситуации (например, разделение сети),
в которых невозможно разрешить транзакцию до устранения сбоя
Простой протокол для фиксации глобальных транзакций, поддержка
которого встроена в PostgreSQL, — двухфазная фиксация (2-Phase
Commit). Узел, выполняющий транзакцию, считается координатором.
На подготовительной фазе (prepare) координатор сообщает остальным
узлам о фиксации транзакции и дожидается от них подтверждения, что
они готовы выполнить фиксацию (если хотя бы один узел не готов —
транзакция обрывается). На фазе фиксации (commit) координатор
сообщает всем узлам о решении зафиксировать транзакцию. При
получении от всех подтверждения, координатор тоже фиксирует
транзакцию.
Этот протокол позволяет обойтись минимумом сообщений, но не
устойчив к сбоям. Например, при отказе координатора после фазы
prepare, остальные узлы не имеют информации о том, должна ли
транзакция быть зафиксирована или отменена. Им придется ждать
устранения сбоя.
Это ограничение преодолевает более сложный протокол трехфазной
фиксации (3-Phase Commit). В нем вводится дополнительная фаза
precommit, на которой координатор сообщает всем узлам о принятом
решении фиксировать транзакцию. После этого, даже если произойдет
сбой координатора, оставшиеся узлы будут иметь право зафиксировать
транзакцию самостоятельно (а до фазы precommit — самостоятельно
отменить ее).
Однако оба алгоритма не справляются с ситуациями разделения сети.