ReOpenLDAP — сквозь тернии в «МегаФон», путь за год (Леонид Юрьев, OSSDEVCONF-2016)

Материал из 0x1.tv

Аннотация

Докладчик
Леонид Юрьев.jpg
Леонид Юрьев

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

За два года проект выведен «на орбиту» высоконагруженной промышленной эксплуатации. Сейчас ReOpenLDAP успешно работает во всех филиалах ПАО МегаФон по всей России и одновременно доступен как OpenSource.

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

Видео

on youtube

Слайды

ReOpenLDAP — сквозь тернии в «МегаФон», путь за год (Леонид Юрьев, OSSDEVCONF-2016).pdf ReOpenLDAP — сквозь тернии в «МегаФон», путь за год (Леонид Юрьев, OSSDEVCONF-2016).pdf ReOpenLDAP — сквозь тернии в «МегаФон», путь за год (Леонид Юрьев, OSSDEVCONF-2016).pdf ReOpenLDAP — сквозь тернии в «МегаФон», путь за год (Леонид Юрьев, OSSDEVCONF-2016).pdf ReOpenLDAP — сквозь тернии в «МегаФон», путь за год (Леонид Юрьев, OSSDEVCONF-2016).pdf ReOpenLDAP — сквозь тернии в «МегаФон», путь за год (Леонид Юрьев, OSSDEVCONF-2016).pdf ReOpenLDAP — сквозь тернии в «МегаФон», путь за год (Леонид Юрьев, OSSDEVCONF-2016).pdf ReOpenLDAP — сквозь тернии в «МегаФон», путь за год (Леонид Юрьев, OSSDEVCONF-2016).pdf

Расширенные тезисы

Кратко

Хочу кратко напомнить, как мы пришли к разработке собственно клона общеизвестного OpenLDAP. Затем рассказать, что было сделано в нашем проекте, с акцентом на последний год.

Если говорить о результате, то тесты и опыт эксплуатации позволяют сделать вывод, что наш ReOpenLDAP — один из немногих годных к высоконагруженной промышленной эксплуатации (возможно, единственный).

Предыстория

Примерно в 2013 году Петер-Сервис приступил к разработке одной из подсистем (NGDR) для инфраструктуры «МегаФона». Один из вариантов реализации предполагал использование высокопроизводительного LDAP-сервера.

Следует отметить, что сценарий использования, а особенно расчётные нагрузки, совершенно не соответствовали традиционным режимам работы LDAP-серверов. Например, предполагаемые 10 тысяч обновлений в секунду на 1–2 порядка превышают то, что может обеспечить большинство LDAP-серверов.

Среди вариантов, конечно, также рассматривались предназначенные для таких сценариев «чемпионские» key-value хранилища, как например tarantool.org. Однако парадигма LDAP и сам протокол очень любимы в телеком-отрасли. Соответственно использование любого не-LDAP-хранилища в скором времени потребовало бы реализации к нему доступа посредством LDAP. Поэтому всё-таки решили попробовать все доступные LDAP-серверы.

В процессе тестов быстро выяснилось, что необходимую производительность даёт только общеизвестный OpenLDAP. При этом крайне важным было то, что нагрузка по записи не приводила к деградации производительности по чтению, и в основном ограничивалась производительностью дисков. Это принципиальное отличие, как и производительность, хорошо объяснялись свойствами движка хранения LMDB.

OpenLDAP также поддерживает синхронизацию содержимого каталога, в том числе в «горячем» режиме, включая топологию multi-master. Массовость использования и 25-летняя история открытого проекта позволяли надеяться, что проблем со стабильностью не будет. По совокупности факторов мы опрометчиво решили закрыть глаза на однократное падение OpenLDAP в процессе наших предварительных тестов. Летом 2014 года разрабатываемая подсистема была включена в тестовую эксплуатацию…

Стоит отметить, что изначально Петер-Сервис не собирался «чинить» OpenLDAP своими силами и тем более делать клон проекта. При первых проблемах компания обратилась за коммерческой поддержкой в Symas Corp. Однако Symas Corp не решилась взять обязательства с фиксированием каких-либо сроков и неустойкой за их несоблюдение.

Исходные проблемы

Для понимания контекста следует сказать пару слов о целевой среде: «NGDR представляет собой UDR (User Data Repository), согласно стандарту 3GPP 23.335, и является централизованным узлом для хранения данных обо всех видах услуг абонентов в ИТ-инфраструктуре оператора связи», см. bit.ly/2d0103K

