Оптимізація переіндексації Elasticsearch для 1С-Бітрікс

Наша компанія займається розробкою, підтримкою та обслуговуванням рішень на Бітрікс та Бітрікс24 будь-якої складності. Від простих односторінкових сайтів до складних інтернет-магазинів, CRM систем з інтеграцією 1С та телефонії. Досвід розробників підтверджено сертифікатами від вендора.
Пропоновані послуги
Показано 1 з 1 послугУсі 1626 послуг
Оптимізація переіндексації Elasticsearch для 1С-Бітрікс
Середня
~1-2 тижні
Часті питання

Наші компетенції:

Етапи розробки

Останні роботи

  • image_website-b2b-advance_0.png
    Розробка сайту компанії B2B ADVANCE
    1262
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Розробка веб-сайту для компанії ФІКСПЕР
    851
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Розробка на базі Бітрікс, Бітрікс24, 1С для компанії Development of an Online
    585
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Розробка на базі 1С Підприємство для компанії МИРСАНБЕЛ
    751
  • image_crm_dolbimby_434_0.webp
    Розробка сайту на CRM Бітрікс24 для компанії DOLBIMBY
    657
  • image_crm_technotorgcomplex_453_0.webp
    Розробка на базі Бітрікс24 для компанії ТЕХНОТОРГКОМПЛЕКС
    989

Оптимізація переіндексації Elasticsearch для 1С-Бітрікс

Оптимізація переіндексації Elasticsearch для 1С-Бітрікс

На проекті з 800 000 SKU планова переіндексація з 1С займала 14 годин. За цей час накопичувалася черга змін, пошук віддавав застарілі дані, а імпорт з 1С конкурував з переіндексацією за ресурси. Завдання — скоротити повну переіндексацію до 1–2 годин без зупинки пошуку.

Чому переіндексація гальмує

Типові причини повільної переіндексації:

Послідовна індексація через одиночні запити. Кожен документ надсилається окремим PUT /bitrix_catalog/_doc/{id}. HTTP-накладні витрати, TCP-з'єднання на кожен запит, відповідь 200ms * 800000 = 160000 секунд.

Занадто маленький batch у Bulk API. Розмір пакета 10 документів замість оптимальних 200–1000.

Refresh після кожного пакета. Примусовий POST /bitrix_catalog/_refresh після кожного batch — самогубство продуктивності. Refresh створює новий сегмент Lucene, блокує індексацію на десятки мілісекунд.

Неправильний refresh_interval під час переіндексації. Дефолтні 1 секунда генерують сотні тисяч дрібних сегментів, які ES витрачає сили на merge.

Стратегія zero-downtime переіндексації

Ключовий прийом — індексувати в новий індекс, а не поверх робочого:

Поточний: bitrix_catalog_v1  <-- аліас bitrix_catalog
Новий:    bitrix_catalog_v2  <-- індексуємо сюди
Після:    перемикаємо аліас на v2
// Створюємо аліас при початковому налаштуванні
POST /_aliases
{
  "actions": [
    { "add": { "index": "bitrix_catalog_v1", "alias": "bitrix_catalog" } }
  ]
}

Бітрікс працює з аліасом bitrix_catalog. Поки йде переіндексація в v2, пошук продовжує працювати через v1. Після завершення атомарно перемикаємо аліас.

Налаштування Elasticsearch для швидкої індексації

Перед переіндексацією тимчасово змінюємо налаштування через API:

PUT /bitrix_catalog_v2/_settings
{
  "index": {
    "refresh_interval": "-1",
    "number_of_replicas": 0,
    "translog.durability": "async",
    "translog.sync_interval": "30s"
  }
}

refresh_interval: -1 повністю вимикає автоматичний refresh — документи не потрапляють в пошук до явного refresh, зате індексація прискорюється в 3–5 разів.

number_of_replicas: 0 вимикає реплікацію на час індексації. ES не витрачає час на копіювання шардів.

translog.durability: async — транслог скидається на диск не при кожній операції, а за таймером. Ризик втрати даних при збої за останні 30 секунд — прийнятно для переіндексації, не для продакшн-даних.

Після завершення відновлюємо налаштування:

PUT /bitrix_catalog_v2/_settings
{
  "index": {
    "refresh_interval": "5s",
    "number_of_replicas": 1,
    "translog.durability": "request"
  }
}

Потім примусовий merge для зменшення кількості сегментів:

POST /bitrix_catalog_v2/_forcemerge?max_num_segments=1

Оптимізація PHP-індексатора

Розмір пакета для Bulk API підбираємо емпірично. Орієнтир — 5–15 МБ на один запит:

$batchSize = 500; // документів на один bulk-запит
$bulk = [];

foreach ($products as $product) {
    $bulk[] = ['index' => ['_index' => 'bitrix_catalog_v2', '_id' => $product['ID']]];
    $bulk[] = buildDocument($product);

    if (count($bulk) >= $batchSize * 2) {
        $client->bulk(['body' => $bulk]);
        $bulk = [];
        // НЕ викликаємо _refresh тут
    }
}

if (!empty($bulk)) {
    $client->bulk(['body' => $bulk]);
}

Паралельна індексація через кілька процесів — ділимо каталог за діапазонами ID:

# Процес 1: ID 1 - 200000
php index_products.php --from=1 --to=200000 &

# Процес 2: ID 200001 - 400000
php index_products.php --from=200001 --to=400000 &

# Процес 3: ID 400001 - 600000
php index_products.php --from=400001 --to=600000 &

wait
echo "Indexing complete"

Три паралельних процеси на 3-нодовому кластері дають лінійне прискорення. Обмеження — пропускна здатність MySQL при читанні даних.

Перемикання аліасу

Після завершення індексації атомарно перемикаємо аліас:

POST /_aliases
{
  "actions": [
    { "remove": { "index": "bitrix_catalog_v1", "alias": "bitrix_catalog" } },
    { "add":    { "index": "bitrix_catalog_v2", "alias": "bitrix_catalog" } }
  ]
}

Операція атомарна — між видаленням старого аліасу і додаванням нового немає моменту, коли аліас не існує. Перемикання займає мілісекунди, пошук не переривається.

Результат

На каталозі 800к SKU після оптимізації: повна переіндексація 1 год 20 хв (було 14 год), інкрементальне оновлення 200–300 документів на секунду через Bulk API замість 15–20 через одиночні запити.