Dev48
ЯЗЫК
  • О нас
  • Услуги
  • Индустрии
  • Технологии
  • Статьи
  • Контакты
Забронировать звонок
    Главная/Статьи/Upravlenie pereindeksatsiey elasticsearch v masshtabnyh sistemah proizvoditelnos
Dev48

© 2026 · All rights reserved.

Управление переиндексацией Elasticsearch в масштабных системах: производительность, надежность и наблюдаемость

Источник: Medium

Управление переиндексацией Elasticsearch в масштабных системах: производительность, надежность и наблюдаемость

Источник: Medium

Примечание редактора: Это четвертая статья в серии, посвященной тому, как Palantir кастомизирует инфраструктурное ПО для надежной работы в масштабе. Ниже публикуется гостевой материал в рамках серии Foundations от команды Gotham Core Platform, которая создает и поддерживает фундамент для критически важных приложений в экосистеме Gotham. Автором этого блог-поста является Кевин Лианг (Kevin Liang), бэкенд-разработчик

25 сентября 2026 г.

14 мин на чтение

8 июня 2026 г.

Нажмите Enter или кликните для просмотра изображения в полном размере

Примечание редактора: Это четвертая статья в серии, посвященной тому, как Palantir кастомизирует инфраструктурное ПО для надежной работы в масштабе.

Ниже публикуется гостевой материал в рамках серии Foundations от команды Gotham Core Platform, которая создает и поддерживает фундамент для критически важных приложений в экосистеме Gotham. Автором этого блог-поста является Кевин Лианг (Kevin Liang), бэкенд-разработчик из Калифорнии. В статье рассматриваются архитектурные соображения и улучшения, внесенные в механизм переиндексации Elasticsearch, который в целом призван предоставить простой в использовании, производительный, надежный и наблюдаемый способ восстановления и перестройки поисковых индексов для бэкенд-приложений. Цель этой публикации двоякая: поделиться нашими проектными решениями и опытом с более широким техническим сообществом, а также пролить свет на то, как выглядит типичная работа системного бэкенд-инженера в команде Gotham Core Platform в Palantir.

Поиск — один из наиболее активно используемых рабочих процессов во всей экосистеме Palantir Gotham. Пользователи постоянно выполняют запросы, фильтруют и детализируют большие наборы данных для выявления сущностей, отслеживания связей и формирования аналитических материалов, которые лежат в основе важнейших операционных решений. На любом этапе этого процесса они ожидают мгновенных результатов, независимо от масштаба или сложности базового графа данных.

Многие из этих поисковых процессов используют Elasticsearch — распределенный поисковый и аналитический движок с открытым исходным кодом, который обеспечивает надежные возможности полнотекстового поиска в больших масштабах. Ранее мы уже объясняли роль Elasticsearch в нашей более широкой экосистеме и архитектуре. Подробнее об этом можно прочитать в статье «Защитные базы данных: оптимизация семантики обновления индексов» (Defensive Databases: Optimizing Index-Refresh Semantics).

Как отмечалось в том блог-посте, большинство приложений Gotham взаимодействуют с Elasticsearch через собственную клиентскую службу базы данных, которая служит прослойкой между бэкенд-сервисами и инфраструктурой хранения. На высоком уровне эта служба напоминает хранилище документов и обеспечивает:

  • Строго согласованные операции CRUD «ключ-значение», поддерживаемые транзакционной базой данных, которая остается авторитетным источником истины (source of truth).
  • Полнотекстовый поиск по полям документов с помощью Elasticsearch, который функционирует как «внешний» вторичный индекс.
  • Встроенное на фундаментальном уровне принудительное применение политик безопасности для основных путей чтения, поиска и записи, а не просто добавленное задним числом.

В дальнейшем мы будем называть эту собственную клиентскую службу базы данных «хранилищем документов». Хранилище документов обслуживает множество различных клиентов, каждый из которых имеет собственную группу схем (аналогичных таблицам в базе данных). Каждая схема определяет имена полей, типы, правила безопасности, структурную макетную разметку документов и, что критически важно, то, должен ли поле индексироваться в Elasticsearch и каким образом, с помощью так называемых маппингов (mappings). Некоторые схемы вообще не индексируются; другие содержат богатые маппинги, обеспечивающие фасетный поиск, геозапросы и фильтры по диапазонам дат. Вы можете подробнее прочитать о маппингах Elasticsearch в их официальной документации здесь.

