Как Redpanda и Materialize воплощают данную идею в жизнь
Как эти продукты, не основанные на JVM, делают потоковую обработку доступной для широких масс за счет снижения операционных издержек? Обсудим в статье.
Говорят, что данные - это сырая нефть. Их нужно извлечь и обработать, прежде чем использовать в своих целях.
Но что, если весь процесс очистки занимает слишком много времени? Какую ценность можно получить из данных, которые не поступили вовремя?
Я бы сказал, к данным нужно относиться как к скоропортящемуся товару. Чем раньше вы их получите, тем быстрее обработаете, соответственно больше ценности извлечете.
Ценность данных уменьшается со временем. Именно поэтому организации отказываются от пакетных пайплайнов в пользу систем потоковой обработки данных в реальном времени.
Но системы, работающие в режиме реального времени и ориентированные на события - это не для всех. Для создания и эксплуатации таких систем в продакшне, которые способны решать задачи обработки больших объемов данных в петабайтах, нужна специализированная команда инженеров по распределенным системам. Для этого часто требуются талантливые специалисты, умеющие хорошо работать на Java или Scala.
Сегодня я расскажу о двух революционных технологиях - Redpanda и Materialize, которые демократизируют область обработки данных в реальном времени. Вместе они делают обработку потоков данных доступной для широких масс.
Давайте разберем их по порядку.
Кафка имеет давнюю историю
Kafka давно уже является неотъемлемой частью важных архитектур для обработки событий в реальном времени. Он обеспечивает работу дашбордов по управлению в режиме реального времени, надежных пайплайнов машинного обучения и сверхбыстрых систем по обнаружению мошенничества. Вокруг Kafka существует активное сообщество разработчиков с открытым исходным кодом, созданное на основе многолетних инженерных усилий.
Но все эти удивительные достижения зачастую имеют свою цену.
Процесс операционализации Kafka и других компонентов обработки потоковых данных из мира открытых исходных кодов сопряжен с ростом сложности. Это требует специализированных навыков, которые иногда не так легко найти на рынке. Управляемые сервисы могут облегчить этот процесс. Однако такие услуги требуют значительных затрат, и не каждая организация способна пойти на это.
"Профессор Батс и Автоматическая Салфетка" (1931) — Для того чтобы выполнить простую задачу, традиционные потоковые технологии требуют серьезных усилий.
Та же мощь, но с минимальными накладными расходами и открытая для всех
Но что, если вы такой же типичный разработчик, как и я:
У вас в организации сегодня нет "проблемы больших данных" петабайтного масштаба. Но, возможно, такая задача вас ждет в будущем.
Вы не имеете опыта работы с JVM (Java Virtual Machine).
Вы бы хотели добавить в свой дата-продукт возможность работы в реальном времени, потому что видели выступления на конференциях замечательных специалистов из FANG.
Таким образом, проще говоря, всё, что вам нужно, - это Kafka, но с большей доступностью для разработчиков, не имеющих опыта работы с JVM, и с меньшими операционными трудностями.
Я считаю, что Redpanda пытается решить эту проблему.
Встречайте Redpanda
Vectorized Redpanda (оптимизированная версия Redpanda с использованием векторизации) - это высокопроизводительная переработка Apache Kafka на языке C++. Внутри Redpanda были переделаны и улучшены различные компоненты Kafka:
Брокер: центральная часть системы Kafka, которая отвечает за хранение, обработку и доставку данных.
Протокол: здесь имеется в виду протокол связи, который определяет, как данные передаются между компонентами системы Kafka.
Полная модель производителя/потребителя: основная концепция в Kafka, где производители отправляют данные, а потребители их получают. Полная модель означает, что в Redpanda эта концепция была усовершенствована и оптимизирована для более эффективной работы.
На сайте говорится:
Платформа потоковой передачи данных, совместимая с API Kafka®, для критически важных рабочих нагрузок.
Целью создания Redpanda было снижение операционной нагрузки на большую часть процессов, сделать ее доступной для обычных разработчиков и добиться большей скорости, чем у Kafka.
Давайте посмотрим, как это было достигнуто.
В Redpanda нет Zookeeper
Для координации работы кластера и управления метаданными наряду с распределенной системой обработки больших данных требуется кластер Zookeeper. Как правило, для получения кворума кластеру Zookeeper требуется не менее трех узлов.
Будь то Hadoop, Hive или Kafka, управление этой инфраструктурой сопровождалось операционной нагрузкой и требовало специальных навыков. Redpanda решает эту проблему, используя алгоритм распределенного консенсуса Raft. Благодаря этому, Zookeeper больше не требуется, что делает работу с Redpanda менее сложной.
Я понимаю, что сравнение с Kafka не совсем корректно, так как они также избавляются от Zookeeper. Но на все это потребуется время, чтобы всё устаканилось.
У Redpanda нет JVM
Исторически сложилось так, что большинство технологий потоковой передачи данных с открытым исходным кодом были построены на основе JVM-технологий. Hadoop, Spark и Flink - это лишь несколько примеров надежных и масштабируемых решений. Но часто для их обслуживания и эксплуатации требуется опыт в области JVM.
Например, чтобы исправить такую систему и внести в нее патч, необходимо быть опытным Java-разработчиком. Также операторы должны были изучать, как настраивать параметры JVM для достижения оптимальной производительности системы.
Всё это долгое время отталкивало разработчиков без опыта работы с JVM, от использования систем потоковой передачи данных.
Написанная на C++, Redpanda позволяет отказаться от JVM и выжать максимум из серверного оборудования. Это наконец-то освобождает потоковые технологии от JVM-зависимости и открывает много возможностей для программистов с разным уровнем подготовки.
Redpanda полностью совместима с API Kafka
Если вы уже являетесь пользователем Kafka, Redpanda предоставляет вам возможность беспрепятственной миграции. Теоретически, замена вашей существующей инфраструктуры, основанной на Kafka, не должна повлечь за собой изменений в зависимых приложениях. Взамен вы получите меньше накладных расходов, улучшенную производительность и большую доступность.
Более подробно о сравнении Kafka и Redpanda вы можете прочитать в этой замечательной статье.
Попробуем Redpanda в действии
Я говорю уже так долго… Теперь давайте увидим Redpanda в действии.
Установка
Redpanda предоставляет различные варианты установки. Это нативные инсталляторы для Linux и Mac, образы Docker и чарты Kubernetes Helm.
Поскольку я использую Mac, то сначала установлю rpk, утилиту командной строки для взаимодействия с Redpanda. Убедитесь, что на вашей рабочей станции установлен Docker.
Я буду использовать следующий файл docker-compose
, чтобы развернуть одноузловой кластер Redpanda.
version: '3.7'
services:
redpanda:
command:
- redpanda
- start
- '--smp'
- '1'
- '--reserve-memory'
- 0M
- '--overprovisioned'
- '--node-id'
- '0'
- '--kafka-addr'
- 'PLAINTEXT://0.0.0.0:29092,OUTSIDE://0.0.0.0:9092'
- '--advertise-kafka-addr'
- 'PLAINTEXT://redpanda:29092,OUTSIDE://localhost:9092'
image: 'docker.vectorized.io/vectorized/redpanda:v21.9.3'
ports:
- '9092:9092'
- '29092:29092'
Запустите команду docker-compose up -d
.
Для проверки состояния кластера выполните следующую команду:
rpk cluster info
Более подробную информацию о других вариантах установки можно найти здесь.
Создание темы и формирование сообщений
Давайте создадим тему для представления потока событий заказа.
rpk topic create orders
Вышеуказанная команда создает тему с одной партицией. Это может ограничить производительность и масштабируемость в будущем, поэтому для более глубокого анализа или изучения этой темы, следует выполнить дополнительную команду:
rpk topic describe orders
Произведите несколько записей о заказах в теме:
rpk topic produce orders
Введите текст в тему и нажмите Ctrl + D, чтобы разделить сообщения. Нажмите Ctrl + C, для выхода из команды produce (чтобы остановить процесс отправки сообщений (производство сообщений о заказах) в тему).
Мы будем использовать событие заказа, подобное представленному ниже. Преобразуйте его в строку и создайте несколько событий с разными значениями.
{
"id":12345,
"customer_id":101,
"total":45.99,
"order_date":"2021-10-09"
}
Потребление сообщений
rpk topic consume orders
В результате выполнения приведенной выше команды мы получим вывод, аналогичный следующему:
Обратите внимание, что в каждом сообщении присутствуют дополнительные данные, называемые метаданными.
Для получения дополнительной информации о всех доступных командах утилиты rpk, вы можете найти здесь.
Если вы привыкли использовать инструмент kafkacat (как и я), то не волнуйтесь – его также можно использовать с Redpanda, так как Redpanda совместим с API Kafka.
Ниже представлены команда для потребления (чтения) сообщений из темы orders
.
kcat -b localhost:9092 -t orders -C
Делаем потоковую обработку данных доступной с помощью технологии Materialize
Materialize — это база данных для работы с потоками данных в режиме реального времени. Она специализируется на аналитике в реальном времени и помогает разработчикам быстро создавать продукты, используя стандартный язык SQL.
Данная технология создана на языке программирования Rust и обладает низким порогом входа для разработчиков, которые не имеют опыта работы с JVM. Если вы не знакомы с Materialize, то можете прочитать мою статью ниже, где будет предоставлена базовая информация.
Итак, теперь, когда данные событий поступают в Redpanda, мы можем воспользоваться Materialize для создания простого обработчика потоков, который будет агрегировать информацию о событиях заказов и предоставлять результат в виде материализованного представления.
Установка
Что касается установки, то Materialize предоставляет несколько вариантов. Вы можете выбрать тот, который наиболее удобен для вас. В моем случае, я выберу установку через Homebrew на macOS.
Подключение с помощью psql
Для взаимодействия с Materialize мы можем воспользоваться инструментом командной строки psql
. Поскольку Materialize совместима с Postgres, этот инструмент будет полезен для работы с базой данных Materialize.
Введите указанный текст в новом окне терминала.
psql -U materialize -h localhost -p 6875 materialize
Определение источников данных из Kafka и материализованных представлений
Первый шаг — это определить источник данных из Kafka для чтения событий из темы orders. Этот источник будет работать “из коробки” без каких-либо изменений.
CREATE SOURCE orders
FROM KAFKA BROKER 'localhost:9092' TOPIC 'orders'
FORMAT BYTES;
Выполним команду SQL для получения списка столбцов, которые были созданы в таблице с названием "orders". При выполнении этой команды, система базы данных вернет список всех столбцов в таблице "orders", включая их имена, типы данных, дополнительные атрибуты и другие сведения о структуре таблицы:
SHOW COLUMNS FROM orders;
Однако Materialize пока не начнет внедрение данных.
Источник Kafka производит данные в виде JSON-строки. Чтобы извлечь JSON-поля для каждого заказа, вы можете использовать встроенные операторы jsonb:
CREATE VIEW orders_view AS
SELECT
(order_data ->'id')::INT as order_id,
(order_data ->'customer_id')::INT as customer_id,
(order_data ->'total')::FLOAT as total,
(order_data ->'order_date')::STRING as order_date
FROM (
SELECT convert_from(data, 'utf8')::jsonb AS order_data
FROM orders
);
Следует отметить, что здесь мы создали нематериализованное представление, которое не хранит результаты запроса, а просто предоставляет псевдоним для вложенного оператора SELECT.
Теперь мы можем использовать это представление в качестве основы для создания материализованного представления, которое будет вычислять общую стоимость продаж для каждого клиента:
CREATE MATERIALIZED VIEW sales_by_customer AS
SELECT
customer_id,
sum(total) as total_order_value
FROM orders_view
GROUP BY 1;
Представление sales_by_customer
инкрементально обновляется по мере поступления новых данных, поэтому вы получаете актуальные и правильные результаты с задержкой в миллисекунды. За кулисами Materialize индексирует результаты вложенного запроса в памяти (то есть материализует представление).
Давайте проверим результаты:
materialize=> select * from sales_by_customer;
customer_id | total_order_value
-------------+--------------------
100 | 32960.64999824762
101 | 22079.549998998642
102 | 25840.319998383522
103 | 38381.63999783993
104 | 28532.509998381138
105 | 26597.789998412132
(6 rows)
materialize=>
Если вы повторно выполните оператор SELECT в разные моменты времени, то сможете увидеть обновленные результаты на основе последних данных.
Заметьте, что мы выполнили несколько команд, чтобы запустить инкрементально обновляемое материализованное представление. Нет необходимости поддерживать кластеры Zookeeper, использовать JVM или предоставлять ресурсные менеджеры, такие как YARN (Yet Another Resource Negotiator), для деплоя потокового процессора.
Как только вы напишете свой SQL-код, Materialize просто начинает работать. Вот и все.
Визуализируем материализованное представление с помощью Dash
Вишенкой на торте будет визуализация содержимого материализованного представления. Для этого мы воспользуемся Dash, фреймворком с низким уровнем кода и возможностью быстрого создания приложений по работе с данными на языках Python, R, Julia и F#.
Следующий Python-скрипт читает представление sales_by_customer
внутри Materialize, как если бы это была обычная база данных Postgres. Затем он создает интерактивную столбчатую диаграмму (гистограмму) с использованием библиотеки Dash library. С ней можно взаимодействовать и анализировать ее в веб-приложении, сделанном с помощью Dash.
import psycopg2
import pandas.io.sql as sqlio
import pandas as pd
import dash
from dash import dcc
from dash import html
import plotly.express as px
app = dash.Dash(__name__)
# Connect to an existing database
conn = psycopg2.connect("dbname=materialize user=materialize port=6875 host=localhost")
sql = "select * from sales_by_customer;"
df = pd.read_sql_query(sql, conn)
fig = px.bar(df, x="customer_id", y="total_order_value")
# Main UI scaffolding
app.layout = html.Div(children=[
html.H1(children='Sales by customer'),
html.Div(children='''
Dash: A web application framework for your data.
'''),
dcc.Graph(
id='bar-chart',
figure=fig
)
])
if __name__ == '__main__':
app.run_server(debug=True)
conn = None
При выполнении в командной строке команды python3 app.py, запускается скрипт app.py с использованием интерпретатора Python 3, и как результат, на экране будет отображена панель управления (dashboard), похожая на эту:
Для практического применения Dash обратитесь к этому руководству.
Заключение
Традиционно в области потоковой обработки данных правили языки JVM, которые часто требовали специализированных навыков.
Платформы потоковых событий и приложения для обработки данных в режиме реального времени необходимо демократизировать. Это означает, что они должны стать более доступными и открытыми для широкого круга разработчиков, чтобы они могли свободно получить доступ к этим инструментам и активно их использовать.
Redpanda представляет собой переписанную на C++ версию Kafka, обеспечивающую 100% совместимость с его API. Redpanda не требует Zookeeper или JVM, что делает ее менее сложной для эксплуатации в продакшне. Отсюда и ее доступность для более широкой аудитории разработчиков.
Materialize упрощает создание приложений потоковой обработки данных, позволяя разработчикам, не использующих JVM, применять стандартный SQL для написания своей логики.
В настоящее время активно развиваются технологии, которые делают использование потоковой обработки, обработки данных в реальном времени и визуализации данных более удобным и доступным для разработчиков и пользователей. Я поддерживаю эту тенденцию, поскольку расширение доступа разработчикам означает больше приложений в реальном времени, что приводит к повышению качества обслуживания пользователей.
Ссылки
Почему разработчики предпочитают Redpanda, Ннамди Ирегбулем (Nnamdi Iregbulem)
Понимание распределенного консенсуса с помощью Raft, Касун Индрасири (Kasun Indrasiri)
В современных масштабируемых архитектурах системы могут быть составлены из множества сервисов, которые взаимодействуют друг с другом. При этом возникает сложная задача поддержания согласованности данных и обработки ошибок в случае сбоев. Элегантное решение для этих проблем предлагает паттерн Saga, позволяя управлять последовательностью транзакций, обеспечивая их атомарность и надежность. Приглашаем всех желающих на открытое занятие «Распределенные транзакции в System Design», которое пройдет 16 августа в 20:00.
Этот вебинар будет полезен разработчикам, архитекторам и техническим специалистам, заинтересованным в создании надежных и масштабируемых распределенных систем. Записаться можно по ссылке.
ivankudryavtsev
Сам исходный посыл автора статьи под большим вопросом; о том что есть какие-то проблемы с продуктами на базе JVM.
Отношусь к широким массам - использую Kafka. Полет нормальный. Поднадоели переводы и переводчики, которые не могут квалифицировать оригинальный контент. Дорогой переводчик, на Medium куча говна с большим количеством одобрения. Потому что это популизм и дешевые идеи, которые в головах народонаселения легко находят отклик.
Вот было на X, переделали на Y и засияло!