В этой статье я представляю исследование по сравнению сред для Apache Kafka. Конечная цель — найти наиболее эффективную настройку и достичь наилучшего соотношения цены и качества.
Наша платформа данных предоставляет управляемые услуги по созданию аналитических платформ для больших наборов данных, конкурирующих с другими рыночными решениями. Чтобы оставаться конкурентоспособными, мы регулярно проводим внутренние исследования, чтобы выявить и улучшить наши сильные стороны, обеспечивая более выгодные сделки. В этой статье представлено одно из таких исследований. В настоящее время наша платформа поддерживает AWS и GCP в качестве поставщиков облачных услуг. Оба предлагают несколько поколений вычислений и две архитектуры ЦП (x86 с Intel и AMD и ARM). Я сравниваю эти настройки с использованием различных виртуальных машин Java (JVM), чтобы оценить производительность новых версий на новых процессорах.
Если вам нужен TL;DR: ARM великолепен. Современная дорогая архитектура не всегда означает «лучше». Вы можете сразу перейти к результатам или перейти к более подробной информации о методологии и настройке.
Я рассматривал возможность тестирования производительности с помощью нашего собственного сервиса, но хотел сравнить ее в различных средах, которые мы еще не поддерживали. Я хотел проверить новые виртуальные машины, регионы и даже других поставщиков облачных услуг. Итак, я начал с реализации игрушечного проекта, который использует базовый Kafka с различными базовыми образами контейнеров. Таким образом, я могу запускать тестовые инструменты на конкретном оборудовании и измерять производительность.
Я стремлюсь протестировать различные конфигурации, чтобы выявить наиболее интересные результаты. Для этого я использую идею матрицы тестирования для фильтрации первоначальных результатов. Я подробно проанализирую эти результаты, используя такие инструменты, как perf и eBPF, для дальнейшего повышения производительности.
Давайте сначала опишем цели тестирования. У меня большой опыт работы с JVM OpenJDK, но сегодня существует множество альтернатив от Microsoft, Amazon и других компаний. Например, Amazon Correto включает дополнительные функции и исправления, оптимизированные для AWS. Поскольку большинство наших клиентов используют AWS, я хотел включить в тесты Amazon Correto, чтобы увидеть, как эти JVM работают на этой платформе.
Для первого сравнения я выбрал эти версии:
После того как версии были определены, я подготовил несколько скриптов для создания образов Kafka с использованием Amazon Correto и OpenJDK .
Для тестов производительности я изменил настройки Kafka, чтобы сосредоточиться на конкретных показателях производительности. Я хотел протестировать различные комбинации [JVM] x [instance_type] x [architecture] x [cloud_provider] , поэтому было важно минимизировать влияние сетевого подключения и производительности диска. Я сделал это, запустив контейнеры с tmpfs для хранения данных:
podman run -ti \ --network=host \ --mount type=tmpfs,destination=/tmp \ kfbench:3.6.1-21.0.2-amzn-arm64
Естественно, эта установка не предназначена для производства, но изолировать узкие места процессора и памяти было необходимо. Лучший способ — исключить из тестов влияние сети и диска. В противном случае эти факторы исказят результаты.
Я использовал инструмент тестирования на том же экземпляре, чтобы обеспечить минимальную задержку и более высокую воспроизводимость. Я также пробовал тесты без конфигураций хост-сети и с виртуальными сетями, изолированными cgroup, но это только добавляло ненужную задержку и увеличивало загрузку ЦП для пересылки пакетов.
Хотя tmpfs динамически распределяет память и может вызвать фрагментацию и задержку, для нашего теста этого было достаточно. Вместо этого я мог бы использовать виртуальный диск, который распределяет память статически и позволяет избежать этих проблем, но tmpfs было проще реализовать, и он все равно давал ту информацию, которую мы искали. Для наших целей это обеспечило правильный баланс.
Кроме того, я применил некоторые дополнительные настройки Kafka, чтобы чаще удалять данные из памяти:
############################# Benchmark Options ############################# # https://kafka.apache.org/documentation/#brokerconfigs_log.segment.bytes # Chaged from 1GB to 256MB to rotate files faster log.segment.bytes = 268435456 # https://kafka.apache.org/documentation/#brokerconfigs_log.retention.bytes # Changed from -1 (unlimited) to 1GB evict them because we run in tmpfs log.retention.bytes = 1073741824 # Changed from 5 minutes (300000ms) to delete outdated data faster log.retention.check.interval.ms=1000 # Evict all data after 15 seconds (default is -1 and log.retention.hours=168 which is ~7 days) log.retention.ms=15000 # https://kafka.apache.org/documentation/#brokerconfigs_log.segment.delete.delay.ms # Changed from 60 seconds delay to small value to prevent memory overflows log.segment.delete.delay.ms = 0
Вот краткий обзор изменений:
Эта конфигурация не подходит для промышленного использования, но она важна для наших тестов производительности, поскольку снижает влияние нерелевантных факторов.
На момент написания этой статьи в DoubleCloud мы поддерживали следующие основные поколения вычислительных ресурсов:
Для процессоров Graviton мы поддерживаем:
Кроме того, я тестировал экземпляры t2a на GCP в качестве альтернативы Graviton на Ampere Altra. Мы не предлагаем их нашим клиентам из-за ограниченной региональной поддержки AWS, но я включил их в тесты для сравнения производительности. Это может быть хорошим вариантом, если вы находитесь в одном из «правильных» регионов.
Для бенчмаркинга я разработал облегченный инструмент на основе библиотеки franz-go и примера . Этот инструмент эффективно насыщает Kafka, не становясь при этом узким местом.
Хотя librdkafka известна своей надежностью и популярностью, я избегал ее из-за потенциальных проблем с cgo.
Kafka хорошо известен своей масштабируемостью, позволяющей разделять темы на несколько разделов для эффективного горизонтального распределения рабочих нагрузок между брокерами. Однако я сосредоточился на оценке одноядерной производительности, чтобы уделить особое внимание соотношению производительности и цены.
Поэтому в тестах использовались темы с одним разделом, чтобы полностью использовать возможности отдельных ядер.
Каждый тестовый пример включал два типа:
Я использовал сообщения размером 8 КБ, что больше, чем среднестатистический клиентский запрос, чтобы полностью заполнить потоки тематических разделов.
Я представляю серию графиков, сравнивающих различные тестовые примеры с использованием синтетической метрики эффективности для оценки различных архитектур. Эта метрика количественно определяет миллионы строк, которые мы можем принять в брокере Kafka , обеспечивая прямую оценку экономической эффективности архитектуры.
Важно понимать, что фактические результаты могут отличаться из-за дополнительных скидок поставщиков облачных услуг. По возможности тесты проводились во Франкфурте для обоих облачных провайдеров (или в Нидерландах в тех случаях, когда варианты типа экземпляра были ограничены).
На всех графиках я использую условные имена для экземпляров, такие же, как их провайдеры. Инстансы сортируются сначала по поставщикам облачных услуг (AWS, затем GCP), а затем по поколениям: от старых к новым.
Полные результаты, хотя и в необработанном виде, доступны в моей подробной таблице сравнительного анализа . Там вы можете найти больше данных, чем я привожу в этой статье, включая показатели задержки и пропускной способности, а также сравнительную производительность различных JVM.
Инстансы s1 «1-го поколения», основанные на поколении m5a с AMD EPYC 7571, выпущенные в третьем квартале 2019 года, являются нашим устаревшим вариантом. Они наименее эффективны и медленны среди наших вариантов во Франкфурте, их стоимость по требованию составляет примерно ~0,2080 евро/час. Переход на новое семейство s2 стоимостью ~0,2070 евро/час дает удвоенную эффективность практически за ту же цену. Мы рекомендуем клиентам перейти на эти более экономичные и производительные варианты, чтобы сократить время выполнения запросов и скорость приема данных для аналитических приложений.
Семейство g1 основано на Graviton 2 и исторически имело хорошую ценность, но новое семейство s2 с процессорами AMD теперь соответствует уровню эффективности Apache Kafka. Несмотря на несколько меньшую пропускную способность и незначительное ценовое преимущество, семейство g1 сейчас считается устаревшим по сравнению с более новыми вариантами.
Семейство g2 на базе Graviton 3 выделяется как наша лучшая рекомендация благодаря своей превосходной эффективности. В определенных сценариях он превосходит семейства s2 и i2 до 39 %, предлагая экономичное решение практически во всех регионах, что делает его идеальным для большинства случаев использования Apache Kafka. Учитывая типичную природу Kafka, связанную с вводом-выводом, оптимизация вычислительной эффективности имеет решающее значение для экономии затрат. Я заметил растущую тенденцию к внедрению архитектуры Arm64: почти половина наших кластеров уже использует эту новую технологию.
Тесты показывают, что каждый новый процессор AMD или Intel улучшает общую пропускную способность и задержку. Несмотря на это, прирост эффективности новых поколений m6 и m7 стабилизировался. Согласно нашим тестам, даже поколение m7, потенциально предлагая меньшую задержку в некоторых регионах, уступает по эффективности по сравнению с семейством g2.
Семейство m7a превосходно работает в приложениях с низкой задержкой, превосходя Intel и предыдущие поколения AMD по пропускной способности и задержке. Хотя эта архитектура не является универсально доступной, она отражает прогресс AMD в повышении производительности. Если он доступен в вашем регионе, рассмотрите вариант m7a для получения превосходных результатов.
Инстансы GCP обычно имеют более низкую эффективность, чем их альтернативы AWS. Для меня это было большим открытием, поскольку клиенты обычно предпочитают GCP из-за его экономической эффективности в аналитических приложениях, что приводит к снижению счетов. В нашем семействе sg1 используется поколение стандарта n2, аналогичное семейству AWS s2. Однако моя попытка распространить это сравнение на другие типы инстансов была ограничена региональной доступностью, особенно для поколений c3 и n2.
Экземпляры Arm, использующие процессоры GCP Tau, обеспечивают повышение эффективности на 5–7 % по сравнению с Graviton 2, что делает их разумным вариантом экономии средств, если они доступны в вашем регионе . Хотя поддержка GCP для экземпляров Arm ограничена четырьмя регионами, она обеспечивает производительность и эффективность, сравнимую с семейством g1.
Поскольку кластеры Apache Kafka постоянно используют виртуальную машину, использование скидок на устойчивое использование позволяет получить скидки до 20%. Это делает даже более старые вычислительные мощности, такие как Ampere Altra, конкурентоспособными с Graviton 3 с точки зрения эффективности. Однако прямое сравнение здесь затруднительно из-за дополнительных скидок AWS, которые также могут применяться.
Я думал, что увижу значительное улучшение в новых версиях JVM на архитектуре ARM. Однако похоже, что openjdk-11 и corretto-11 уже достаточно оптимизированы для ARM. Поскольку для новых версий Kafka требуется Java 17 и выше, я перешел на Java 17, что привело к увеличению производительности примерно на 4–8 % в наших тестах.
Кроме того, 21.0.2-amzn кажется многообещающим, предлагая дополнительный прирост производительности на 10–20 % на новых типах инстансов.
Время от времени я провожу внутренние исследования, чтобы найти оптимальные решения для наших производственных кластеров и собрать полезную информацию. Переход к архитектуре ARM выгоден для управляемых сервисов, поскольку он экономит деньги и снижает потребление энергии.
Использование ARM уже доказало свою эффективность, поскольку повышает производительность и экономическую эффективность как Managed Service для Apache Kafka, так и Managed Service для ClickHouse. Это исследование помогло уточнить нашу матрицу тестирования, определив наиболее эффективные среды и области для дальнейшей оптимизации. Мы постоянно работаем над этим: настраиваем и совершенствуем «под капотом», и я рад поделиться нашими знаниями с сообществом. Следите за обновлениями!