Поток данных от различных бэкендов приложений в базу данных, Elasticsearch и службу аутентификации проиллюстрирован на следующей схеме, которая является расширенным вариантом диаграммы из блог-поста о защитных базах данных.

Нажмите Enter или кликните для просмотра изображения в полном размере

Хотя группа Foundations в Palantir отвечает за эксплуатацию и предоставление кластеров Elasticsearch для нашего разнообразного парка развертываний, службы, взаимодействующие с этой инфраструктурой, также несут ответственность за эффективное и ответственное использование кластеров и поддержание в актуальном состоянии собственных индексов.

Бывают также ситуации, когда службе необходимо восстановить или перестроить индексы Elasticsearch. Когда индекс устаревает или переходит в несогласованное состояние (будь то из-за изменений маппинга или операционных сбоев), процессом устранения проблемы часто становится переиндексация.

  • Например, логистическому приложению, которому необходимо добавить новое поле для поиска данных о сбоях в цепочке поставок или поддержать дополнительное поле метаданных безопасности в политике доступа, потребуется переиндексация.
  • Переиндексация также может применяться на уровне кластера. Например, при миграции с Elasticsearch 8.x на 9.x мы предпочитаем переиндексацию обновлению на месте (in-place upgrade), поскольку она позволяет нам быстро выполнить откат в случае возникновения проблем.

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

Что нам необходимо

Как упоминалось ранее, переиндексация может потребоваться по нескольким причинам. Схемы и их маппинги эволюционируют вместе с нашими продуктами, настройки индексов (включая количество шардов) могут изменяться, а индексы могут повреждаться из-за непредвиденных сбоев или ошибок в программном обеспечении. В таких случаях необходимо создать новый индекс с правильными маппингами и обновленными настройками, наполнить его данными и подменить. Кроме того, когда нам требуется миграция между кластерами — например, при обновлении версий (скажем, с Elasticsearch 8.x на 9.x) или при переходе на автономный кластер вместо совместного использования с другими службами, когда это оправдано пропускной способностью, — нам нужно выполнить межкластерную переиндексацию.

Elasticsearch действительно предлагает API _reindex, который копирует документы из одного индекса в другой в пределах одного кластера, а также позволяет использовать удаленный кластер в качестве источника для переиндексации. Однако, поскольку в нашей архитектуре база данных является первичным источником истины со строгой согласованностью, выполняемая нами переиндексация будет заново наполнять новый индекс документами, загруженными непосредственно из базы данных. Это означает, что наша служба хранилища документов должна будет сама оркестровать и контролировать весь процесс переиндексации, а не просто отправлять команду и позволять кластеру Elasticsearch разбираться со всем остальным.

Требования к нашему механизму переиндексации Elasticsearch следующие:

1. Реконструкция с учетом схем: Система должна знать, как строить индексы для каждой клиентской схемы — типы полей, анализаторы, количество шардов и т. д.

2. Минимум ручных действий: Операторам не нужно вручную сопровождать каждую схему на всех этапах процесса. Управление переиндексацией в сотен развертываний, каждое из которых содержит более 100 схем, — это просто слишком большой объем работы для выполнения вручную.

3. Автоматическое обнаружение и устранение несогласованностей: Система должна уметь самостоятельно определять, когда для конкретной схемы необходима переиндексация, и выполнять ее автономно.

4. Ограниченное использование ресурсов: Переиндексация не должна уронить сервер или препятствовать обработке API-запросов. Она не может монополизировать память, исчерпывать пул потоков или насыщать пул соединений с базой данных.

5. Онлайн-переиндексация в реальном времени: Служба обслуживает реальный трафик все это время, включая поиск. В контексте нашего логистического приложения существующие поисковые функции должны продолжать работать.

Наша первая система переиндексации

Учитывая все требования, мы внедрили первый механизм переиндексации Elasticsearch в хранилище документов. На следующей схеме показан процесс переиндексации определенной схемы.

Нажмите клавишу Enter или щелкните, чтобы просмотреть изображение в полном размере

Теневой индекс

Наше примерное приложение должно продолжать обрабатывать поисковые запросы во время и после переиндексации. Ключом к поддержанию работоспособности во время переиндексации является теневой индекс — отдельный физический индекс в том же кластере Elasticsearch для той же схемы с требуемыми маппингами и настройками, который получает все запросы индексации / удаления из индекса от клиентского API хранилища документов, одновременно наполняясь данными механизмом переиндексации. Крайне важно, что теневой индекс пока не обслуживает операции чтения. Механизм переиндексации создаст теневой индекс с суффиксом _b, если текущий индекс заканчивается на _a (и наоборот), с предполагаемым маппингом и настройками на момент запуска, а также выполнит первичное наполнение документами из базы данных. По завершении механизм назначит теневой индекс в качестве первичного и удалит предыдущий индекс.

