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

Наша компания занимается разработкой, поддержкой и обслуживанием решений на Битрикс и Битрикс24 любой сложности. От простых одностраничных сайтов до сложных интернет магазинов, CRM систем с интеграцией 1С и телефонии. Опыт разработчиков подтвержден сертификатами от вендора.
Предлагаемые услуги
Показано 1 из 1 услугВсе 1626 услуг
Разработка ETL-процессов для 1С-Битрикс
Средняя
~1-2 недели
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1177
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    811
  • 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 Appointment Booking Widget for a Medical Center
    564
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Разработка на базе 1С Предприятие для компании МИРСАНБЕЛ
    747
  • image_crm_dolbimby_434_0.webp
    Разработка сайта на CRM Битрикс24 для компании DOLBIMBY
    655
  • image_crm_technotorgcomplex_453_0.webp
    Разработка на базе Битрикс24 для компании ТЕХНОТОРГКОМПЛЕКС
    976

Разработка 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 недель в зависимости от количества источников и сложности трансформаций.