С увеличением вычислительных мощностей и пропускной способности каналов связи увеличились также и объемы обрабатываемых данных, а также требования к скорости обработки. Сейчас все больше систем требуют, чтобы работа с данными велась в режиме реального времени. Apache Kafka является распределённым программным брокером сообщений с открытым исходным кодом. Цель Kafka является создание горизонтально масштабируемой платформы для обработки потоковых данных в реальном времени с высокой пропускной способностью и низкой задержкой.

Еще одним популярным решением является использование архитектуры микросервисов для создания крупномасштабных приложений. Она позволяет разработчикам разделять сложные приложения на более мелкие, независимые и слабо связанные сервисы, которые взаимодействуют друг с другом с помощью упрощенных протоколов. В качестве инструмента взаимодействия может в том числе использоваться брокер Kafka. В этой статье мы рассмотрим методы, которые могут быть использованы для обеспечения эффективного взаимодействия между микросервисами с помощью Kafka.

Архитектура, управляемая событиями

Event Driven Architecture (EDA) архитектура, управляемая событиями представляет собой шаблон, который позволяет микросервисам взаимодействовать друг с другом с помощью событий. В этом шаблоне сервисы генерируют события при выполнении определенных действий, и другие микросервисы могут подписаться на эти события и реагировать соответствующим образом.

В качестве примера рассмотрим ситуацию, когда у нас есть один микросервис, который обрабатывает платежи, и другой, который отправляет уведомления клиентам. Когда мы производим платеж, микросервис платежей генерирует событие, содержащее платежную информацию, а микросервис уведомлений, подписанный на это событие отправляет уведомление клиенту.

Если говорить о реализации данной логики с помощью Kafka, то здесь мы можем использовать топики для реализации архитектуры, управляемой событиями. В таком случае у нас каждый топик может представлять определенное событие, и службы могут подписываться на интересующие их топики.

В примерах кода ниже мы сначала создаем продьюсеров:

from kafka import KafkaProducer
# Kafka broker configuration
bootstrap_servers = 'localhost:9092'
# Create Kafka producer
producer = KafkaProducer(bootstrap_servers=bootstrap_servers)
# Define the topic to produce messages to
topic = 'test_topic'
# Produce a message
message = 'Hello, Kafka Broker!'
producer.send(topic, value=message.encode('utf-8'))
# Wait for the message to be delivered to Kafka
producer.flush()
# Close the producer
producer.close()

 А в следующем фрагменте создаем консьюмера:

from kafka import KafkaConsumer
 # Kafka broker configuration
bootstrap_servers = 'localhost:9092'
 # Create Kafka consumer
consumer = KafkaConsumer(bootstrap_servers=bootstrap_servers)
 # Define the topic to consume messages from
topic = 'test_topic'
 # Subscribe to the topic
consumer.subscribe(topics=[topic])
 # Start consuming messages
for message in consumer:
    # Process the consumed message
    print(f"Received message: {message.value.decode('utf-8')}")
 # Close the consumer
consumer.close()

Наши участники информационного обмена взаимодействуют друг с другом через топик test_topic. При этом консьюмер обрабатывает каждое полученное сообщение.

Запрос-ответ

Еще один распространенный способ взаимодействия микросервисов друг с другом это шаблон Request‑Response. Здесь модель взаимодействия можно назвать более классической, так как микросервис просто отправляет запрос другому микросервису и ожидает ответа.

Например, предположим, что у нас есть микросервис, который обрабатывает заказы, и другой микросервис, который проверяет наличие товаров на складе, проще говоря проводит инвентаризацию. Всякий раз, когда клиент размещает заказ, микросервис заказа может отправить запрос в микросервис инвентаризации, чтобы проверить, доступен ли товар. Затем микросервис инвентаризации может отправить ответ, указывающий, на наличие товара. 

В Kafka каждый запрос может быть отправлен в определенный топик, а ответ может быть также отправлен обратно в топик для подтверждения.

Command Query Responsibility Segregation

Command Query Responsibility Segregation (CQRS) — разделение ответственности за командный запрос это шаблон, который разделяет операции чтения и записи в микросервисе. В этом шаблоне один микросервис отвечает за обработку команд (операции записи), а другой микросервис отвечает за обработку запросов (операции чтения).

Например, предположим, что у нас есть микросервис, который управляет профилями клиентов. Другой микросервис может отвечать за обработку операций чтения, таких как получение информации о клиентах. Операции записи могут выполняться другим микросервисом, который обновляет информацию о клиентах.

В Kafka мы можем использовать топики для разделения операций чтения и записи. Каждый микросервис может публиковать сообщения в определенном топике, а другие сервисы могут подписываться на эти топики для получения или обновления информации.

