[Open source, Администрирование баз данных, Big Data, Data Engineering] EventNative – простой инструмент для записи потока событий в ClickHouse (перевод)

Автор Сообщение
news_bot ®

Стаж: 6 лет 3 месяца
Сообщений: 27286

Создавать темы news_bot ® написал(а)
26-Янв-2021 15:31

Данные стали бесценным активом, позволяющим компаниям лучше понимать своих пользователей, прогнозировать их поведение и определять тренды. EventNative – проект с открытым исходным кодом, разработанный командой из Jitsu, который позволяет упростить сбор данных о событиях. EventNative поддерживает работу с несколькими хранилищами данных, и ClickHouse – одно из них.В этой статье мы расскажем как настроить EventNative с ClickHouse, а также в ней приводятся советы по эксплуатации и повышению производительности и надежности.Загрузка данных в ClickHouse – не такая простая задача, как может показаться на первый взгляд. Обработка потоков с миллионами событий из различных приложений (где у каждого события может быть своя собственная структура) может вызывать значительные затруднения. Ситуация может стать особенно сложной, если в одной продакшн-среде работают разные версии одного и того же приложения (например, разные версии iOS-приложения).Архитектура EventNative максимально эффективна и надежна. Она состоит из легковесного HTTP-сервера, принимающего поток событий (состоящий из JSON-объектов) и буферизующего его на локальный диск. Отдельный поток приложения занимается обработкой этого буфера, маппингом JSON-объектов с таблицами в ClickHouse, настройкой схемы и хранением данных.Быстрый запуск ClickHouse и EventNativeВ этом разделе мы расскажем об установке узла с ClickHouse и EventNative c помощью официальных Docker-образов.Обратите внимание, что здесь мы рассматриваем настройку окружения для разработки. В продакшн-сценариях вы можете развернуть несколько узлов EventNative и подключить реплики ClickHouse, чтобы убедиться в доступности данных и масштабировать пропускную способность.1. Скачиваем Docker-образы
docker pull ksense/eventnative:latest && docker pull yandex/clickhouse-server:latest
2. Запускаем ClickHouse
mkdir ./clickhouse_data && docker run --name clickhouse-test -p 8123:8123 -v $PWD/clickhouse_data:/var/lib/clickhouse yandex/clickhouse-server
3. Настраиваем EventNativeДобавьте следующий текст в ./eventnative.yaml
server:
auth:
   - server_secret: 'ia7i92rqp3mh' # access token. We will need it later for sending events through HTTP API
destinations:
  clickhouse:
    mode: stream
    clickhouse:
      dsns:
        - "http://default:@host.docker.internal:8123?read_timeout=5m&timeout=5m"
      db: default
    data_layout:
      mappings:
        fields:
        - src: /field_1/sub_field_1
          action: remove
        - src: /field_2/sub_field_1
          dst: /field_10/sub_field_1
          action: move
        - src: /field_3/sub_field_1/sub_sub_field_1
          dst: /field_20
          action: move
          type: DateTime
        - dst: /constant_field
          action: constant
          value: 1000