Всего шесть филиалов по России, в каждом:

  • Объём данных до 100 ГБ, от 10 до 70 миллионов записей.
  • Порядка 10 тысяч обновлений в секунду, до 50 тысяч читающих запросов в секунду.
  • Сбой при чтении — каскад сбоев в инфраструктуре, неполученная услуга, недовольство абонента и потеря прибыли оператором.
  • Сбой при записи — потеря или искажение изменений в наборе услуг и тарифных опциях.

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

Почти всегда было неясно, где искать причину. Временами приходилось переделывать все «подозрительные места», а это примерно 80% исходного кода ;)


Устраняли проблемы «послойно», по мере понимания и естественного смещения фокуса от «горим, пожар» до «хорошо бы поправить».

  1. Повреждение БД и падения внутри движка LMDB.
  2. Последствия архитектурных изъянов LMDB. Например, выполнение «ldapsearch бла-бла-бла | less» приводило к переполнению БД, отказу по записи и последующей деградации производительности до пересоздания БД.
  3. Утечки памяти, отказы в обслуживании из-за OOM.
  4. Разнообразные падения, особенно при разрыве соединений под высокой нагрузкой.
  5. Распухание базы вплоть до удвоения её физического объёма.
  6. Проблемы в механизме репликации, от потери отдельных изменений до внезапного обнуления DIR.
  7. Шатающиеся тесты, редкие сбои и падения.

Следует отметить, что для абонентов и оператора в целом эти сбои не стали катастрофой благодаря «военным» регламентам внутри «МегаФона», а также чёткой работе инженеров службы эксплуатации.

Почему «форк»?

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

  1. Первым «звоночком» была ситуация с ошибками в движке LMDB: разделяемый несколькими процессами memory-mapped файл, lock-free алгоритмы и ни одного «volatile» в исходных текстах. При этом убедить авторов в наличии ошибки удалось только показательным тестом с assert-проверкой, а до этого «мы не понимали дизайна».
  2. Затем мейнтейнеры Symas отказались принимать патчи, мотивировав отказ использованием variadic macro в одном из них. Казус будет непонятен без ряда деталей:
    1. Суммарно наши патчи устраняли почти 5000 предупреждений, большей частью безобидных, но в этом море годами оставались незамеченными реальные проблемы.
    2. Только один из патчей использовал variadic macro, тогда как остальные устраняли явные ошибки и недочёты. При этом grep по исходному коду обнаруживал variadic macro и без наших изменений.
    3. Мы не нашли платформ или систем, на которых можно было бы собрать OpenLDAP и при этом не было компилятора с поддержкой variadic macro, ни пользователей таких систем, ни информации о последних успешных проверках или сборках на таких платформах.

В результате, мы пришли к выводу что нам «нужно ехать, а не шашечки», и в первых числах 2015 года основали ReOpenLDAP. При этом отдельный форк движка LMDB не предполагался. Но осенью 2015 его пришлось сделать по техническим причинам (при подготовке к докладу на Highload++2015), а название «MDBX» было выбрано, как первый подходящий вариант.

Доработки

Рассказывать или даже просто перечислять все исправления «падений» и утечек памяти смысла нет. Поэтому только ключевые и существенные доработки, которые есть только в ReOpenLDAP или в MDBX:

В 2014 году починили то, что не давало спать:

  • Поддержка LIFO при сборке мусора и повторном использовании страниц в MDBX. Этим мы решили проблему неэффективного использования кэша обратной записи, а также устранили лишнее вымывание кэша страниц ОС. Проще говоря, при наличии BBWC производительность по записи может быть увеличена в разы. Подробно это было рассмотрено в отдельном докладе, см. highload.ru/2015/abstracts/1831.html
  • Механизм OOM-Handler в MDBX позволил смягчить (фактически нейтрализовать) проблему «зависших читателей» и устранить отказы в обслуживании из-за переполнения БД. Знатокам может показаться, что проблема решена в последних версиях OpenLDAP, так как реализован рестарт «долгих» транзакций чтения, в том числе при ожидании сети. Однако это не так — снижена лишь вероятность возникновения проблем.

В 2015 году устранили падения и замеченные системные проблемы:

  • В MDBX устранена специфическая проблема возможного разрушения БД при использовании read-write отображения в память. Может показаться странным, но оригинальный движок LMDB при некоторых обстоятельствах может безвозвратно потерять всю базу — даже если приложение периодически явно выполняет синхронизацию данных с диском.
  • Устранено сохранение лишних нормализованных значений LDAP-атрибутов, когда нормализованное и «обычное» значения равны. Эта незаметная и вроде бы безобидная ошибка на деле приводит к удвоению размера каждой записи и к пропорциональной деградации производительности в лучшем случае.
  • Поддержка «limit-concurrent-refresh», что позволяет избежать одинаковых одновременных обновлений на стороне получателя репликации и таким образом существенно ускорить синхронизацию, одновременно с уменьшением пикового потребления памяти.