Замеряем производительность

Далее мы поговорим о том, как измерить производительность процесса взаимодействия между микросервисами с помощью Kafka. Для мониторинга Kafka содержит несколько показателей, которые можно использовать для оценки производительности системы обмена сообщениями. Прежде всего это пропускная способность, то есть скорость, с которой Kafka обрабатывает сообщения. Ее можно измерить в сообщениях в секунду или байтах в секунду.

Также важной характеристикой является задержка, то есть время, необходимое для доставки сообщения от продьюсера к консьюмеру. Это значение может измеряться в миллисекундах.

При обмене сообщениями важно учитывать размер сообщений, пересылаемых между микросервисами. Чрезмерно большие сообщения могут повлиять на производительность системы обмена сообщениями.

Ну и еще одним важным показателем является размер очередей, то есть интервал времени, в течение которого сообщения находятся в топике. Увеличение этого интервала может говорить проблем с производительностью.

Мониторинг этих показателей может помочь в выявлении любых проблем с производительностью и принятии соответствующих мер для улучшения взаимодействия между микросервисами.

Решаем проблемы

Проблемы с производительностью могут быть самыми разнообразными, и не всегда их причина кроется в самом ПО Kafka. Проблемы могут быть с аппаратной частью, каналами связи, настройками ОС и инфраструктурного ПО, и многим другим. Однако, давайте рассмотрим несколько методов, которые можно использовать для повышения производительности взаимодействия между микросервисами с помощью Kafka.

Здесь начать стоит с оптимизации размера сообщений с помощью сжатия данных может повысить производительность системы обмена. В Kafka поддерживаются пять типов сжатия: none, gzip, snappy, lz4 и zstd. В общем случае для повышения производительности рекомендуется использовать lz4. При этом популярный gzip не рекомендуется к использованию из‑за высоких накладных расходов. Но, если вы ищете степень сжатия, аналогичную gzip, но с меньшими накладными расходами процессора, попробуйте использовать zstd. Следует помнить, что каждый уникальный конвейер или приложение требует тестирования для определения оптимального типа сжатия.

Также важным элементом повышения производительности является секционирование (partitioning), которое позволяет Kafka распределять сообщения между несколькими брокерами и увеличивать пропускную способность системы обмена сообщениями. Разделение может основываться на различных критериях, таких как тип сообщения, время или идентификатор клиента. Масштабирование консьюмеров может улучшить обработку сообщений и увеличить пропускную способность системы обмена сообщениями. Kafka позволяет масштабировать консьюмеров по горизонтали, добавляя больше экземпляров потребителей.

И, наконец, гибкая настройка параметров конфигурации Kafka, таких как размер пакета, размер буфера и коэффициент репликации, может повысить производительность системы обмена сообщениями.

Заключение

Apache Kafka это достаточно мощный инструмент, позволяющий решить различные задачи. В этой статье мы рассмотрели основные шаблоны для работы с микросервисами и некоторые вопросы мониторинга производительности.

А в завершение хочу порекомендовать вам ряд бесплатных вебинаров курса Microservice Architecture:

Комментарии (6)


  1. Gabenskiy
    03.10.2024 08:51
    +2

    Вместо статьи для рекламы можно было что-то посущественнее написать.


  1. yri066
    03.10.2024 08:51

    Можете дать совет в каком направлении можно копать: только недавно познакомился с Kafka, когда запускаю несколько экземпляров приложения и они подключается к одной теме, то перед тем как они начнут читать сообщения, приходится ждать минут 10 когда начнется перебалансировка. Есть способ как-нибудь это ускорить? (в kafka настройки по умолчанию).


    1. IlyaEdrets
      03.10.2024 08:51

      Очень странное поведение. На моем опыте обычно несколько реплик (3-5) балансируются меньше минуты.


  1. boov
    03.10.2024 08:51

    Гарантирует ли kafka порядок доставки сообщений до консьюмеров? Т.е. сперва придут все сообщения N1, затем N2 и тд. от продьюсеров и N2 не придёт вперёд N1.


    1. return_nullptr
      03.10.2024 08:51
      +1

      Kafka гарантирует порядок доставки в рамках одного партишна топика (topic partition). Сообщения из разных партишнов могут быть получены разными консюмерами и обработаны в любом порядке.


    1. IlyaEdrets
      03.10.2024 08:51
      +1

      Все начинается от продьюсеров. Для сообщений где порядок важен, должен использоваться один и тот же ключ при отправке сообщения в топик. Сообщения с одинаковым ключом попадут в одну и ту же партицию. Каждая партиция читается только одним консьюмером и строго последовательно