ADG Оставить заявку
Блог Данные и аналитика 4 мин чтения

ClickHouse 1.1.54310: Materialized Views с фильтрами и ARRAY JOIN для сетевых flow-данных

Внедряем ClickHouse для хранения NetFlow/IPFIX: Materialized Views с фильтрами и улучшенный ARRAY JOIN сократили агрегацию 100 млн записей с 20 минут до секунд.

Контекст момента

ClickHouse 1.1.54310 - Materialized Views с WHERE-фильтрами, расширены табличные движки, улучшен ARRAY JOIN

Yandex выкатил ClickHouse 1.1.54310. На фоне всего что мы сейчас делаем с сетевым flow - это не просто патч-релиз.

Контекст: зачем вообще ClickHouse для NetFlow

У заказчика - телеком-оператор регионального уровня - поток NetFlow/IPFIX с нескольких граничных маршрутизаторов. Раньше это собиралось в MSSQL Server 2014, потом аналитик формировал отчёт через Excel-надстройку. Ждать приходилось от 15 до 25 минут. Запрос «топ-20 источников трафика за сутки» мог занять полчаса, если база не была свежеперезапущена.

Мы предложили ClickHouse как основное хранилище для аналитики flow-данных. Заказчик смотрел скептически - продукт относительно молодой, документация местами дырявая, Yandex его не позиционирует как «enterprise». Но у заказчика не было выбора объяснять директору почему отчёт за прошлый месяц нельзя посмотреть быстрее чем выпить чашку кофе.

Что изменилось в 1.1.54310

Три вещи попали точно в нашу задачу.

Materialized Views с WHERE. Раньше Materialized View в ClickHouse - это по сути триггер-INSERT в другую таблицу, куда идут все строки из источника. Фильтровать на этапе MV было нельзя. В 1.1.54310 появилась возможность добавить WHERE в тело MV - строки, не прошедшие фильтр, просто не попадают в целевую таблицу. Для нас это значит: можно держать «сырой» поток в одной таблице, а предагрегированные срезы по критичным префиксам IP или конкретным AS - в отдельных таблицах, без написания ETL-скрипта.

Улучшенный ARRAY JOIN. Flow-данные часто приходят пачками - один UDP-пакет содержит несколько flow-записей. У нас коллектор раскладывает их в массивы перед вставкой. ARRAY JOIN превращает строку с массивом в несколько строк - по одной на элемент. В прежних версиях ARRAY JOIN с несколькими массивами давал неожиданные результаты при разных длинах массивов. В 54310 поведение исправлено и задокументировано - LEFT ARRAY JOIN теперь работает предсказуемо, и мы перестали городить обходные костыли на стороне коллектора.

Расширение табличных движков. В частности, улучшения в Buffer-движке: теперь можно явнее контролировать условия сброса буфера в основную таблицу по числу строк и по времени. Для нас это позволяет принимать burst от коллектора без деградации вставок.

Как это выглядит в проде

Схема примерно такая: коллектор получает NetFlow, нормализует поля (src_ip, dst_ip, src_port, dst_port, protocol, bytes, packets, start_ts, end_ts, router_id), вставляет через Buffer-таблицу в основную MergeTree-таблицу. Партиционирование по дате. Сортировочный ключ - (router_id, toStartOfMinute(start_ts), src_ip) - это под большинство оперативных запросов.

Поверх сидят два Materialized View: один считает агрегаты по /24-подсетям за минуту (суммарные bytes/packets), второй - агрегаты по AS-номерам (добавили GeoIP-словарь для резолва). Оба теперь с WHERE - отбрасываем внутренние RFC1918-адреса из агрегата публичного трафика, это делалось раньше постфактум в запросе.

Результат который заказчик увидел первым: запрос «топ-20 AS по трафику за сутки» на таблице агрегатов. Не миллионы строк, а несколько тысяч в агрегированной таблице - ответ мгновенный. На сырой таблице, с сотнями миллионов записей за сутки - секунды. Заказчик переспросил трижды, думал что мы ему показываем кешированный результат.

Для сравнения: тот же запрос на MSSQL с тем же объёмом данных - мы не проверяли напрямую, потому что там данные уже не в той же форме, - но по словам аналитика «раньше это было минут двадцать».

Что пока не идеально

ClickHouse не умеет UPDATE и DELETE в обычном смысле. Для flow-данных это не проблема - поток иммутабельный. Но если приходит коррекция от коллектора (у некоторых вендоров бывает) - вставляем новую строку с флагом correction и учитываем в запросах. Небольшое усложнение логики приложения.

Мониторинг самого ClickHouse - через системные таблицы system.metrics и system.events. Мы прикрутили экспорт в Prometheus через простой скрипт-exporter. Штатного экспортера нет, пришлось написать самим.

Документация по Buffer-движку местами устарела и не отражала поведение в 54310 сразу после релиза. Разобрались через исходники и GitHub issues.

Итог

Заказчик согласился на расширение: добавляем хранение DNS-логов и DHCP lease-table рядом с flow. Для корреляции IP - имя хоста в реальном времени это отдельная задача, но ClickHouse с Dictionary-движком закрывает lookup достаточно быстро.

Для подобных задач - высокая скорость вставки, аналитические запросы по широким временным диапазонам, иммутабельные данные - инструмент работает именно так как ожидаешь по описанию. Это не всегда так бывает.

Контакт

Нужна такая же инженерная работа?

Опишите задачу и контекст. Ответим в течение рабочего дня, при необходимости подпишем NDA.