Apache Kafka способен обеспечивать невероятно высокую пропускную способность. Он славится такими впечатляющими достижениями, как поддержка 20 миллионов заказов в час для рассылки тестов на COVID гражданам США во время пандемии. Достичь такого уровня масштабируемости позволяет подход Kafka к партиционированию топиков. Партиции, содержащиеся в топиках, являются основной "единицей параллелизма" в Kafka. Что такое единица параллелизма? Это как несколько кассиров в одном магазине вместо одного. Можно одновременно совершать несколько покупок, что увеличивает общее количество покупок, совершенных за то же время (по сути пропускная способность). В данной аналогии кассир является единицей параллелизма.   В Kafka каждый лидер партиции может находиться на отдельном брокере в кластере, и продюсер может отправлять несколько сообщений, каждое из которых имеет свою партицию в качестве пункта назначения; то есть продюсер может отправлять их параллельно. Хотя это основная причина, по которой Kafka обеспечивает высокую пропускную способность, сжатие также может быть инструментом, помогающим повысить пропускную способность и эффективность за счет снижения сетевого трафика благодаря уменьшению размера сообщений. Хорошо реализованная стратегия сжатия также выливается в более эффективное использование дискового пространства в Kafka, поскольку хранящиеся на диске сообщения имеют меньший размер.  Продюсеры Kafka сжимают данные путем пакетной обработки данных, поступающих в одну и ту же партицию. Обычно это работает следующим образом: за сжатие отвечает продюсер, а тип сжатия топика (compression.type) — producer.  Почему на уровне партиции, а не на уровне всего топика? Продюсеры общаются с лидерами партиций. Если сжимать данные для нескольких разделов в одном пакете, то этот пакет должен будет отправиться к нескольким лидерам, что приведет к передаче большего количества данных, а значит, сжатие не будет оправдывать затраченных усилий. Для проверки данных брокеры всегда выполняют некоторую пакетную декомпрессию. Внутри класса LogValidator реализуется логика проверки, а декомпрессия сообщений в конечном итоге происходит в реализации wrapForInput соответствующего CompressionType. Следующие сценарии всегда требуют полной декомпрессии полезной нагрузки: Продюсер сжимает батчи (т.е. compression.type не none), а на уровне топика compression.type задает другой кодек или сжатия не происходит. Вы используете брокеры Confluent Server и включили проверку схем в топике. Если топик уплотнен, брокер также будет периодически распаковывать все сжатые пакеты, чтобы отфильтровать записи, пригодные для уплотнения. Итак, какого же размера батчи должен быть установлены у продюсеров? (Следует помнить, что конечный размер батча определяется двумя параметрами конфигурации: верхней границей размера батча batch.size и максимальным временем заполнения батча linger.ms). Как и многие другие настройки в Kafka, это зависит от конкретного сценария. Преимуществом небольшого размера пакета является экономия памяти и уменьшение задержки; с другой стороны, большой размер пакета увеличивает пропускную способность, но занимает больше памяти. Производительность сжатия важна с точки зрения производителя, а производительность распаковки — с точки зрения потребителя. Не будем забывать и о брокерах: для брокеров важна производительность распаковки, а производительность сжатия имеет значение, если используемый брокером compression.type уровне топика отличается от того, который использовал продюсер. Производительность во многом зависит от типа сжатия.  Существует пять типов сжатия:   none gzip snappy lz4 zstd none (или, если вы задаете эту конфигурацию из топика, uncompressed) означает, что сжатия происходить не будет. Остальные настройки представляют собой различные алгоритмы сжатия, поддерживаемые Kafka. В общем случае для повышения производительности рекомендуется использовать lz4. gzip не рекомендуется из-за высоких накладных расходов; если вы ищете степень сжатия, аналогичную gzip, но с меньшими накладными расходами процессора, попробуйте использовать zstd. Следует помнить, что каждый уникальный конвейер или приложение требует тестирования для определения оптимального типа сжатия.  Важная деталь реализации: существует два места для установки compression.type — на уровне топика и на уровне продюсера. Тип сжатия на уровне топика может быть сконфигурирован так, чтобы давать приоритет типу производителя с помощью метко названной настройки producer. Остальные типы сжатия на уровне топика имеют приоритет над типом сжатия на уровне продюсера и будут переопределять по части кодека, используемого для хранения сообщений на брокере и отправки их потребителям. В следующей таблице приведены рекомендации по часто используемым комбинациям типов сжатия, а также сценарии, в которых стоит рассмотреть и протестировать менее распространенные комбинации. compression.type топика  compression.type продюсера Тип сжатия для связи между продюсером и брокером Тип сжатия для хранения данных на брокере и обмена данными между брокером и потребителем Разъяснение producer none тип сжатия продюсера тип сжатия продюсера Это нетронутое значение по умолчанию, т.е. то, что вы получите, если не будете указывать значения. Считается подходящим для разработки, но не рекомендуется для производства, если это не подтверждено тестированием производительности. producer gzip, snappy, lz4, zstd тип сжатия продюсера тип сжатия продюсера Это распространенная комбинация, возлагающая ответственность на продюсера. gzip, snappy, lz4, zstd (что-то иное, чем у топика, но не "none") тип сжатия продюсера тип сжатия топика В этой ситуации брокер должен будет выполнить повторную компрессию (используя тип сжатия топика). Обычно это нежелательный результат, но в некоторых случаях он может быть применим, например, когда старые производители используют различные подходы к сжатию, а вы хотите обеспечить применение нового типа сжатия на уровне кластера. gzip, snappy, lz4, zstd (то же, что и топик) тип сжатия продюсера тип сжатия топика Не рекомендуется, так как при изменении типа сжатия продюсера брокер будет переопределять его, что обычно нежелательно. Предлагаем вместо этого использовать topic compression.type = producer. gzip, snappy, lz4, zstd none тип сжатия продюсера тип сжатия топика Такие комбинации встречаются редко, но могут применяться в некоторых исключительных случаях, например, когда продюсер или потребитель ограничены процессором, но не имеют узких мест в сети. В первом случае от производителя не требуется сжатия, но топики все равно сжимаются при хранении или передаче потребителю. Не рекомендуется использовать в качестве начальной конфигурации, но может быть рассмотрена только после тщательного анализа сквозной пропускной способности. uncompressed gzip, snappy, lz4, zstd тип сжатия продюсера тип сжатия топика То же, что и выше. uncompressed none тип сжатия продюсера тип сжатия топика Не рекомендуется, так как при изменении типа сжатия продюсера брокер переопределит его и будет хранить/передавать данные потребителю в несжатом виде, что обычно нежелательно. Предлагаем вместо этого использовать topic compression.type = producer. Сжатые данные должны быть также распакованы! Как сжатие обычно повышает пропускную способность продюсера, так и сжатие повышает пропускную способность потребителя (консумера), только за счет декомпрессии, которая зависит от типа сжатия. Сжатые сообщения идентифицируются специальным заголовком, который "распознается" потребителем. Затем он распаковывает все полученные сжатые сообщения и возвращает только распакованные.  Теперь потребитель может обрабатывать как сжатые, так и несжатые сообщения. Разделение продюсера и потребителя является одним из основных преимуществ использования Kafka. Поскольку потребитель справляется с этой несогласованностью, обрабатывая оба типа сообщений, он может обрабатывать сообщения от продюсера, которые посылают как сжатые, так и несжатые сообщения. Однако, учитывая, что сжатие влияет на загрузку процессора, сети и диска от продюсеров к брокерам и потребителям, для достижения оптимальной сквозной производительности необходимо согласовать тип сжатия между продюсерами. Несколько советов, которые могут помочь вам избежать некоторых неприятных ошибок.  Прежде всего, следует помнить, что зашифрованные данные не следует сжимать; шифрование рандомизирует структуру информации, поэтому результат обычно плохо сжимается. С другой стороны, можно шифровать данные, которые уже были сжаты.  Далее, когда речь идет о стандартных элементах конфигурации, всегда полезно перепроверить, соответствуют ли они ожидаемым в ваших реализациях. Совпадают ли они между клиентом и оригинальным дистрибутивом? В этой связи следует отметить, что тип сжатия в заголовке не доходит до потребителя, поэтому для проверки файлов на брокере можно использовать инструмент DumpLogSegments. Команда выглядит следующим образом:   А вывод JSON содержит используемый кодек сжатия:  Если эта статья вызвала у вас интерес и вы хотите узнать больше, вот некоторые рекомендации:  Запрос клиента: Туда и обратно — Узнайте о конфигурации продюсера и потребителя из доклада Даники Файн (Danica Fine) на Kafka Summit London В документации по Batch.size и linger.ms дается официальное описание этих настроек Compression.type: Документация для продюсера Оптимизация и настройка клиентов Confluent Cloud: Руководство по оптимизации клиентов Confluent Cloud, включая управление пропускной способностью Как настроить продюсерский клиент Apache Kafka: Используйте инструмент producer-perf-test для просмотра пропускной способности и других метрик Напоследок всех желающих приглашаем на открытое занятие «Место Kafka в событийно-ориентированных системах». Записаться можно на странице онлайн-курса Apache Kafka.  Редактор