Розробка ETL-процесів для 1С-Бітрікс
Ми часто стикаємося з ситуацією, коли стандартний імпорт через адміністративну панель 1С-Бітрікс перестає справлятися з регулярною синхронізацією. ERP, 1С, складські системи, маркетплейси — кожне джерело тягне дані у своєму форматі. Без повноцінного ETL через місяць виявляєш, що 3% товарів мають невірні залишки, а ніхто про це не знає. Ми розробляємо ETL-процеси під ключ: з трансформацією, обробкою помилок і моніторингом, щоб ви спали спокійно.
Як 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 з подальшим повним перебудуванням індексів. Це дає приріст продуктивності в 3-5 разів.
Чому інкрементальна синхронізація критична?
Повний перезапис кожні N годин — дорого і навантажує сервер. Інкрементальний ETL працює лише зі зміненими записами:
// Фіксуємо момент початку синхронізації $syncStartTime = new \Bitrix\Main\Type\DateTime(); // Запитуємо з джерела лише змінені з минулої синхронізації $changedItems = $source->getChangedSince($this->getLastSyncTime()); // Після успішної синхронізації оновлюємо мітку $this->setLastSyncTime($syncStartTime); Таблиця для зберігання стану синхронізації:
| source_name | last_sync_at | records_processed |
|---|---|---|
| 1С | 2023-12-01 12:00 | 15000 |
Трансформація даних: типові складнощі
Трансформація — найскладніша частина. Маппінг категорій: у джерелі може бути плоский список з parent_id, у Бітріксі — дерево розділів. Будуємо дерево, зіставляємо за кодом або external_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) — для event-driven ETL, коли джерело публікує події змін. Дозволяє обробляти високочастотні зміни без втрат.
Моніторинг ETL
| Метрика | Джерело | Алерт |
|---|---|---|
| Час останньої успішної синхронізації | etl_sync_state | > N годин від розкладу |
| Частка помилкових записів | Лог синхронізації | > 5% |
| Час виконання синхронізації | Лог | Перевищення планового вікна |
| Розбіжність кількості записів | Порівняння джерела та Бітрікса | > 1% |
Що входить у роботу
- Аналіз джерел: структура даних, формати, розклад
- Розробка конекторів Extract для кожного джерела
- Трансформація: маппінг, нормалізація, валідація
- Завантаження в Бітрікс: API або прямі SQL, оптимізація продуктивності
- Обробка помилок та моніторинг: логування, алерти, звіти
- Документація: опис ETL-процесу, інструкція для адміністратора
- Навчання: передача знань вашій команді
- Підтримка після запуску: гарантія стабільної роботи
Етапи розробки
| Етап | Зміст | Строк |
|---|---|---|
| Аналіз джерел | Структура даних, формати, розклад | 3–5 днів |
| Конектори Extract | Підключення до джерел | 1 тиждень |
| Трансформація | Маппінг, нормалізація, валідація | 1–2 тижні |
| Завантаження в Бітрікс | API або SQL, оптимізація | 1–2 тижні |
| Обробка помилок та моніторинг | Логування, алерти | 3–5 днів |
| Тестування | Навантажувальні тести, граничні випадки | 1 тиждень |
Сумарно: 6–12 тижнів залежно від складності. Оцінимо проєкт під ключ — зв'яжіться, щоб обговорити ваше завдання.
Докладніше про реалізацію синхронізації через CommerceML.