Также создайте директорию для логов: mkdir ./eventnative-logs4. Запускаем EventNative
docker run -d -t --name eventnative-test -p 8001:8001 \
-v $PWD/eventnative.yaml:/home/eventnative/app/res/eventnative.yaml \
-v $PWD/eventnative-logs:/home/eventnative/logs/events/ ksense/eventnative:latest
5. Отправляем тестовое событие и проверяем, что оно записалось в ClickHouseДобавьте следующий объект в ./api.json:
{
"eventn_ctx": {
   "event_id": "19b9907d-e814-42d8-a16d-c5da51e01531"
},
"field_1":  {
   "sub_field_1": "text1",
   "sub_field_2": 100
},
"field_2": "text2",
"field_3": {
   "sub_field_1": {
     "sub_sub_field_1": "2020-09-25T12:38:27"
   }
}
}
Запустите следующую команду:
curl -X POST -H "Content-Type: application/json" -d @./api.json \
'http://localhost:8001/api/v1/s2s/event?token=ia7i92rqp3mh'
echo 'SELECT * FROM events;' | curl 'http://localhost:8123/' --data-binary @-
Вы увидите одно событие в базе данных. Тест сработал!6. Тестируем буферизацию событийОдна из основных фич EventNative'а — это буфферизация. События записываются во внутреннюю очередь с сохранением на диск. Если база данных (в нашем случае ClickHouse) недоступна, данные не будут потеряны. События будут сохранены локально и попадут в базу данных когда ClickHouse станет доступным опять.Давайте протестируем эту фичу:Добавьте следующий JSON в ./api2.json:
{
"eventn_ctx": {
   "event_id": "4748c7bb-50d4-43a7-91b4-21a5bcccb12e"
},
"field_1":  {
   "sub_field_1": "text1",
   "sub_field_2": 100
},
"field_2": "text2",
"field_3": {
   "sub_field_1": {
     "sub_sub_field_1": "2020-09-25T12:38:27"
   }
}
}
Остановите ClickHouse
docker stop clickhouse-test
Отошлите событие
curl -X POST -H "Content-Type: application/json" -d @./api2.json 'http://localhost:8001/api/v1/s2s/event?token=ia7i92rqp3mh'
Проверьте что ClickHouse действительно не работает
echo 'SELECT * FROM events;' | curl 'http://localhost:8123/' --data-binary @-
Запустите ClickHouse опять
docker start clickhouse-test
Подождите 60 секунд и убедись, что событие не потерялось
echo 'SELECT * FROM events;' | curl 'http://localhost:8123/' --data-binary @-
Управление схемой с помощью EventNative и ClickHouseEventNative спроектирован так, что вам не потребуется создавать схемы таблиц и поддерживать их. EventNative позаботится об этом автоматически! Каждое поле в JSON-объекте будет сопоставляться с полем в SQL. Если поле отсутствует, оно будет автоматически создано в базе ClickHouse.Это особенно полезно, если одна команда разработчиков занимается структурой событий, а другая работает с ClickHouse. Приведем пример: фронтенд-разработчик может начать отправлять очень простые данные для отслеживания просмотров страницы продукта (id продукта и его стоимость), а затем будет добавлять более сложные поля (валюту и изображения). Потому что они могут пригодиться.Пример:JSON с событием
{
   "product_id":  "1e48fb70-ef12-4ea9-ab10-fd0b910c49ce",
   "product_price": 399.99,
   "price_currency": "USD",
   "product_type": "supplies",
   "product_release_start": "2020-09-25T12:38:27",
   "images": {
     "main": "picture1",
     "sub":  "picture2"
   }
}
Автоматически сгенерированная структура таблицы:
"product_id" String,
"product_price" Float64,
"price_currency" String,
"product_type" String,
"product_release_start" String,
"images_main" String,
"images_sub" String
По умолчанию, все поля не будут допускать запись Null. Проблема в том, что Nullable-поля влияют на производительность. Но в случае если Null значения необходимы - можно сконфигурировать список полей:
nullable_fields: ['product_id', 'product_price', 'price_currency']
(См полное описание конфигурации mapping'а)Больше о конфигурация mapping'аС помощью изменения настроек EventNative может применять к входящим JSON-объектам определенные преобразования, например:
  • Удалять поля
  • Переименовывать поля (включая перенос поля в другой узел)
  • Явно определять тип поля
  • Подставлять константу
Пример
- src: /field_1/sub_field_1
    action: remove
  - src: /field_2/sub_field_1
    dst: /field_10/sub_field_1
    action: move
  - src: /field_3/sub_field_1/sub_sub_field_1
    dst: /field_20
    action: move
    type: DateTime
  - dst: /constant_field
    action: constant
    value: 1000
В результате применения правил следующий JSON
{
"eventn_ctx": {
   "event_id": "19b9907d-e814-42d8-a16d-c5da51e01530"
},
"field_1":  {
   "sub_field_1": "text1",
   "sub_field_2": 100
},
"field_2": "text2",
"field_3": {
   "sub_field_1": {
     "sub_sub_field_1": "2020-09-25T12:38:27"
   }
}
}
Превратится в такую запись в базе данных
{
"eventn_ctx_eventn_id": "19b9907d-e814-42d8-a16d-c5da51e01530",
"field_1_sub_field_1":  "text1",
"field_1_sub_field_2":  100,
"field_2": "text2",
"field_3_sub_field_1_sub_sub_field_1": "2020-09-25T12:38:27.763000Z",
"constant_field": 1000
}
Полное описание этой функции вы можете изучить в документацииСоветы по повышению производительности ReplacingMergeTree (или ReplicatedReplacingMergeTree) – лучший движок для данных, созданных EventNative, и вот почему:
  • Обычно данные, созданные EventNative используются в запросах с агрегатными функциями (например, при подсчете количества событий, удовлетворяющих некоторому условию, за заданный период времени). Движки из семейства MergeTree показывают отличную производительность при работе с такими запросами.
  • ReplacingMergeTree (в отличие от MergeTree) имеет приятный побочный эффект – дедупликация данных. Зачастую ошибки в данных обнаруживаются уже после их загрузки. Иногда их необходимо перезаписывать. Поскольку EventNative может хранить логи событий в течении некоторого времени, вы можете написать скрипт для исправления данных и их повторной записи. ReplacingMergeTree позволит избежать дублирования данных (при условии, что у каждого события есть уникальный идентификатор, который используется в качестве ключа)
Если целевая таблица отсутствует, EventNative создаст таблицу с помощью ReplacingMergeTree или ReplicatedReplacingMergeTree (если размер кластера больше 1). Однако, этот механизм можно настроить вручную. Подробнее о создании таблиц можно прочитать в документации
===========
Источник:
habr.com
===========

===========
Автор оригинала: Altinity Team
===========
Похожие новости: Теги для поиска: #_open_source, #_administrirovanie_baz_dannyh (Администрирование баз данных), #_big_data, #_data_engineering, #_clickhouse, #_eventnative, #_data_engineering, #_blog_kompanii_jitsu (
Блог компании Jitsu
)
, #_open_source, #_administrirovanie_baz_dannyh (
Администрирование баз данных
)
, #_big_data, #_data_engineering
Профиль  ЛС 
Показать сообщения:     

Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы

Текущее время: 29-Май 12:52
Часовой пояс: UTC + 5