Продюсеры и сжатие данных  

Apache Kafka способен обеспечивать невероятно высокую пропускную способность. Он славится такими впечатляющими достижениями, как поддержка 20 миллионов заказов в час для рассылки тестов на COVID гражданам США во время пандемии. Достичь такого уровня масштабируемости позволяет подход Kafka к партиционированию топиков.

Партиции, содержащиеся в топиках, являются основной "единицей параллелизма" в Kafka. Что такое единица параллелизма? Это как несколько кассиров в одном магазине вместо одного. Можно одновременно совершать несколько покупок, что увеличивает общее количество покупок, совершенных за то же время (по сути пропускная способность). В данной аналогии кассир является единицей параллелизма.  

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

За счет чего достигается сжатие данных в продюсере Kafka? 

Продюсеры Kafka

Продюсеры Kafka сжимают данные путем пакетной обработки данных, поступающих в одну и ту же партицию. Обычно это работает следующим образом: за сжатие отвечает продюсер, а тип сжатия топика (compression.type) — producer. 

compression-in-kafka-producer
compression-in-kafka-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 

Важная деталь реализации: существует два места для установки 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

Сжатые данные должны быть также распакованы! Как сжатие обычно повышает пропускную способность продюсера, так и сжатие повышает пропускную способность потребителя (консумера), только за счет декомпрессии, которая зависит от типа сжатия. Сжатые сообщения идентифицируются специальным заголовком, который "распознается" потребителем. Затем он распаковывает все полученные сжатые сообщения и возвращает только распакованные

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

Прежде чем вы закроете страницу...

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

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

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

kafka-run-class kafka.tools.DumpLogSegments --files /path/to/log/file --print-data-log

А вывод JSON содержит используемый кодек сжатия: 

compresscodec: <CODEC>

Ресурсы

Если эта статья вызвала у вас интерес и вы хотите узнать больше, вот некоторые рекомендации: 

Напоследок всех желающих приглашаем на открытое занятие «Место Kafka в событийно-ориентированных системах». Записаться можно на странице онлайн-курса Apache Kafka.

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