Пока представляется более удобным и целесообразным публиковать новости по проекту здесь, нежели вести отдельный "сферический блог в вакууме".
Новости, тезисно:- Важная, принципиальная новость: Были устранены две большие недоделки связанные с согласованностью данных после системного сбоя при использовании LMDB-движка для хранения данных. Грубо говоря, мы сделали то, что в OpenLDAP посчитали невозможным, подробности см. ниже.
- Принято решение сохранить поддержку только POSIX-совместимых платформ, с набором предоставляемых набор возможностей не хуже чем RedHad Enterprise Linux 6. Всё более старое или несовместимое, в том числе: Windows, SunOS, Solaris, старые версии *BSD - поддерживаться не будут.
- В июне планируется оформить сборку пакетов (deb, rpm) для распространенных дистрибутивов Linux. Поддержки FreeBSD в виде порта/пакета не планируется (не найдено меинтейнера, готового взяться за работу).
Кратко о самом важном:- Обе недоделки были зафиксированны ранее в issues №1 и №2, сразу как только стало ясно, что их устранение в оригинальном OpenLDAP не возможно и для этого требуется клонировать исходный проект.
- В оригинальном OpenLDAP первая недоделка считается feature (как-бы "не баг, а фича"), а вторая не актуальна, так как LIFO-reclaiming для LMDB есть только в ReOpenLDAP.
- Переписав часть кода отвечающую за фиксацию изменений на диске, мы обеспечили гарантию согласованности данных (т.е. не разрушение всей базы при системном сбое, например из-за выключении питания), одновременно сохранив возможность компромисса между высокой производительностью по-записи и частотой фиксации изменений на диске.
Подробно:- Обе недоделки касаются внутренностей движка базы данных LMDB (aka Symas Lightning Memory-Mapped Database).
- Исходная реализация LMDB обеспечивает целостность данных, но ориентирована на обеспечение чемпионской производительности по-чтению, а не по-записи.
- Для гарантии согласованности (не разрушения базы) на диске, требовалась фиксация данных после каждой транзакции.
- Проблема в том, что при большой нагрузке по-записи (десятки тысяч изменений в секунду) для этого требуется подсистема хранения с фантастической производительностью.
- С технической точки зрения проблема известна как LMDB write-amplification.
- Другими словами, даже минимальные изменения в базе данных, могут приводить к необходимости записи на диск относительно большого объема данных.
- Поэтому, во многих случаях, для получения требуемой производительности приходилось отказываться от фиксации изменений после каждой транзакции:
- Для этого в LMDB предусмотрены специальные режимы, управляемые опцией envflags: dbnosync, nometasync, writemap и mapasync (подробности см. в документации).
- Не вдаваясь в детали, можно сказать, что суть всех этих режимов в отложенной фиксации изменений на диске.
- С этой целью предлагается механизм периодического формирования "контрольных точек", конфигурируемый директивой checkpoint <kbyte> <min>.
- Однако и тут не обошлось без нескольких "ведер дегтя":
- Контрольные точки по задаваемому размеру изменений (параметр <kbyte>) в OpenLDAP не реализованы.
- Периодические контрольные точки с задаваемым интервалом (параметр <min>) в OpenLDAP возможны только с гранулярностью в одну минуту, что полностью их обесценивает: при большой нагрузке за минуту будет огромный объем изменений, который не получится "быстро" записать на диск, и который одновременно слишком опасно потерять в случае сбоя.
- Повторное использование (aka reclaiming) страниц базы данных выполняется в FIFO-порядке(тут была очепятка), что делает полностью неэффективным кеш обратной записи в системах хранения (дисковых массивах) промышленного уровня.
- Кроме этого, в режимах writemap и mapasync согласованность данных не гарантируется даже в контрольных точках, так как операционная система может (имеет полное право) записать страницы с мета-данными раньше страниц данных.
- Таким образом, исходный LMDB движок в OpenLDAP:
- В реальности оказывается непригодным для промышленной эксплуатации в условиях высокой нагрузки по-записи.
- Для устранения этих и многих других проблем мы и стартовали ReOpenLDAP как отдельный проект в начале 2015 года.
- Сейчас в ReOpenLDAP:
- 2014-Q3: Реализован возможность автоматического формирования контрольных точек как по объему изменений, так и периодически с гранулярностью до секунды. Что позволило использовать режимы dbnosync и mapasync с гораздо меньше вероятностью потери данных в случае системного сбоя.
- 2014-Q4: Реализован, отлажен и проверен режим повторного использования (aka reclaiming) страниц базы данных в LIFO-порядке. Что позволило получить эффект от кэша обратной записи в развитых системах хранения, что дало прирост производительности в 10-50 раз (в некоторых сценариях до 100 и более раз). Реализованы механизмы oom-handler (поведение при исчерпании места в БД) и dreamcatcher (рестарт долгих операций чтения мешающих освобождению места).
- 2015-Q1: Устранена масса проблем в механизме репликации при работе в multi-master режиме, в том числе несколько застарелых проблем с возрастом более 5 лет.
- 2015-Q2: Реализованы возможности "кворума" при репликации, ограничение сеансов syncrepl в фазе refresh, что в разы снизило пиковое потребления механизмом репликации оперативной памяти и процессорного времени.
- На днях устранены вышеописанные проблемы с согласованностью данных и добавлена утилита mdb_chk для максимально полной проверки структуры базы.
- Таким образом, в ReOpenLDAP устранены все известные на текущий момент проблемы и недоработки, мешающие промышленной эксплуатации в условиях высоких нагрузок, как по-чтению, так и по-записи (но приемочные испытания перед "боевой работой" еще не завершены).
Технические детали доработок для обеспечения согласованности данных:- Чистка кода и прекращение поддержки:
- В LMDB отброшена поддержка не-POSIX платформ, включая Windows.
- Самой "старой" эталонной поддерживаемой платформой считается RedHad Enterprise Linux 6, требуется поддержка PTHREAD_PROCESS_SHARED и PTHREAD_MUTEX_ROBUST.
- Ликвидирована поддержка нерелевантного режима работы, при котором разделение доступа обеспечивается приложением (выброшен флажок MDB_NOLOCK).
- Полностью переработан (переписан код) путь сброса данных на диск:
- Появилась возможность гарантировать последовательность (линерализуемость) обновлений мета-страниц относительно страниц с данными.
- Теперь возможно полностью контролировать режим фиксации на диске каждой транзакции.
- Гарантируется правильная работа на системах с багом без дополнительной потери производительности.
- В meta-страницы добавлен признак о том, как данные были зафиксированы на диске - надежно (steady) или по-быстрому (weak):
- При "быстрой" записи в режимах dbnosync, writemap и mapasync обновляемая meta-страница помечается "не-надежной" (weak).
- При надежной записи сначала всегда полностью сохраняются страницы с данными, а затем обновляются и записывается meta-страница помечаемая "надежной" (steady).
- Крайне важно, что этот порядок гарантируется всегда, в том числе и для режимом writemap и mapasync. Этим устраняется проблема №1.
- Фиксация состояния базы и откат (rollback) потенциально несогласованных данных:
- При штатном (не аварийном) закрытии базы, в контрольных точках, а также после каждой транзакции в "синхронных" режимах выполняется надежная фиксация всех изменений на диске.
- При открытии базы происходит автоматический возврат к последней из надежно зафиксированных точек.
- Повторное использование страниц и поведение при исчерпании доступных:
- Переработка записей таблицы freeDB (aka reclaiming) не пересекает границу последней надежной фиксации данных. Этим устраняется проблема №2.
- В ситуации исчерпания доступных страниц и наличия незафиксированных данных производится их надежная фиксация, что позволяет переработать "заблокированные" записи freeDB.
- В ситуации исчерпания доступных страниц из-за их блокировки долгими операциями чтения, как и прежде, доступны oom-handler и dreamcatcher.
Как последние доработки меняют поведение:- В любом из "синхронных" режимов фиксации транзакций всё будет как раньше.
- В процессе работы, при асинхронной записи (режимы dbnosync или mapasync) и ВЫКЛЮЧЕННЫХ checkpoint, внешне будет почти как раньше:
- Никакой явной фиксации не будет, до тех пор пока не будут израсходованы доступные страницы.
- Повторное использование страниц (aka reclaiming) "упрется" в последнюю надежную фиксацию и будет приостановлено.
- При исчерпании доступных страниц будет сформирована надежная контрольная точка и повторное использование страниц продолжится до этой границы.
- Так как асинхронная запись в общем случае будет выполняться ядром ОС, то в совокупности мы получим максимальную производительность по-записи с периодической гарантией согласованности данных на диске.
- В процессе работы, при асинхронной записи (режимы dbnosync или mapasync) и ВКЛЮЧЕННЫХ checkpoint:
- Согласно параметрам checkpoint будет выполняться надежная фиксация с гарантией согласованности данных на диске.
- Плюс контрольные точки будут дополнительно формироваться при исчерпании доступных страниц, как описано выше.
- По завершению работы, в режимах без синхронной записи (envflags: dbnosync или mapasync):
- Если база будет закрыта штатно (без "срубания" или "падения" slapd, и без system wide failure), то гарантируется согласованность данных на диске.
- Если же slapd будет "срублен" или "упадет", либо будет обще-системный сбой, то потеряются все изменения после последней надежной записи при формировании checkpoint или из-за исчерпания свободных страниц.
Актуальная версия доступна в ветке
master на github.