Поиск всегда обслуживается из первичного индекса, а запросы на запись из API дублируются как в первичный, так и в теневой индекс, чтобы не потерять последние изменения. Мы используем примитив оптимистичного контроля параллелизма, предоставляемый Elasticsearch (version_type.external_gte), для разрешения конфликтов при одновременной записи в индекс из API и из механизма переиндексации.

Что касается маршрутизации запросов чтения и записи, вместо прямого обращения к именам физических индексов мы используем псевдонимы (aliases) индексов Elasticsearch в путях кода чтения, записи и переиндексации. Сопоставления между псевдонимами и физическими индексами устанавливаются или изменяются только во время создания индекса и после операций переиндексации.

В следующей таблице показаны изменения псевдонимов, затрагивающие теневой индекс (_b) и существующий первичный индекс (_a) на ключевых этапах переиндексации. В этом примере индекс _b был создан и помечен псевдонимом переиндексации в самом начале процесса. За индексом _a сохранился псевдоним чтения, в то время как псевдоним записи был удален. Когда фаза наполнения данных переиндексации завершается, индекс _b становится первичным, получая псевдонимы чтения и записи, в то время как индекс _a удаляется.

Нажмите клавишу Enter или щелкните, чтобы просмотреть изображение в полном размере

Оркестрация переиндексации

Механизм переиндексации поддерживает таблицу метаданных индекса на уровне схем для отслеживания информации, связанной с выполнением заданий переиндексации, например: когда схема в последний раз запускалась / успешно завершалась / завершалась с ошибкой, находится ли схема в очереди, выполняется ли для нее переиндексация, прерывается ли она или нет работы. Метаданные индекса на уровне схем являются единственным источником правды для координации внутри механизма переиндексации.

Будучи фоновой задачей на сервере, механизм переиндексации периодически сканирует все определения схем, сравнивает метаданные, сохраненные в базе данных, с актуальным состоянием индекса в кластере Elasticsearch и определяет, какие схемы требуют внимания: продолжение текущей переиндексации, запуск следующей из очереди или попытка восстановления несогласованного индекса схемы перед постановкой его в очередь на полную переиндексацию, если восстановления оказалось недостаточно.

Помимо упреждающей переиндексации для схем, индексы которых требуют восстановления, отдельная фоновая задача, обрабатывающая запросы из конфигурации, а также несколько конечных точек административного API позволяют операторам и клиентам (включая наше логистическое приложение в примере) запрашивать и прерывать переиндексацию.

Независимость от кластера

Ключевым архитектурным выбором для службы хранилища документов является независимость от конкретного кластера. Кластеры Elasticsearch обнаруживаются и сопоставляются с логическими компонентами в коде. В большинстве случаев имеется один кластер, но во время межкластерной переиндексации подключается дополнительный миграционный кластер, который распознается как таковой. Через динамический уровень операции чтения обслуживаются только из первичного кластера, в то время как операции записи (включая переиндексацию) распределяются по всем подключенным кластерам, поддерживая как однокластерные, так и межкластерные операции с минимальным объемом дополнительного кода.

Получайте статьи Palantir на свою электронную почту

Присоединяйтесь к Medium бесплатно, чтобы получать обновления от этого автора.

Запомнить меня для более быстрого входа

С помощью этого базового дизайна мы можем выполнять переиндексацию любых схем в хранилище документов. Наше логистическое примерное приложение может включить переиндексацию в обновление своей схемы и заблокировать новую функцию поиска до завершения переиндексации.

Эволюция механизма переиндексации

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

Параллелизация и асинхронная обработка

Параллелизация была заложена в механизм переиндексации на ранних этапах, поскольку как чтение страниц документов из базы данных, так и их индексация в поисковой системе связаны со значительным ожиданием операций ввода-вывода. Решением является параллельный исполнитель заданий, поддерживаемый настраиваемым пулом потоков и ограниченной очередью промежуточного хранения. Потоки-воркеры динамически принимают на себя одну из двух ролей на каждой итерации: поток, получающий блокировку страничного чтения, загружает следующую пачку записей в очередь, в то время как потоки, обнаружившие, что блокировка занята, забирают уже поставленную в очередь пачку и выполняют работу по индексации. Отдельный фоновый поток периодически фиксирует прогресс, записывая позицию самой ранней незавершенной пачки, что позволяет задаче возобновить работу с того места, где она остановилась после сбоя. Такая схема создает конвейер, в котором одновременно обрабатывается несколько пачек — одни считываются из базы данных, другие индексируются, — без необходимости явного назначения ролей или блокировки цикла переиндексации.

