Розробка ETL-процесів для 1С-Бітрікс

Наша компанія займається розробкою, підтримкою та обслуговуванням рішень на Бітрікс та Бітрікс24 будь-якої складності. Від простих односторінкових сайтів до складних інтернет-магазинів, CRM систем з інтеграцією 1С та телефонії. Досвід розробників підтверджено сертифікатами від вендора.
Пропоновані послуги
Показано 1 з 1 послугУсі 1626 послуг
Розробка ETL-процесів для 1С-Бітрікс
Середня
~1-2 тижні
Часті питання
Наші компетенції:
Етапи розробки
Останні роботи
  • image_website-b2b-advance_0.png
    Розробка сайту компанії B2B ADVANCE
    1229
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Розробка веб-сайту для компанії ФІКСПЕР
    839
  • 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
    580
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Розробка на базі 1С Підприємство для компанії МИРСАНБЕЛ
    747
  • image_crm_dolbimby_434_0.webp
    Розробка сайту на CRM Бітрікс24 для компанії DOLBIMBY
    657
  • image_crm_technotorgcomplex_453_0.webp
    Розробка на базі Бітрікс24 для компанії ТЕХНОТОРГКОМПЛЕКС
    980

Розробка ETL-процесів для 1С-Бітрікс

Стандартний імпорт через адміністративну панель 1С-Бітрікс добре працює для разового завантаження каталогу. Для регулярної синхронізації із зовнішніми джерелами — ERP, 1С, складськими системами, маркетплейсами — потрібні повноцінні ETL-процеси з трансформацією даних, обробкою помилок і моніторингом. Інакше через місяць виявиться, що 3% товарів мають невірні залишки, а ніхто про це не знає.

Архітектура ETL для Бітрікс

ETL (Extract, Transform, Load) на базі 1С-Бітрікс будується навколо кількох шарів:

Extract — отримання даних із джерела. Джерела бувають:

  • Файли (CSV, XML, JSON, YML) — по FTP/SFTP або HTTP
  • REST API зовнішніх систем (1С, SAP, Salesforce)
  • БД напряму (MySQL, MSSQL, PostgreSQL) через PDO
  • Черги повідомлень (RabbitMQ, Kafka)

Transform — приведення даних до структури Бітрікс: маппінг полів, нормалізація форматів, валідація.

Load — запис у Бітрікс через D7 API або прямі SQL-запити для великих обсягів.

Завантаження товарів: продуктивність

Для завантаження товарів через стандартний API Бітрікс використовуємо \Bitrix\Iblock\ElementTable і CCatalogProduct. При завантаженні 10 000+ товарів — ключові налаштування:

// Вимикаємо непотрібні обробники на час імпорту
define('STOP_STATISTICS', true);
define('NO_AGENT_STATISTIC', 'Y');
define('DisableEventsCheck', true);

// Вимикаємо пошуковий індекс — перебудуємо наприкінці
\CSearch::DisableIndex();

// Завантаження елемента інфоблоку
$el = new \CIBlockElement();
$result = $el->Add([
    'IBLOCK_ID' => CATALOG_IBLOCK_ID,
    'NAME' => $item['name'],
    'CODE' => $item['code'],
    'ACTIVE' => 'Y',
    'PROPERTY_VALUES' => [
        'VENDOR_CODE' => $item['vendor_code'],
        'WEIGHT' => $item['weight'],
    ],
]);

При обсязі > 50 000 елементів прямий виклик CIBlockElement::Add деградує через каскад подій і оновлення пошуку. Переходимо на прямі INSERT у таблиці b_iblock_element, b_iblock_element_property, b_catalog_product з подальшим повним перебудуванням індексів.

Інкрементальна синхронізація

Повна перезапис кожні N годин — дорого. Інкрементальний ETL працює лише зі зміненими записами:

// Фіксуємо момент початку синхронізації
$syncStartTime = new \Bitrix\Main\Type\DateTime();

// Запитуємо із джерела лише змінені з часу останньої синхронізації
$changedItems = $source->getChangedSince($this->getLastSyncTime());

// Після успішної синхронізації оновлюємо мітку
$this->setLastSyncTime($syncStartTime);

Таблиця для зберігання стану синхронізації:

CREATE TABLE etl_sync_state (
    source_name VARCHAR(64) PRIMARY KEY,
    last_sync_at TIMESTAMP,
    last_sync_status VARCHAR(16), -- success/error/running
    records_processed INTEGER,
    errors_count INTEGER
);