За последний год

  1. Во-первых, починили репликацию:
    1. Устранение логических ошибок в механизме репликации (синхронизации содержимого), которые приводят к потере отдельных изменений:
      1. Упущены несколько проверок при обработке уведомлений.
      2. Преобразование UUID в DN-ключи при репликации может быть некорректным, из-за чего синхронизатор может удалить пересозданную запись либо перезаписать её последнее обновление старым значением.
    2. Устранение технических ошибок при формировании списка существующих записей (present list), которые приводят к полному или частичному удалению записей DIT:
      1. Может отправляться пустой present list без попыток его локального формирования, с последующим удалением всех записей на получателе репликации.
      2. Некорректная обработка ошибок при формировании present list приводит к его «обрезанию» и удалению всех упущенных записей на получателе репликации.
    3. Устранение недочёта в RFC-4533 при работе в режиме multi-master с тремя или более участниками. Есть эффект «экранирования удаления». Достаточно сложно и запутанно, но суть в том, что могут накапливаться записи, которые были удалены на одном сервере, но остались на других и уже никогда не будут удалены механизмом репликации/синхронизации. При этом обнаружить расхождение можно только «построчно», сравнив участвующие в репликации базы. Наше текущее решение сводится к дополнительной сверке данных — это не идеально, но обеспечивает совместимость с OpenLDAP и старыми версиями ReOpenLDAP, что крайне важно при промышленной эксплуатации. Подробности см. bit.ly/2d9z53B.
  2. Во-вторых, прочие важные переделки:
    1. Проверки с AddressSanitizer, ThreadSanitizer, PVS-Studio, Coverity.
    2. Поддержка TCP-keepalive для входящих соединений к серверу, в том числе к поставщику репликации (syncprov) при обслуживании persistent search запросов.
    3. Реализация «Recursive Upgradeable Read-Write Lock» с устранением ряда проблем в Config Backend.
    4. Много работы по устранению редких сбоев встроенных тестов.
    5. Слияние liblber и libldap, переход на актуальные версии Automake и Autoconf с переделкой сборки. Важно, что при этом существенно выросла готовность (прозрачность) проекта к CMake и другим инструментам.
    6. Импортированы все релевантные патчи от Red Hat, ALT Linux, Debian/Ubuntu.
  3. В-третьих, конечно, переносились все патчи из оригинальных OpenLDAP и LMDB, но порядка 20–30 % были неактуальны для ReOpenLDAP и MDBX (у нас уже исправлено).

Всего порядка 800 коммитов, из которых на портированные из OpenLDAP приходится менее 1/8.

Ближайшие задачи и планы

Вопросы с лицензией
Цель — переход на AGPL, как рабочий вариант — двойное лицензирование: исходная лицензия OpenLDAP плюс AGPL для всех наших доработок и добавлений. Сейчас мы пытаемся договориться с OpenLDAP Foundation, одновременно поняв, «как правильно». Советы и помощь приветствуются.
Верификация в Coverity и PVS-Studio
Проверка в Coverity выявила 444 «дефекта», см. scan.coverity.com/projects/reopen-reopenldap. Выглядит кошмарно, но на момент ответвления дефектов было почти в пять раз больше — поэтому на самом деле тут колоссальный прогресс. Среди этих «дефектов» основная часть — false positives, но их всё равно следует «погасить», а для этого требуется рафинирование многих функций в libreldap.
Пакетирование
К сожалению, эти задачи постоянно вытесняются более «пожарными». Поэтому тянем резину. Пока есть только сторонняя сборка rpm для Fedora/RHEL/CentOS.
Устранение редких сбоев тестов
Уже проделана огромная работа, в ходе которой выявлено и исправлено много «плавающих» ошибок. Но некоторые тесты всё-таки иногда сбоят, особенно при параллельном тестировании (высокая, но нерегулярная нагрузка, задержки из-за свопинга). Частично проблема в самих тестах, частично в ещё не выявленных ошибках.
Сравнительные тесты
Опыт, полученный при починке репликации в multi-master режиме, позволяет сделать обоснованное предположение, что в этом режиме из всех LDAP-серверов стабильно работает только наш ReOpenLDAP. Возникает желание проверить это предположение, одновременно оценив итоговую производительность.
ReOpenLDAP — сквозь тернии в «МегаФон», путь за год (Леонид Юрьев, OSSDEVCONF-2016)!.jpg

Примечания и отзывы


Plays:236   Comments:1