На приведенной ниже схеме показана структура параллельного исполнителя заданий.

Нажмите клавишу Enter или щелкните, чтобы просмотреть изображение в полном размере

Ограничение размера пачек

Чтобы предотвратить падение хранилища документов из-за переиндексации, мы добавили множество возможностей ограничения частоты и размера пачек вокруг механизма переиндексации. Один запуск переиндексации ограничен по трем измерениям:

  • Количество документов в пачке: ограничивает количество объектов, извлекаемых из базы данных за одну транзакцию, сокращая время удержания соединения с базой данных.
  • Память на пачку: мягкое ограничение объема памяти, занимаемого одной пачкой, предотвращающее неожиданные всплески потребления памяти, вызванные крупными документами при жестком лимите размера пачки.
  • Всего пачек за запуск: ограничивает количество пачек, которые обрабатывает один вызов цикла переиндексации до передачи управления. В сочетании с настраиваемым интервалом отдыха между запусками это создает естественные паузы для потоков обработки API и сборщика мусора.

Эти три параметра взаимодействуют друг с другом, не позволяя ни одному из измерений стать узким местом. Схема со множеством мелких документов упирается в лимит количества документов; схема с меньшим количеством, но более крупными документами упирается в лимит памяти; а лимит пакетов за один запуск гарантирует, что процесс переиндексации будет периодически приостанавливаться независимо ни от чего.

Безопасность при сбоях

Представьте, если бы сервер хранилища документов дал сбой посреди операции, изменяющей индексы и псевдонимы — например, во время запуска или завершения переиндексации для нашего логистического приложения. Индексы могли бы остаться в поврежденном состоянии, из которого невозможно детерминированное восстановление без перезапуска всей переиндексации с нуля. Чтобы защититься от этого, каждая операция жизненного цикла индекса моделируется как детальный конечный автомат: перед отправкой любого изменения в поисковый движок текущее состояние сохраняется в базу данных, а каждая операция поискового движка проектируется как идеопотентная. Если сервер аварийно завершает работу в любой момент, он просто возобновляет работу с последнего сохраненного состояния и безопасно повторно выполняет ожидающую операцию.

Состояния, показанные ниже, сохраняются в отдельной таблице метаданных для каждого кластера и каждой схемы, где мы также сохраняем ключевые параметры, такие как текущий первичный индекс для обеспечения безопасности при сбоях.

Нажмите Enter или кликните для просмотра изображения в полном размере

Логов? Метрик? Или диагностики? Да.

Когда фоновый процесс молча перестраивает индексы, включающие миллионы документов, наблюдаемость не подлежит обсуждению. Разнообразные и часто ограниченные среды, в которых развертываются продукты Palantir, также означают, что жизнеспособность и доступность различных форм наблюдаемости сильно различаются в разных развертываниях. Нельзя внедрить задним числом ту наблюдаемость, которая вам нужна, когда что-то идет не так. Не говоря уже о том, что у разных форм наблюдаемости есть свои плюсы и минусы, и мы хотели бы получить лучшее из всех миров.

Логи:

  • Плюсы: показывают снимки состояния с временными метками и богатым набором параметров, отлично подходят для отслеживания точных шагов и изучения детальных состояний на каждом шаге.
  • Минусы: могут быть слишком «шумными» и занимать избыточное дисковое пространство, если параметры содержат слишком много информации; хотя логи полезны для расследования постфактум, и мы хотели бы иметь исчерпывающие логи во время анализа первопричин, большую часть времени логи и их параметры просто не используются.

Метрики:

  • Плюсы: идеальный, легковесный инструмент для отслеживания изменений состояний и прогресса с течением времени, который можно превратить в удобные визуализации на дашбордах для быстрого получения аналитических выводов и агрегированного анализа.
  • Минусы: не содержат дополнительной информации за пределами самих временных рядов и тегов, то есть не имеют дополнительных параметров.

