{"id":20645041,"url":"https://github.com/romanow/kafka-streams","last_synced_at":"2026-04-17T20:31:29.049Z","repository":{"id":146005646,"uuid":"439245139","full_name":"Romanow/kafka-streams","owner":"Romanow","description":null,"archived":false,"fork":false,"pushed_at":"2021-12-24T16:05:17.000Z","size":3274,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-09T15:54:36.551Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Romanow.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-12-17T07:19:53.000Z","updated_at":"2024-09-24T11:48:37.000Z","dependencies_parsed_at":null,"dependency_job_id":"223b5f87-2af8-434a-b33d-53367c7c239a","html_url":"https://github.com/Romanow/kafka-streams","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Romanow/kafka-streams","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Romanow%2Fkafka-streams","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Romanow%2Fkafka-streams/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Romanow%2Fkafka-streams/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Romanow%2Fkafka-streams/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Romanow","download_url":"https://codeload.github.com/Romanow/kafka-streams/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Romanow%2Fkafka-streams/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31944950,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-17T17:29:20.459Z","status":"ssl_error","status_checked_at":"2026-04-17T17:28:47.801Z","response_time":62,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-16T16:18:29.979Z","updated_at":"2026-04-17T20:31:29.024Z","avatar_url":"https://github.com/Romanow.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Kafka Streams\n\nKafka Streams — это Java-библиотека для анализа и обработки данных, хранящихся в Apache Kafka. Как и в любой другой\nплатформе потоковой обработки, она способна выполнять обработку данных с сохранением и/или без сохранения состояния в\nрежиме реального времени.\n\nГлавная абстракция Kafka Streams – это поток – неограниченный и постоянно обновляемый набор данных в виде упорядоченной,\nвоспроизводимой и отказоустойчивой последовательности неизменяемых парных записей «ключ-значение» (key-value).\nВычислительная логика приложений потоковой обработки, использующих библиотеку Apache Kafka Streams, работает по графовой\nмодели обработчиков потоков (вершин), связанных между собой потоками (ребрами). В этой топологии обработчик является\nузлом преобразования данных в потоки, который выполняет следующие действия [1]:\n\n* получает по одной входной записи за раз от вышестоящих узлов;\n* применяет к входящей записи свою операцию (агрегация, фильтр и пр.);\n* создает одну или несколько выходных записей для своих нижестоящих узлов.\n\n* Различают 3 вида обработчиков потоков Apache Kafka Streams:\n\n* источник (source processor), который не имеет вышестоящих узлов, он создает входной поток в свою топологию из одному\n  или нескольким топикам Кафка, потребляя из них записи и направляя их на свои нижестоящие узлы;\n* обычный обработчик потока (stream processor), который получает входной поток от вышестоящих узлов, обрабатывает его и\n  отправляет нижестоящим узлам, при этом обработанные результаты могут быть либо переданы обратно в Kafka, либо записаны\n  во внешнюю систему;\n* приемник (sink processor), который не имеет нижестоящих узлов, он отправляет все полученные записи от своих\n  вышестоящих обработчиков в указанный топик Кафка.\n\n![Topology](images/topology.png)\n\nВ качестве логических единиц своей модели параллелизма Kafka Streams использует концепции потоковых разделов и потоковых\nзадач (stream task). При этом между Кафка и Kafka Streams существуют следующие связи:\n\n* каждый потоковый раздел (stream partition) представляет собой полностью упорядоченную последовательность записей\n  данных в соответствии с разделом топика (topic partition) Кафка;\n* запись данных в потоке отображает сообщение из топика Кафка;\n* ключи записей определяют разбиение данных по разделам (partition) в Кафка и Kafka Streams (то, как данные направляются\n  в определенные разделы топиков).\n\nТопология программного обработчика масштабируется путем разбивки его на несколько потоковых задач: Kafka Streams создает\nфиксированное количество потоковых задач на основе входных потоковых разделов (stream partition) для приложения. При\nэтом каждой задаче назначается свой список топиков Кафка. Назначение потоковых разделов потоковым задачам никогда не\nменяется, поэтому потоковая задача является фиксированной единицей параллелизма приложения. Задачи могут создавать свою\nсобственную топологию потоковых обработчиков на основе назначенных разделов, буферизируя каждый раздел и обрабатывая по\nодной записи за раз из этих буферов.\n\nОтметим, что Kafka Streams позволяет настраивать количество веток (thread) для распараллеливания обработки в экземпляре\nприложения. При этом каждая ветка может независимо выполнять одну или несколько задач с своими топологиями обработки.\nЗапуск большего количества потоковых веток или большего количества экземпляров приложения сводится к репликации\nтопологии и позволяет обрабатывать другое подмножество разделов Kafka, эффективно распараллеливая обработку. Поскольку\nмежду потоками нет общего состояния, нет необходимости в их координации, что позволяет очень просто запускать разные\nтопологии обработки параллельно между экземплярами приложения и потоками. Назначение разделов топика Кафка среди\nразличных потоковых веток обрабатывается Kafka Streams с помощью координации Kafka.\n\n## Topic, Stream, Table\n\nСтрим в Kafka — это полная история всех случившихся событий в мире с начала времён по сегодняшний день. Он представляет\nпрошлое и настоящее. По мере того, как мы переходим из сегодняшнего дня в завтрашний, новые события постоянно\nдобавляются к мировой истории.\n\nТаблица в Kafka — это состояние мира на сегодняшний день. Она представляет настощее. Это совокупность (aggregation) всех\nсобытий в мире, которая постоянно изменяется по мере того, как мы переходим из сегодняшнего в завтрашний.\n\n![Topic to Stream to Table](images/topic_to_stream_to_table.png)\n\n### Topic\n\nТопик в Kafka состоит из сообщений ключ-значение. Топик не зависит от формата сериализации или типа сообщений: ключи и\nзначения в сообщениях трактуются как обычные массивы байтов `byte[]`.\n\n![Plain Stream](images/plain_stream.gif)\n\n![Counter Stream](images/counter_stream.gif)\n\n### Stream\n\nТеперь мы читаем топик в стрим, добавляя информацию о схеме (schema-on-read). Другими словами, counter превращаем сырой,\nнетипизированный топик в типизированный топик или стрим.\n\n### Table\n\nТаблицы — это агрегированные стримы. Всякий раз, когда вы выполняете агрегацию в Kafka Streams или KSQL, результатом\nвсегда является таблица. Особенность этапа агрегирования определяет, является ли таблица напрямую получаемой из стрима\nчерез семантику UPSERT без состояния (таблица отображает ключи в их последнее значение в стриме, который является\nагрегацией при чтении топика Kafka напрямую в таблицу), через подсчёт количества увиденных значений для каждого ключа с\nсохранением состояния, или более сложные агрегации, такие как суммирование, усреднение и так далее.\n\n![Changelog](images/changelog.gif)\n\nПотоки изменений Кафка Стримс непрерывно резервируются (back up) и сохраняются в виде топиков Kafka, обеспечивая\nэластичность и отказоустойчивость. Это позволяет перемещать задачи между узлами кластера, виртуальными машинами или\nконтейнерами без потери данных в течение всех операций, независимо от необходимости сохранения состояний (stateful) или\nее отсутствия (stateless). Таблица является частью состояния (state) потокового приложения Kafka Streams или запроса\nKSQL, благодаря чему Кафка переносит между узлами кластера не только код обработки, но и само состояние приложения с\nпомощью changelog stream. Например, когда требуется переместить таблицу с клиентской машины A на машину B, то на узле B\nтаблица реконструируется из её потока изменений в состояние, идентичное исходному (на машине A).\n\n### Windows\n\nОкна позволяют группировать нужные записи с одинаковым ключом для операций с сохранением состояния (stateful). Окна\nотслеживаются по ключу записи, чтобы обеспечить правильное разбиение данных («ключ») для последующих операций. После\nпервичной агрегации по ключу возможно дополнительно группировать нужные записи. Например, в операциях объединения (join)\nоконное хранилище состояний (windowing state store) используется для хранения всех записей, полученных в пределах\nопределенной границы этого окна. В операциях агрегирования оконное хранилище состояний используется для хранения\nпоследних результатов агрегации каждого окна.\n\nВ Kafka Streams существует 3 типа окон:\n\n* сеансовые (session), которые отражают интервалы активности и ограничиваются периодами бездействия пользователя,\n  приложения, сервиса или другой активной сущности, поведение которой требуется отслеживать;\n  ![Session Window](images/session_window.png)\n* кувыркающиеся (tumbling), которые захватывают события, попадающие в определенный промежуток времени. Например, все\n  биржевые транзакции заданной компании каждые 20 секунд, по окончании которых окно «кувыркается» и переходит на новый\n  20-секундный интервал наблюдения;\n  ![Tumbling Window](images/tumbling_window.png)\n* скользящие (sliding) и прыгающие (hopping), которые не ждут окончания интервала времени перед созданием нового окна\n  для обработки недавних событий, а запускают новые вычисления после интервала ожидания, меньшего чем длительность окна.\n  Например, требуется подсчитывать число биржевых транзакций каждые 20 секунд, но обновлять счетчик — каждые 5 секунд.\n  ![Hopping Window](images/hopping_window.png)\n\n### Schema Registry\n\nSchema Registry обеспечивает нужный уровень обслуживания для метаданных, предоставляет Restful-API для хранения и\nполучения схем AVRO, а также поддерживает эволюцию схемы, храня историю всех версий. Еще реестр схем предоставляет\nнесколько параметров совместимости, позволяя изменять схемы в соответствии с этими параметрами. Наконец, Schema Registry\nпредоставляет сериализаторы, которые подключаются к клиентам Kafka, обрабатывают хранение и извлечение схемы для\nсообщений в формате AVRO.\n\n## Примеры\n\n```shell\n$ docker compose up -d\n[+] Running 7/7\n ⠿ Network kafka-streams_default  Created                                                                                                                                                 0.3s\n ⠿ Container zookeeper            Started                                                                                                                                                 1.1s\n ⠿ Container kafka-2              Started                                                                                                                                                 2.2s\n ⠿ Container kafka-1              Started                                                                                                                                                 2.4s\n ⠿ Container kowl                 Started                                                                                                                                                 3.7s\n ⠿ Container ksqldb-server        Started                                                                                                                                                 3.8s\n ⠿ Container control-center       Started  \n```\n\n```\nCREATE STREAM github (\n  id VARCHAR, \n  type VARCHAR, \n  repo STRUCT\u003c\n  \tid INT, \n  \tname VARCHAR, \n  \turl VARCHAR,\n  \tlanguage VARCHAR\n  \u003e)\nWITH (\n  KAFKA_TOPIC='github-change-events', \n  VALUE_FORMAT='json'\n);\n\nSELECT repo-\u003elanguage, count(repo-\u003eid) FROM GITHUB GROUP BY repo-\u003elanguage EMIT CHANGES;\n\nCREATE TABLE GITHUB_REPO AS SELECT\n  count(repo-\u003ename) AS repos,\n  repo-\u003elanguage AS lang\nFROM github\nGROUP BY repo-\u003elanguage\nEMIT CHANGES;\n```\n\n## Литература\n\n1. [KSQL Syntax Reference](https://docs.confluent.io/5.4.1/ksql/docs/developer-guide/syntax-reference.html)\n2. [Путешествуем во времени и пользовательском пространстве с Apache Kafka Streams](https://www.bigdataschool.ru/blog/windows-kafka-streams.html)\n3. [AVRO и JSON В Apache Kafka: краткий ликбез по реестру схем](https://www.bigdataschool.ru/blog/avro-json-and-schema-registry-in-kafka.html)\n4. [Как работает Apache Kafka Streams: архитектура и топология внутренних обработчиков потоков](https://www.bigdataschool.ru/blog/streaming-processors-kafka-streams.html)\n5. [Streams Architecture](https://docs.confluent.io/platform/current/streams/architecture.html)\n6. [Introducing Kafka Streams: Stream Processing Made Simple](https://www.confluent.io/blog/introducing-kafka-streams-stream-processing-made-simple/)\n7. [Обеспечение высокой доступности приложений с Kafka Streams](https://habr.com/ru/post/488558/)\n8. [Почему стриминг на KSQL и Kafka Streams — это непросто](https://habr.com/ru/company/glowbyte/blog/492944/)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fromanow%2Fkafka-streams","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fromanow%2Fkafka-streams","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fromanow%2Fkafka-streams/lists"}