ClickHouse и Kafka: архитектура потоковой аналитики и практическая реализация
Краткое введение
Эффективная работа аналитической системы во многом определяется умением обрабатывать потоковые данные в реальном времени. Соединение ClickHouse и Kafka позволяет строить масштабируемые пайплайны: от нулевого задержания поступления событий до агрегаций и alerting в реальном времени. В рамках курса мы разберём принципы проектирования, типовые паттерны ingestion, архитектурные решения и риск-менеджмент, чтобы выпускник мог строить надёжные системы на стыке потоковых данных и хранилищ столбцовых данных. В этом контексте ключевое словосочетание звучит как единое целое в реальной практике: clickhouse kafka.
Введение
Современные дата-архитектуры строятся вокруг двух столпов: кластеров сообщений (Kafka) и аналитических хранилищ (ClickHouse). Kafka обеспечивает надёжную потоковую передачу событий с высоким скейлингом и гарантией доставки, тогда как ClickHouse обеспечивает низкую задержку запросов и мощные возможности агрегаций на больших объёмах данных. Интеграция двух технологий позволяет реализовать конвейеры типа «событие - факт» и «CDC - аналитика» с минимальной задержкой и высокой воспроизводимостью.
Ниже кратко обозначены ключевые концепции, которые будут использоваться в этой главе:
- потоковые источники и форматы данных: JSON, Avro, Protobuf, Parquet, ORC;
- инфраструктура: Kafka как источник, ClickHouse как целевое хранилище и обработчик;
- методологии: ingestion через Kafka Engine в ClickHouse, материализованные представления, Upsert-паттерны на MergeTree;
- безопасность и операционные аспекты: аутентификация, шифрование, мониторинг, управление схемами.
Мы будем внимательно различать понятия «потоковая загрузка» и «пакетная загрузка» и показывать, как переходить от простых сценариев к надёжным продакшн-решениям с учётом реальных ограничений.
Теоретические основы и терминология
- Kafka и его роль в архитектуре: брокеры, топики, партиции, потребительские группы, смещение (offset) и управление ими. Kafka обеспечивает устойчивость к сбоям и масштабируемость через горизонтальное масштабирование партиций.
- ClickHouse как хранилище и движок потоковой загрузки: MergeTree-подобные таблицы, таблицы с движком Kafka, материализованные представления, различные типы MergeTree (ReplacingMergeTree, SummingMergeTree и т. п.).
- Kafka Engine в ClickHouse: таблица, которая реализует источник данных из Kafka. Данные читаются из Kafka и конвейер идёт в ClickHouse через материализованные представления или прямой INSERT INTO целевых таблиц.
- Форматы данных: JSONEachRow, JSONCompact, CSV, Parquet/ORC через внешние источники и SerDe-слой ClickHouse. Различия в производительности и схемах.
- Серлийка и схема эволюции: Schema-on-read vs Schema-on-write; роль схем registries (например, Avro/Protobuf) и механизмы совместимости.
- Идентификация и консистентность: «at-least-once» гарантии в потоках, дубликаты, порядок доставок и паттерны их устранения.
- Типовые паттерны обработки: чистка, фильтрация, агрегации в реальном времени, сохранение итогов в MergeTree, использование внешних MATERIALIZED VIEW для трансформаций.
В практическом плане следует укоренить, что корректная работа с clickhouse kafka требует ясного выбора форматов и именно продуманной архитектуры ingestion, чтобы минимизировать задержку и ошибки.
Методологии и подходы
- Паттерн «Kafka как ingestion surface»: все события приходят в Kafka, затем через ClickHouse Kafka Engine поступают в промежуточную «сырую» таблицу, после чего материализованными представлениями данные поступают в целевые таблицы с необходимыми агрегированиями.
- Паттерн «CDC + ClickHouse»: Debezium или собственные решения производят CDC-кадры в Kafka, откуда ClickHouse читает через Kafka Engine и материализованные представления синхронно обновляют аналитические таблицы.
- Паттерн «schema evolution» без остановок: использование Nullable полей, Defining default values, совместимых изменений типов, применение ALTER TABLE только при крайней необходимости.
- Паттерн управления качеством данных: валидации на уровне materialized view, фильтры по правам доступа, мониторинг задержек и ошибок чтения из Kafka.
- Паттерн производственной эксплуатации: мониторинг lag, настройка таймаутов и ретраев, лимитов памяти, централизация логирования, резервы на случай сбоя брокера.
Применение этих паттернов требует осознанного подхода к выбору форматов, схем и режимов потребления.
Архитектура и технологическая реализация
Общая схема конвейера
- Продюсерские приложения публикуют события в Kafka topics.
- Kafka Engine в ClickHouse читает события и помещает их в «сырую» таблицу Kafka-топика.
- Материализованные представления (MV) или обычные вставки в MergeTree-таблицы приводят сырые данные к аналитическим таблицам с нужными агрегатами и форматом.
- BI/генераторы отчётов работают на основе целевых таблиц; можно строить маркеры изменения (versioning) и метаданные.
Пример архитектурной схемы:
- Входной поток: Kafka (topics) -> ClickHouse Kafka Engine (сырой слой)
- Преобразование: MV → целевая таблица (инкремент, агрегации, полнотекстовая обработка)
- Выгрузка: пользовательские дашборды, тайм-серии, алерты
Пример реализации ingestion через Kafka Engine
Ниже приведён упрощённый пример конфигурации для реализации потока “событие - факт” через Kafka Engine.
-- Таблица-источник, читающая данные из Kafka
CREATE TABLE kafka_events
(
event_time DateTime,
user_id UInt64,
event String,
amount Float64
)
ENGINE = Kafka
SETTINGS
kafka_broker_list = 'kafka1:9092,kafka2:9092',
kafka_topic_list = 'events',
kafka_group_name = 'clickhouse_consumer_group',
kafka_format = 'JSONEachRow';
-- Целевая таблица MergeTree
CREATE TABLE events_fact
(
event_time DateTime,
user_id UInt64,
event String,
amount Float64
) ENGINE = MergeTree()
PARTITION BY toYYYYMM(event_time)
ORDER BY (event_time, user_id);
-- Материализованное представление для маршрутизации данных из Kafka в целевую таблицу
CREATE MATERIALIZED VIEW mv_kafka_to_events_fact TO events_fact AS
SELECT
event_time,
user_id,
event,
amount
FROM kafka_events;
- Особенности:
- Формат данных: JSONEachRow подходит для гибких схем; для строгих схем - Avro или Protobuf с последующим SerDe.
- В конфигурации Kafka Engine можно задать дополнительные параметры для оптимизации задержек и размера батчей: kafka_batch_size, kafka_max_block_size, kafka_poll_interval, и т. п.
- Важная деталь: в CH данные из Kafka могут попадать в целевую таблицу с несколько задержкой из-за конвейера MV и вставок в MergeTree. Планируйте задержку и SLA accordingly.
Форматы данных и преобразования
- JSONEachRow: гибкость и простота; хорошо подходит для динамических схем, когда формат событий стабилен, но поля могут расширяться.
- Avro/Protobuf через Schema Registry: более строгая схему, поддерживает эволюцию схем. В интеграциях часто применяют конвертеры внутри MV или внешние сервисы для сериализации и десериализации.
- Parquet/ORC на входе: прямой поддержки в Kafka Engine как формата входа чаще нет; данные чаще подготавливаются в виде JSON/Native в Kafka, а затем записываются в Parquet/ORC внутри ClickHouse через внешние преобразования или экспорты.
Взаимодействие с безопасностью
- TLS между клиентом Kafka и ClickHouse; SASL/ Kerberos для аутентификации внутри кластера.
- Разграничение доступа: только необходимый доступ к топикам и таблицам. Использование принципа наименьших прав.
- Шифрование в транзите и на диске для конфиденциальных данных.
Мониторинг и операционные аспекты
- Lag и задержки: мониторинг задержки потребления по каждому топику и партиции.
- Здоровье топиков: просмотр ошибок парсинга, пропусков и ошибок сериализации.
- Метрики ClickHouse: system.metrics, system.table_engines, system.mutations.
- Аудит и безопасность: логирование действий по доступу к Kafka и к таблицам CH.
- Резервирование: продуманные стратегии репликации таблиц и резервного копирования.
Роли и ответственность
- Архитектор: выбор паттерна ingestion (Kafka Engine, MV, Upsert-паттерны) и архитектуры для необходимой задержки/скейлинга.
- Разработчик: проектирование схем, форматирование данных, обработка ошибок и написание MV.
- Инженер эксплуатации: мониторинг, доступ, безопасность, резервы на сбои Kafka и ClickHouse.
Организационные и процессные аспекты
- Управление схемами:
- Регистрация и эволюция форматов данных (JSON vs Avro) должны быть задокументированы.
- Наличие единого подхода к обработке изменений в схеме: дополнительные поля, дефолтные значения, Nullable.
- Контроль качества данных:
- Введение проверок на стадии MV: корректность типов, диапазоны значений, валидность JSON.
- Настройка предупреждений в случае падения задержек или ошибок парсинга.
- SLA и операционные показатели:
- Определение задержек, частоты обновления агрегатов, требования к доступности.
- Нормы по потреблению ресурсов: память, CPU, диск для хранения больших объёмов данных.
- Безопасность данных:
- Шифрование в покое и в транзите, разграничение доступа, журналирование действий.
- Соответствие требованиям регуляторов и внутренним политикам компании.
- Росcийский контекст:
- В российских реалиях инфраструктура потоковых систем часто строится на гибридном подходе: локальные кластеры Kafka + локальные кластеры ClickHouse для снижения задержек и обеспечения приватности.
- Примеры использования в крупных организациях России показывают, как сочетание ClickHouse и Kafka даёт возможность real-time аналитики на миллионах событий в секунду.
Технические детали реализации (алгоритмы, схемы, протоколы, интеграции)
- Подключение к Kafka:
- Настройка TLS/SAASL, выбор группы потребителей, управление смещением.
- Схема потоковой загрузки:
- Вставка сырых данных в Kafka → чтение через Kafka Engine → MV → целевые таблицы MergeTree.
- Управление временем и событиями:
- EventTime как источник времени; обработка временных окон для агрегаций; использование функций toStartOfHour, toStartOfDay в ClickHouse.
- Обработка дубликатов:
- ИспользованиеReplacingMergeTree на основе версии или TTL-логики; параметр version_col; дополнительные уникальные ключи.
- Эволюция схем:
- Добавление новых столбцов: ALTER TABLE ADD COLUMN; настройка MV для поддержки новых полей.
- Устойчивые принципы: дефолтные значения, nullable, fallback-поля.
- Интеграции:
- Debezium + Kafka: CDC события в Kafka, чтение через Kafka Engine и обработка в CH.
- Flink/Spark: промежуточная обработка больших потоков, затем запись в CH через Insert запросы к MergeTree.
- Kafka Connect: источники и коннекторы для интеграций в реальном времени; возможна запись в CH через коннектор, но чаще используется через Kafka Engine для единообразной обработки.
Пример сценария интеграции Debezium + ClickHouse
- Debezium публикует изменения в Kafka топик.
- ClickHouse читает данный топик через Kafka Engine в таблицу сырых данных.
- MV преобразует и вставляет в целевые таблицы аналитических фактов.
- Визуализация и алерты строятся на основе целевых таблиц.
Этот сценарий позволяет обрабатывать CDC-потоки, поддерживая согласованность и минимизируя задержку.
Риски, ограничения и типовые ошибки
- Неправильный выбор формата данных: JSON vs Avro/Protobuf может повлечь несовместимости и сложности эволюции схем.
- Неправильное управление схемой: изменение типов без учёта существующих записей может привести к ошибкам чтения и падению производительности.
- Отсутствие guarantees exactly-once: CH + Kafka Engine чаще обеспечивает at-least-once; дубликаты и перестановки(false ordering) требуют дополнительных мер.
- Задержки и деградации: неправильно настроенные батчи и poll-интервал могут приводить к чрезмерной задержке.
- Ошибки сериализации/десериализации: несоответствие полей и типов между Kafka и CH может привести к ошибкам парсинга.
- Безопасность: недостаточно строгие политики доступа к топикам или незашифрованное соединение увеличивают риск утечки данных.
- Масштабирование:
- Проблемы с дисками и сетевым трафиком при больших объемах.
- Неэффективная конфигурация партицирования и ключей в MergeTree.
- Мониторинг и операционная ответственность: без централизованного мониторинга трудно быстро определить проблемы в конвейере.
Типовые ошибки при внедрении:
- Неправильная настройка kafka_topic_list и kafka_broker_list, что вызывает отсутствие данных.
- Пренебрежение схемой и упрощение обработки, что приводит к несоответствиям.
- Несоответствие worldview между продюсерскими приложениями и CH MV.
- Игнорирование задержек и lag-а.
Заключение
Сочетание ClickHouse и Kafka образует мощный фундамент для потоковой аналитики на больших объёмах данных. Архитектура «Kafka Engine в ClickHouse + Materialized Views» даёт достаточно гибкости для реализации низкой задержки, масштабируемые решения и устойчивые к изменению схемы конвейеры. Важна не только техническая реализация, но и организация процессов, безопасность и мониторинг. Правильный выбор форматов данных, схем и паттернов обработки позволяет уменьшать риск дублирования и ошибок, обеспечивая надёжную аналитическую экосистему.
FAQ (7-10 вопросов с развёрнутыми ответами)
Q1. В чём ключевое различие между ingestion через Kafka Engine и прямой загрузкой данных в ClickHouse?
- A: Ingestion через Kafka Engine обеспечивает потоковую загрузку данных прямо из Kafka без необходимости внешних коннекторов. Это позволяет строить real-time конвейеры, минимизировать задержку и упростить архитектуру. Прямой загрузкой называют пакетную вставку или буферизированную запись через внешние сервисы (Flink, Spark), что дает больше возможностей для предобработки и сложной трансформации, но может увеличить задержку. Выбор зависит от требований к латентности и сложности обработки.
Q2. Как обеспечить низкую задержку в цепочке Kafka → ClickHouse?
- A: Выбор формата JSONEachRow для гибкости и скорость парсинга; настройка Kafka Engine на минимальные задержки через параметры batch_size и poll_interval; использование MV для минимизации задержек между чтением и записью; обеспечение достаточного уровня параллелизма и кеширования в MergeTree. В критически важных сценариях можно рассмотреть прямую вставку из MV в финальные таблицы с минимальной обработкой.
Q3. Как реализовать обработку CDC с помощью Debezium и ClickHouse?
- A: Debezium публикует CDC-события в Kafka, CH читает их через Kafka Engine, MV трактует эти события и обновляет целевые таблицы. Важно корректно настроить схемы изменений (update_before, op) и использовать подходящие MergeTree-таблицы (например, ReplacingMergeTree) для обновления существующих строк. Также нужен верный ключ обновления и версия, чтобы избежать конфликтов.
Q4. Как управлять схемами и эволюцией без простоев?
- A: Используйте Nullable поля и дефолтные значения для новых столбцов; добавляйте столбцы через ALTER TABLE ADD COLUMN; поддерживайте совместимость форматов; применяйте MV-обработчики, которые учитывают новые поля, чтобы не нарушать существующие потоки. В случае сложной эволюции можно временно поддерживать «плоскость» старой схемы и новую схему через дополнительные таблицы.
Q5. Какие паттерны используются для обеспечения устойчивости к дубликатам и перестановкам?
- A: Паттерны: 1) использование version column и ReplacingMergeTree, 2) применение уникального ключа в MergeTree, 3) логика idempotent-вставок через MV, 4) контроль qualify-условий и фильтрация на этапе MV. Важно документировать, какие дубликаты допустимы и как они будут обрабатываться.
Q6. Какие меры безопасности важны при работе с ClickHouse и Kafka в рамках одного конвейера?
- A: TLS-шифрование на каналах, SASL/Kerberos для аутентификации в Kafka и ClickHouse, ограничение доступа к топикам и таблицам по принципу минимальных привилегий, аудит и журналы доступа. Также следует обеспечить безопасную миграцию схем и критичных данных между окружениями.
Q7. Как мониторить конвейер и выявлять проблемы вовремя?
- A: Мониторинг задержек и lag по каждому топику/партиции; мониторинг пропускной способности и ошибок парсинга; использование system.mutations для отслеживания процессов обновления; логирование и алертинг по критическим метрикам: задержки, ошибки сериализации, падение продуктивных воркфлоу. Рекомендуется централизованный дашборд по ключевым KPI: latency, throughput, error_rate.
Q8. Какие формы интеграции с другими системами стоит рассмотреть вместе с CH и Kafka?
- A: Интеграции с Flink/Spark для предобработки, Debezium для CDC, Kafka Connect для специфических коннекторов, а также экспорты в Parquet/ORC для оффлайн-аналитики. В некоторых случаях полезно построить «модуль обработки» на Flink, который читает из Kafka и пишет в CH, чтобы разгрузить MV от сложной трансформации.
Q9. Какие примеры архитектур можно привести в реальном мире?
- A: Архитектура для онлайн-аналитики в e-commerce: события покупки, клики и транзакции публикуются в Kafka; CH читает через Kafka Engine, MV агрегирует за «последние 5 минут» и сохраняет в финальные таблицы; BI-дашборды показывают агрегации по пользователю и товару. Другой сценарий - мониторинг и алертинг: логи систем и метрики публикуются в Kafka; CH агрегирует в окнах и генерирует алерты через Materialized View, интегрированные с системой оповещений.
Q10. Какие российские и open-source примеры можно привести как опору для внедрения?
- A: Open-source примеры: Apache Kafka и Apache Flink, Debezium, ClickHouse как ядро аналитическое. Российский контекст: модель архитектуры часто базируется на ClickHouse как основном хранилище и Kafka как движке персистирования событий, с использованием открытого кода ClickHouse, который родился в рамках российской инфраструктуры и продолжает развиваться в российской экосистеме. Также российские компании применяют решения для мониторинга и безопасности на основе открытых инструментов в связке с локальными кластерами CH.
Примеры open-source и российских продуктов
- Open-source:
- Apache Kafka и его экосистема (Confluent, KSQL, Kafka Connect)
- Apache Flink/Apache Spark для стриминга и микро-батчей
- Debezium для CDC
- ClickHouse (проект с российскими корнями, открытый исходный код)
- Российские направления:
- ClickHouse как ядро аналитических систем в крупных компаниях (например, в телекоммуникациях, онлайн-ритейле, финансовом секторе)
- Локальные инфраструктурные решения вокруг безопасности, мониторинга и управления данными, адаптированные под требования российского рынка
- Интеграционные решения и консалтинг российских компаний, которые внедряют инфра-решения на базе ClickHouse и Kafka
Эти примеры демонстрируют, что данная связка работает как в международном контексте, так и в специфику российского рынка, где важна автономность, безопасность и устойчивость инфраструктуры.
Примеры кода и конфигураций (ещё несколько сценариев)
Сценарий: Агрегации в окнах и сохранение в финальные таблицы
-- сырые данные из Kafka
CREATE TABLE kafka_events
(
event_time DateTime,
user_id UInt64,
city String,
amount Float64
)
ENGINE = Kafka
SETTINGS
kafka_broker_list = 'kafka1:9092,kafka2:9092',
kafka_topic_list = 'sales',
kafka_group_name = 'sales_consumer',
kafka_format = 'JSONEachRow';
-- целевая таблица агрегаций
CREATE TABLE sales_agg
(
event_date Date,
city String,
total_amount Float64,
cnt UInt64
) ENGINE = MergeTree()
PARTITION BY event_date
ORDER BY (city, event_date);
-- агрегация по окнам (пример: сутки)
CREATE MATERIALIZED VIEW mv_sales_agg TO sales_agg AS
SELECT
toDate(event_time) AS event_date,
city,
sum(amount) AS total_amount,
count() AS cnt
FROM kafka_events
GROUP BY event_date, city;
Пример: CDC через MV и ReplacingMergeTree
CREATE TABLE cdc_source
(
id UInt64,
name String,
status String,
_version UInt64
)
ENGINE = Kafka
SETTINGS
kafka_broker_list = 'kafka1:9092',
kafka_topic_list = 'service_changes',
kafka_group_name = 'cdc_group',
kafka_format = 'JSONEachRow';
CREATE TABLE service_state
(
id UInt64,
name String,
status String,
_version UInt64
) ENGINE = ReplacingMergeTree(_version)
ORDER BY id;
CREATE MATERIALIZED VIEW mv_cdc TO service_state AS
SELECT
id,
name,
status,
_version
FROM cdc_source;
Заключение к главе
Интеграция ClickHouse и Kafka - мощный фундамент современных систем анализа и мониторинга, сочетающих преимущества потоковой передачи и столбцового хранения. Выбор конкретной архитектуры зависит от требований к задержке, точности агрегаций, эволюции схем и операционных ограничений. Правильное применение форматов данных, MV и паттернов обработки позволяет строить устойчивые решения для реального времени и масштабирования, включая CDC-решения и гибкую эволюцию схем.
Вопросы и ответы (FAQ) - повторяются и дополняют материал главы
-
Вопрос: В чем преимущество использования Kafka Engine в ClickHouse по сравнению с внешними коннекторами?
Ответ: Kafka Engine обеспечивает прямой, высокопроизводительный доступ к потокам из Kafka внутри ClickHouse без необходимости внешних коннекторов и промежуточного преобразования. Это упрощает архитектуру, снижает задержки и помогает реализовать потоковую аналитику в реальном времени. Однако внешний коннектор может понадобиться для сложной предобработки и интеграции с другими системами, когда нужна гибкость в трансформациях и совместимости форматов. -
Вопрос: Как выбрать формат данных для события в Kafka в контексте CH?
Ответ: JSONEachRow прост и гибок, подходит для динамических схем и быстрого старта. Avro или Protobuf через Schema Registry обеспечивают строгую схему и легкую эволюцию схем без потери совместимости. В продакшне часто комбинируют: JSON в Kafka для быстрого старта и MV с внешним преобразованием к Avro для сложной эволюции схем. -
Вопрос: Как минимизировать риск дубликатов и неверного порядка событий?
Ответ: Используйте MV и ReplacingMergeTree с версионными полями; назначайте уникальный ключ на уровне источника; соблюдайте idempotent-подходы в приложениях-производителях; обеспечьте корректную обработку порядка по разделам и оконным функциям. -
Вопрос: Какие меры стоит принять для мониторинга конвейера?
Ответ: Мониторинг задержек (lag) по топикам и партициям, ошибок сериализации, пропусков и повторных попыток; мониторинг состояния MV и mutate-запросов; мониторинг загрузки кластера CH и Kafka; сбор и анализ логов. -
Вопрос: Как обеспечить безопасность при интеграции CH и Kafka?
Ответ: TLS/SSL для шифрования, SASL/kerberos для аутентификации, ACL для ограничения доступа, централизованные журналы аудита и мониторинг доступа к данным и топикам. -
Вопрос: Как организовать эволюцию схем без простоев?
Ответ: Планируйте добавления столбцов через ALTER TABLE ADD COLUMN, используйте Nullable поля и дефолтные значения, поддерживайте совместимые версии в MV и используйте staging-таблицы на период миграции. -
Вопрос: Какие сценарии подходят для использования Debezium + CH?
Ответ: CDC для изменений из баз данных (PostgreSQL, MySQL и др.) в Kafka, после чего CH читает события через Kafka Engine и обновляет аналитические таблицы. Это мощно для «финальные изменённые строки» и реального времени. -
Вопрос: Какие ограничения стоит учесть при работе с Kafka + ClickHouse в регионах с высокой задержкой?
Ответ: В таких условиях критично повысить параллелизм и размер батчей, выбрать подходящие топики и партиции, возможно, использовать локальные кластеры Kafka и ClickHouse и минимизировать пересечения между регионами. Задержки будут выше, но можно управлять ими через настройку параметров и архитектурные паттерны. -
Вопрос: Какие примеры паттернов можно применить в российских проектах?
Ответ: Примеры паттернов - локальные кластеры CH и Kafka для снижения задержек, использование MV для агрегаций, CDC через Debezium и локальные схемы, а также интеграции с отечеальными BI- и мониторинг-решениями. РФ-подходы часто фокусируются на приватности данных, отказоустойчивости и соблюдении регуляторных требований. -
Вопрос: Какие практические шаги для старта проекта можно предложить?
Ответ:
- Определить требования к латентности и SLA;
- Выбрать форматы данных и схемы;
- Настроить базовую схему: Kafka Engine + MV + целевые таблицы;
- Включить мониторинг и логирование;
- Постепенно расширять функционал - CDC, дополнительные окна агрегаций, безопасность и масштабирование.
Эта глава даёт всестороннее представление о том, как проектировать, реализовывать и поддерживать интеграцию ClickHouse и Kafka для продвинутой потоковой аналитики. В приложении к курсу вы сможете применить полученные паттерны на практике: выбрать правильную архитектуру, настроить ingestion и MV, обеспечить мониторинг и управление схемами, а также управлять операционными рисками в реальном Prod.