Диагностика (по запросу, разовые отчеты, генерируемые по требованию, часто используемые на Palantir Apollo):

  • Плюсы: могут быть настолько подробными, насколько нам это необходимо (в разумных пределах, конечно), без необходимости беспокоиться о «засорении» или дисковом пространстве, учитывая, что они создаются по запросу.
  • Минусы: часто представляют собой снимок (если специально не спроектированы для отражения исторических событий) на момент их запроса, что делает их менее полезными для анализа постфактум.

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

Обработка межкластерной переиндексации

Вспомните из наших предыдущих примеров, что переиндексация может быть вызвана причинами, выходящими за рамки изменений на уровне приложений. Межкластерные миграции — перенос поискового трафика службы из одного кластера Elasticsearch в другой без простоя — являются суровой реальностью на крупномасштабной платформе. Например, если мы хотим перейти с Elasticsearch 8.x на 9.x, сохранив при этом возможность отката в любой момент, нам потребуется реализовать миграцию с помощью переиндексации.

В архитектуре механизма переиндексации, которую мы рассмотрели до сих пор и которая нацелена на восстановление первичного кластера Elasticsearch, обслуживающего запросы, мы создаем новый индекс как теневой индекс в том же кластере, который затем перестраивается из первичного хранилища. Когда бэкфиллинг завершен, теневой индекс продвигается для поиска. Хотя межкластерная переиндексация концептуально похожа на обычную, она требует немного другого подхода. В частности, нам нужно убедиться, что новый индекс находится в другом кластере, отличном от кластера, в котором размещен старый индекс, и пропустить удаление старых индексов по завершении переиндексации, так как в новом кластере удалять нечего, а индексы в старом кластере мы хотим сохранить на случай необходимости отката.

Отдельный механизм переиндексации для миграции

Мы решили оставить два механизма переиндексации раздельными, каждый из которых управляет переиндексацией на основе метаданных, привязанных к соответствующему кластеру Elasticsearch. Основной механизм переиндексации, который мы до сих пор рассматривали в этой статье, работает с первичным кластером и служит для восстановления активных индексов, обрабатывающих запросы API. Новый механизм миграционной переиндексации, с другой стороны, выполняет бэкфиллинг кластера миграции и подготавливает его к тому, чтобы стать новым первичным кластером. Создание двух отдельных механизмов переиндексации упрощает настройку, управление метаданными, читаемость кода и наблюдаемость по сравнению с единым механизмом переиндексации, наполненным логикой ветвления для конкретных кластеров. Каждый механизм переиндексации будет иметь собственную конфигурацию: количество потоков, размеры пакетов, лимиты памяти, интервал расписания и т.д., и работать как независимые фоновые задачи, взаимодействуя только со своим собственным кластером, а не со всеми подключенными кластерами.

Каждый механизм переиндексации применяет различные эволюции индексов и псевдонимов, адаптированные под свой вариант использования:

Эволюция индексов и псевдонимов в основном механизме переиндексации (так же, как и раньше)

Нажмите Enter или кликните для просмотра изображения в полном размере

Эволюция индексов и псевдонимов в механизме миграционной переиндексации

Нажмите Enter или кликните для просмотра изображения в полном размере

На следующей диаграмме показано сравнение активных индексов в соответствующих кластерах при переиндексации для первичного кластера и при проведении межкластерной переиндексации в целях миграции.

Нажмите Enter или кликните для просмотра изображения в полном размере

Москва не сразу строилась

С годами многие инженеры Palantir работали над обеспечением первоклассного поиска, внося множество улучшений в механизмы переиндексации в службе хранения документов Gotham. Получаемый в процессе работы опыт как с технической, так и с эксплуатационной точек зрения продолжает стимулировать усовершенствования всей системы переиндексации Elasticsearch. Многие из тех же выводов, касающихся наблюдаемости и все более проактивных методов поддержки, лягут в основу проектирования будущих программных продуктов — в рамках разработки Foundry, AIP, Gotham и Apollo — которые взаимодействуют со слоями инфраструктуры Palantir. Ни один продукт никогда не достигает совершенства, но в Palantir мы стремимся постоянно учиться на каждом вызове и каждом операционном результате, используя эти инсайты в качестве топлива для дальнейшего совершенствования наших продуктов. Наша цель — не просто предоставлять мощные возможности, но и обеспечивать высочайший уровень стабильности и надежности для наших пользователей.

Если это похоже на тот тип проектов и масштаб задач, которые вам интересны, ознакомьтесь с нашими актуальными вакансиями сегодня: https://www.palantir.com/careers/open-positions/

← Все статьи