Трансформація даних

Трансформація — найскладніша частина: у кожного джерела своя модель даних. Типові завдання:

Маппінг категорій: у джерелі може бути плоский список із полем parent_id, у Бітрікс — дерево розділів. Потрібно будувати дерево, зіставляти за кодом або створювати зі збереженням маппінгу external_id → iblock_section_id.

Нормалізація цін: джерело може давати ціну з ПДВ, без ПДВ, у різних валютах. Потрібно перераховувати з урахуванням курсів і зберігати у правильний тип ціни.

Очищення HTML: описи з 1С часто містять нечитабельне форматування. Пропускаємо через DOMDocument, видаляємо небажані теги.

Дедублікація: якщо джерело не гарантує унікальності артикулів — потрібна логіка об'єднання дублів.

Обробка помилок на рівні рядків

ETL-процес не повинен зупинятися через один невалідний запис:

foreach ($items as $item) {
    try {
        $transformed = $this->transform($item);
        $this->load($transformed);
        $this->stats->incrementSuccess();
    } catch (\Bitrix\Main\ArgumentException $e) {
        // Помилка валідації даних — логуємо і продовжуємо
        $this->logger->warning('Validation failed', [
            'external_id' => $item['id'],
            'error' => $e->getMessage(),
        ]);
        $this->stats->incrementError($item['id'], $e->getMessage());
    } catch (\Exception $e) {
        // Неочікувана помилка — логуємо і продовжуємо
        $this->logger->error('Load failed', ['item' => $item['id'], 'error' => $e->getMessage()]);
        $this->stats->incrementError($item['id'], $e->getMessage());
    }
}

Після синхронізації — звіт: скільки створено, оновлено, пропущено з помилками. Якщо помилок > 5% — алерт.

Управління пам'яттю при великих обсягах

PHP при обробці 100 000 записів легко вичерпує пам'ять. Правила:

  • Читаємо дані порціями (chunk), не завантажуємо весь файл у масив
  • Використовуємо генератори для ітерації по CSV/XML
  • Явно викликаємо unset() після обробки порції
  • Скидаємо ORM-кеш Бітрікс: \Bitrix\Main\ORM\Data\DataManager::cleanCache()
  • Стежимо за memory_get_usage() — при наближенні до ліміту пишемо в лог
// Генератор для читання великого CSV
function readCsvChunks(string $file, int $chunkSize = 500): \Generator {
    $handle = fopen($file, 'r');
    $header = fgetcsv($handle);
    $chunk = [];
    while (($row = fgetcsv($handle)) !== false) {
        $chunk[] = array_combine($header, $row);
        if (count($chunk) >= $chunkSize) {
            yield $chunk;
            $chunk = [];
        }
    }
    if ($chunk) yield $chunk;
    fclose($handle);
}

Агенти vs Cron vs Черга

Агенти Бітрікс (b_agent) — для невеликих завдань (до 1000 записів за запуск). Запускаються при зверненні до сайту, нестабільні при низькому трафіку.

Cron — надійніше для регулярних синхронізацій. Скрипт запускається незалежно від трафіку:

*/30 * * * * php -f /var/www/bitrix/etl/sync_products.php >> /var/log/etl.log 2>&1

Черга (RabbitMQ/Redis Queue) — для event-driven ETL, коли джерело публікує події змін. Дозволяє обробляти високочастотні зміни без втрат.

Моніторинг ETL

Метрика Джерело Алерт
Час останньої успішної синхронізації etl_sync_state > N годин від розкладу
Частка помилкових записів Лог синхронізації > 5%
Час виконання синхронізації Лог Перевищення планового вікна
Розбіжність кількості записів Порівняння джерела та Бітрікс > 1%

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

Етап Зміст Термін
Аналіз джерел Структура даних, формати, розклад 3–5 днів
Конектори Extract Підключення до джерел, отримання даних 1 тиждень
Трансформація Маппінг, нормалізація, валідація 1–2 тижні
Завантаження в Бітрікс API або прямий SQL, оптимізація продуктивності 1–2 тижні
Обробка помилок і моніторинг Логування, алерти, звіти 3–5 днів
Тестування Навантажувальні тести, граничні випадки 1 тиждень

Загалом: 6–12 тижнів залежно від кількості джерел і складності трансформацій.