25.1. Сравнение различных решений
- Отказоустойчивость на разделяемых дисках
Отказоустойчивость на разделяемых дисках позволяет избежать избыточности синхронизации путём задействования только одной копии базы данных. Она использует единственный дисковый массив, который разделяется между несколькими серверами. Если основной сервер БД откажет, резервный сервер может подключиться и запустить базу данных, что позволит восстановить БД после аварии. Это обеспечивает быстрое переключение без потери данных.
Функциональность разделяемого оборудования обычно реализована в сетевых устройствах хранения. Так же возможно применение сетевой файловой системы; особое внимание следует уделить тому, чтобы поведение системы полностью соответствовало POSIX (см. Подраздел 17.2.2). Существенное ограничение этого метода состоит в том, что в случае отказа или порчи разделяемого дискового массива оба сервера: главный и резервный — станут нерабочими. Другая особенность — резервный сервер никогда не получает доступ к разделяемым дискам во время работы главного.
- Репликация на уровне файловой системы (блочного устройства)
Видоизменённая версия функциональности разделяемого оборудования представлена в виде репликации на уровне файловой системы, когда все изменения в файловой системе отражаются в файловой системе другого компьютера. Единственное ограничение: синхронизация должна выполняться методом, гарантирующим целостность копии файловой системы на резервном сервере — в частности, запись на резервном сервере должна происходить в том же порядке, что и на главном. DRBD является популярным решением на основе репликации файловой системы для Linux.
- Трансляция журнала транзакций
Серверы тёплого и горячего резерва могут так же поддерживаться актуальными путём чтения потока записей из журнала изменений (WAL). Если основной сервер отказывает, резервный содержит почти все данные с него и может быть быстро преобразован в новый главный сервер БД. Это можно сделать синхронно или асинхронно, но может быть выполнено только на уровне сервера БД целиком.
Резервный сервер может быть реализован с применением трансляции файлов журналов (см. Раздел 25.2), или потоковой репликации (см. Подраздел 25.2.5), или их комбинацией. За информацией о горячем резерве обратитесь к Разделу 25.5.
- Репликация главный-резервный на основе триггеров
При репликации главный-резервный все запросы, изменяющие данные, пересылаются главному серверу. Главный сервер, в свою очередь, асинхронно пересылает изменённые данные резервному. Резервный сервер может обрабатывать запросы только на чтение при работающем главном. Такой резервный сервер идеален для обработки запросов к хранилищам данных.
Slony-I является примером подобного типа репликации, действующей на уровне таблиц, и поддерживает множество резервных серверов. Так как обновления на резервных серверах происходят асинхронно (в пакетах), возможна потеря данных во время отказа.
- Репликация запросов в среднем слое
В схеме с репликацией запросов в среднем слое, средний слой перехватывает каждый SQL-запрос и пересылает его на один или все серверы. Каждый сервер работает независимо. Модифицирующие запросы должны быть направлены всем серверам, чтобы каждый из них получал все изменения. Но читающие запросы могут быть посланы только на один сервер, что позволяет перераспределить читающую нагрузку между всеми серверами.
Если запросы просто перенаправлять без изменений, функции подобные
random()
,CURRENT_TIMESTAMP
и последовательности могут получить различные значения на разных серверах. Это происходит потому что каждый сервер работает независимо, а эти запросы неизбирательные (и действительно не изменяют строки). Если такая ситуация недопустима, или средний слой, или приложение должно запросить подобные значения с одного сервера, затем использовать его в других пишущих запросах. Другим способом является применения этого вида репликации совместно с другим традиционным набором репликации главный-резервный, то есть изменяющие данные запросы посылаются только на главный сервер, а затем применяются на резервном в процессе этой репликации, но не с помощью реплицирующего среднего слоя. Следует иметь в виду, что все транзакции фиксируются или прерываются на всех серверах, возможно с применением двухфазной фиксации (см. PREPARE TRANSACTION и COMMIT PREPARED). Репликацию такого типа реализуют, например Pgpool-II и Continuent Tungsten.- Асинхронная репликация с несколькими главными серверами
Если серверы не находятся постоянно в единой сети или связаны низкоскоростным каналом, как например, ноутбуки или удалённые серверы, обеспечение согласованности данных между ними представляет проблему. Когда используется асинхронная репликация с несколькими главными серверами, каждый из них работает независимо и периодически связывается с другими серверами для определения конфликтующих транзакций. Конфликты могут урегулироваться пользователем или по правилам их разрешения. Примером такого типа репликации является Bucardo.
- Синхронная репликация с несколькими главными серверами
При синхронной репликации с несколькими главными серверами каждый сервер может принимать запросы на запись, а изменённые данные передаются с получившего их сервера всем остальным, прежде чем транзакция будет подтверждена. Если запись производится интенсивно, это может провоцировать избыточные блокировки и задержки при фиксации, что приводит к снижению производительности. Запросы на чтение могут быть обработаны любым сервером. В некоторых конфигурациях для более эффективного взаимодействия серверов применяются разделяемые диски. Синхронная репликация с несколькими главными серверами лучше всего работает, когда преобладают операции чтения, хотя её большой плюс в том, что любой сервер может принимать запросы на запись — нет необходимости искусственно разделять нагрузку между главным и резервными серверами, а так как изменения передаются от одного сервера другим, не возникает проблем с недетерминированными функциями вроде
random()
.Postgres Pro не предоставляет данный тип репликации, но так как Postgres Pro поддерживает двухфазное подтверждение транзакции (PREPARE TRANSACTION и COMMIT PREPARED) такое поведение может быть реализовано в коде приложения или среднего слоя.
- Коммерческие решения
Так как Postgres Pro обладает открытым кодом и легко расширяется, некоторые компании взяли за основу Postgres Pro и создали коммерческие решения с закрытым кодом со своими реализациями свойств отказоустойчивости, репликации и балансировки нагрузки.
Таблица 25.1 итоговая таблица возможностей различных решений приведена ниже.
Таблица 25.1. Таблица свойств отказоустойчивости, балансировки нагрузки и репликации
Тип | Отказоустойчивость через разделяемые диски | Репликация файловой системы | Трансляция журнала транзакций | Репликация главный-резервный на основе триггеров | Репликация запросов в среднем слое | Асинхронная репликация с несколькими главными серверами | Синхронная репликация с несколькими главными серверами |
---|---|---|---|---|---|---|---|
Наиболее типичная реализация | NAS | DRBD | Потоковая репликация | Slony | pgpool-II | Bucardo | |
Метод взаимодействия | разделяемые диски | дисковые блоки | WAL | Строки таблицы | SQL | Строки таблицы | Строки таблицы и блокировки строк |
Не требуется специального оборудования | • | • | • | • | • | • | |
Допускается несколько главных серверов | • | • | • | ||||
Нет избыточности главного сервера | • | • | • | ||||
Нет задержки при нескольких серверах | • | без синхр. | • | • | |||
Отказ главного сервера не может привести к потере данных | • | • | с синхр. | • | • | ||
Резервный сервер принимает читающие запросы | с горячим резервом | • | • | • | • | ||
Репликация на уровне таблиц | • | • | • | ||||
Не требуется разрешение конфликтов | • | • | • | • | • |
Несколько решений, которые не подпадают под указанные выше категории:
- Секционирование данных
При секционировании таблицы расщепляются на наборы данных. Каждый из наборов может быть изменён только на одном сервере. Например, данные могут быть секционированы по офисам, например, Лондон и Париж, с сервером в каждом офисе. В случае необходимости обращения одновременно к данным Лондона и Парижа, приложение может запросить оба сервера, или может быть применена репликация главный-резервный для предоставления копии только для чтения в другом офисе для каждого из серверов.
- Выполнение параллельных запросов на нескольких серверах
Многие из указанных выше решений позволяют обрабатывать несколько запросов на нескольких серверах, но ни один из них не может обрабатывать один запрос с применением нескольких серверов для уменьшения общего времени выполнения. Подобное решение позволяет нескольким серверам обрабатывать один запрос одновременно. Такое обычно достигается путём разделения данных между серверами, обработкой на сервере своей части запроса с возвратом результата на центральный сервер. Там данные проходят окончательную обработку и возвращаются пользователю. Pgpool-II предоставляет такую возможность. Так же это может быть реализовано с применением набора средств PL/Proxy.