Прим. прев.: В тази статия компанията Banzai Cloud споделя пример за използване на специализирани инструменти за улесняване на работата с Kafka в контекста на Kubernetes. Инструкциите илюстрират как може да се определи оптималният размер на инфраструктурата и да се настрои самата Kafka за постигане на необходимата пропускна способност.

Apache Kafka е разпределена стрийминг платформа за създаване на надеждни, мащабируеми и високопроизводителни системи за поточно предаване в реално време. Впечатляващите ѝ възможности могат да бъдат разширени с помощта на Kubernetes. За това разработихме и инструмент, наречен . Те позволяват стартиране на Kafka в Kubernetes и използване на различните ѝ функции, като фина настройка на конфигурацията на брокера, мащабиране на база метрики с ребалансиране, осведомленост за достъп до хардуерни ресурси (rack awareness), 'меко' (graceful) разгръщане на актуализации и т.н.
Опитайте Supertubes в своя кластер:
curl https://getsupertubes.sh | sh и supertubes install -a --no-democluster --kubeconfigИли се свържете с . Можете също така да прочетете за някои функции на Kafka, чиято работа е автоматизирана с помощта на Supertubes и Kafka оператора. Писали сме за тях в блога:
- ;
- ;
- ;
- ;
- ;
- ;
- .
Решавайки да разположите кластер Kafka в Kubernetes, вероятно ще се сблъскате с проблема да определите оптималния размер на основната инфраструктура и необходимостта от фина настройка на конфигурацията на Kafka, за да отговори на изискванията за пропускна способност. Максималната производителност на всеки брокер се определя от производителността на компонентите на инфраструктурата в основата му, като памет, процесор, скорост на диска, пропускна способност на мрежата и т.н.
Идеално е конфигурацията на брокера да е такава, че всички елементи на инфраструктурата да се използват на максимум своите възможности. Въпреки това, в реалния живот такава настройка е доста сложна. По-вероятно е потребителите да настройват конфигурацията на брокерите по начин, който максимизира използването на един или два компонента (диск, памет или процесор). По принцип, брокерът показва максимална производителност, когато конфигурацията му позволява да използва най-бавния компонент „на пълна пара“. Така можем да получим приблизителна представа за натоварването, с което е способен да се справи един брокер.
Теоретично можем също да преценим броя на брокерите, необходими за работа с дадено натоварване. Въпреки това, на практика възможностите за настройка на различни нива са толкова много, че оценката на потенциалната производителност на дадена конфигурация е много сложна (ако не и невъзможна). С други думи, много трудно е да се планира конфигурация, основаваща се на предварително зададена производителност.
За потребителите на Supertubes обикновено прилагаме следния подход: започваме с определена конфигурация (инфраструктура + настройки), след това измерваме нейната производителност, коригираме настройките на брокера и повтаряме процеса отново. Това продължава, докато потенциалът на най-бавния компонент на инфраструктурата не бъде напълно включен.
По този начин получаваме по-ясна представа за това колко брокери са необходими на клъстера, за да се справи с определено натоварване (броят на брокерите също зависи от други фактори, като минималния брой реплики на съобщенията за осигуряване на устойчивост, броя на partition-лидерите и т.н.). Освен това получаваме представа за това, за кой инфраструктурен компонент е желателно вертикално мащабиране.
В тази статия ще разгледаме стъпките, които предприемаме, за да „изстискаме всичко“ от най-бавните компоненти в началните конфигурации и да измерим пропускната способност на клъстера Kafka. Конфигурацията с висока устойчивост изисква наличие на поне три работещи брокера (min.insync.replicas=3), разпределени в три различни зони на достъпност. За настройка, мащабиране и мониторинг на инфраструктурата Кubernetes използваме собствена платформа за управление на контейнери за хибридни облаци — . Тя поддържа on-premise (bare metal, VMware) и пет типа облаци (Alibaba, AWS, Azure, Google, Oracle), както и всякакви комбинации от тях.
Размисли относно инфраструктурата и конфигурацията на кластера Kafka
За примерите, изброени по-долу, избрахме AWS като доставчик на облачни услуги и EKS като дистрибуция на Kubernetes. Подобна конфигурация може да се реализира с помощта на — дистрибуция на Kubernetes от Banzai Cloud, сертифицирана от CNCF.
Диск
Amazon предлага различни . В основата на gp2 и io1 лежат SSD дискове, но за осигуряване на висока пропускателна способност gp2 изразходва натрупаните кредити (I/O кредити), затова предпочетохме тип io1, който предлага стабилна висока пропускателна способност.
Типове инстанции
Производителността на Kafka зависи от кеша на страниците на операционната система, затова се нуждаем от инстанции с достатъчно памет за брокерите (JVM) и кеша на страниците. Инстанцията c5.2xlarge е добро начало, тъй като има 16 Гб памет и Недостатъкът е, че може да осигури максимална производителност не повече от 30 минути на всеки 24 часа. Ако работния товар изисква максимална производителност за по-дълъг период, трябва да разгледате и други типове инстанции. Именно така постъпихме, спирайки се на c5.4xlarge.Той осигурява максимална пропускателна способност от 593,75 Мб/с.Максималната пропускателна способност на EBS тома io1 е по-висока от тази на инстанцията c5.4xlarge., затова най-бавният елемент от инфраструктурата, очевидно, е пропускателната способност I/O на този тип инстанция (което също трябва да потвърдят резултатите от нашите тестове на натоварване).
Мрежа
Пропускателната способност на мрежата трябва да бъде достатъчно голяма в сравнение с производителността на инстанцията VM и диска, в противен случай мрежата става тесен врата. В нашия случай мрежовият интерфейс c5.4xlarge. поддържа скорост до 10 Гб/с, което е значително над пропускателната способност I/O на инстанцията VM.
Разгръщане на брокерите
Брокерите трябва да се разгръщат (планират в Kubernetes) на отделни възли, за да се избегне конкуренцията с другите процеси за ресурсите на процесора, паметта, мрежата и диска.
Версия на Java
Логичният избор е Java 11, тъй като тя е съвместима с Docker в смисъл, че JVM правилно определя процесорите и паметта, налична на контейнера, в който работи брокера. Знаейки, че лимитите на процесорите са важни, JVM вътрешно и прозрачно установява броя на потоковете GC и потоковете на JIT компилатора. Ние използвахме образа Kafka banzaicloud/kafka:2.13-2.4.0, включващ версия Kafka 2.4.0 (Scala 2.13) на Java 11.
Ако искате да научите повече за Java/JVM на Kubernetes, обърнете внимание на следните наши публикации:
- ;
- .
Настройки на паметта на брокера
Има два ключови аспекта в настройването на паметта на брокера: настройки за JVM и за pod на Kubernetes. Лимитът на паметта, зададен за pod, трябва да бъде по-голям от максималния размер на heap, за да остане място за метапространството на Java, което е в собствената памет, и за кеша на страниците на операционната система, който Kafka активно използва. В нашите тестове стартирахме брокери на Kafka с параметри -Xmx4G -Xms2G, а лимитът на паметта за pod беше 10 Gi. Обърнете внимание, че настройките за паметта на JVM могат да се получават автоматично с помощта на -XX:MaxRAMPercentage и -X:MinRAMPercentage, базирано на лимита на паметта за pod.
Настройки на процесора на брокера
Говорейки общо, може да се повиши производителността, увеличавайки паралелизма чрез нарастване на броя на потоковете, използвани от Kafka. Колкото повече процесори са налични за Kafka, толкова по-добре. В нашия тест започнахме с лимит от 6 процесора и постепенно (чрез итерации) увеличихме броя им до 15. Освен това зададохме num.network.threads=12 в настройките на брокера, за да увеличим броя на потоковете, приемащи данни от мрежата и изпращащи ги. Веднага установихме, че брокерите-последователи не могат да получават реплики достатъчно бързо и увеличихме num.replica.fetchers до 4, за да увеличим скоростта, с която брокерите-последователи репликират съобщения от лидери.
Инструмент за генериране на натоварване
Трябва да се уверим, че потенциалът на избрания генератор на натоварване няма да свърши, преди кластерът Kafka (за който се провежда бенчмарка) да достигне своята максимална натовареност. С други думи, трябва да направим предварителна оценка на възможностите на инструмента за генериране на натоварване и да изберат типове инстанции с достатъчен брой процесори и памет. В този случай нашият инструмент ще генерира повече натоварване, отколкото кластерът Kafka може да обработи. След множество експерименти, спряха на три инстанции c5.4xlarge., във всяка от които беше стартиран генератор.
Бенчмаркинг
Измерването на представянето е итеративен процес, който включва следните етапи:
- настройка на инфраструктурата (кластера EKS, кластера Kafka, инструмента за генериране на натоварване, както и Prometheus и Grafana);
- генериране на натоварване в продължение на определен период за филтриране на случайни отклонения в събираните показатели за представяне;
- настройка на инфраструктурата и конфигурацията на брокера на базата на наблюдаваните показатели за представяне;
- повторение на процеса, докато не се постигне необходимото ниво на пропускателна способност на кластера Kafka. При това той трябва да бъде стабилно воспроизводим и да показва минимални вариации на пропускателната способност.
В следващия раздел са описани стъпките, които бяха предприети в процеса на бенчмарка на тестовия кластер.
Инструменти
За бързо разгръщане на базовата конфигурация, генериране на натоварване и измерване на представянето бяха използвани следните инструменти:
- за организиране на кластера EKS на Amazon с (за събиране на метрики от Kafka и инфраструктурата) и (за визуализиране на тези метрики). Използвахме интегрирани в услуги, които осигуряват федеративен мониторинг, централизирано събиране на логове, сканиране за уязвимости, възстановяване след аварии, сигурност на корпоративно ниво и много други.
- — инструмент за стрес тестиране на кластера Kafka.
- Панелите на Grafana за визуализиране на метрики от Kafka и инфраструктурата: , .
- Supertubes CLI за максимално лесна настройка на Kafka клъстера в Kubernetes. Zookeeper, Kafka оператор, Envoy и много други компоненти са инсталирани и конфигурирани правилно за стартиране на готов за продукция Kafka клъстер в Kubernetes.
- За инсталация supertubes CLI использвайте инструкциите, приведенные .

Клъстер EKS
Подгответе клъстера EKS с отделени работни възли c5.4xlarge. в различни зони на достъпност за подовете с Kafka брокери и отделени възли за генериране на натоварване и мониторингова инфраструктура.
banzai cluster create -f https://raw.githubusercontent.com/banzaicloud/kafka-operator/master/docs/benchmarks/infrastructure/cluster_eks_202001.jsonКогато клъстерът EKS заработи, активирайте неговата интегрирана — тя ще разверне Prometheus и Grafana в клъстера.
Системни компоненти на Kafka
Инсталирайте системните компоненти на Kafka (Zookeeper, kafka-operator) в EKS с помощта на supertubes CLI:
supertubes install -a --no-democluster --kubeconfigКлъстер Kafka
По подразбиране в EKS се използват EBS томове от тип gp2, затова е необходимо да се създаде отделен клас за съхранение на базата на томове io1 за клъстера Kafka:
kubectl create -f - <<EOF
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast-ssd
provisioner: kubernetes.io/aws-ebs
parameters:
type: io1
iopsPerGB: "50"
fsType: ext4
volumeBindingMode: WaitForFirstConsumer
EOF Задайте параметъра за брокерите min.insync.replicas=3 и разположете подовете на брокерите на възлите в три различни зони на достъпност:
supertubes cluster create -n kafka --kubeconfig -f https://raw.githubusercontent.com/banzaicloud/kafka-operator/master/docs/benchmarks/infrastructure/kafka_202001_3brokers.yaml --wait --timeout 600Топици
Същевременно стартирахме три екземпляра на генератора на натоварване. Всеки от тях записва в своя собствен топик, т.е. общо се нуждаем от три топика:
supertubes cluster topic create -n kafka --kubeconfig -f -<<EOF
apiVersion: kafka.banzaicloud.io/v1alpha1
kind: KafkaTopic
metadata:
name: perftest1
spec:
name: perftest1
partitions: 12
replicationFactor: 3
retention.ms: '28800000'
cleanup.policy: delete
EOF
supertubes cluster topic create -n kafka --kubeconfig -f -<<EOF
apiVersion: kafka.banzaicloud.io/v1alpha1
kind: KafkaTopic
metadata:
name: perftest2
spec:
name: perftest2
partitions: 12
replicationFactor: 3
retention.ms: '28800000'
cleanup.policy: delete
EOF
supertubes cluster topic create -n kafka --kubeconfig -f -<<EOF
apiVersion: kafka.banzaicloud.io/v1alpha1
kind: KafkaTopic
metadata:
name: perftest3
spec:
name: perftest3
partitions: 12
replicationFactor: 3
retention.ms: '28800000'
cleanup.policy: delete
EOFЗа всеки топик факторът на репликация е 3 — минимално препоръчваното значение за високо-достъпни производствени системи.
Инструмент за генериране на натоварване
Стартирахме три инстанции на генератора на натоварването (всяка от които пише в отделна тема). За pod'овете на генератора на натоварването е необходимо да зададете node affinity, за да бъдат планирани само на определените за тях възли:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
labels:
app: loadtest
name: perf-load1
namespace: kafka
spec:
progressDeadlineSeconds: 600
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
app: loadtest
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
creationTimestamp: null
labels:
app: loadtest
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: nodepool.banzaicloud.io/name
operator: In
values:
- loadgen
containers:
- args:
- -brokers=kafka-0:29092,kafka-1:29092,kafka-2:29092,kafka-3:29092
- -topic=perftest1
- -required-acks=all
- -message-size=512
- -workers=20
image: banzaicloud/perfload:0.1.0-blog
imagePullPolicy: Always
name: sangrenel
resources:
limits:
cpu: 2
memory: 1Gi
requests:
cpu: 2
memory: 1Gi
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30Няколко момента, на които трябва да обърнете внимание:
- Генераторът на натоварването генерира съобщения с дължина 512 байта и ги публикува в Kafka на партии от 500 съобщения.
- С помощта на аргумента
-required-acks=allпубликацията се счита за успешна, когато всички синхронизирани реплики на съобщението са получени и потвърдени от брокерите на Kafka. Това означава, че в теста измервахме не само скоростта на работа на лидерите, които получават съобщения, но и техните последователи, репликиращи съобщения. Задачата на този тест не е да оценява скоростта на четене на потребители (consumers) на наскоро приети съобщения, които все още остават в страницовия кеш на ОС, и нейното сравнение със скоростта на четене на съобщения, съхранявани на диска. - Генераторът на натоварването стартира 20 worker'а паралелно (
-workers=20). Всеки worker съдържа 5 продюсера, които споделят връзката на worker'а с кластера Kafka. В крайна сметка всеки генератор има 100 продюсера, които всички изпращат съобщения в кластера Kafka.
Наблюдение на състоянието на клъстера
По време на натоварващо тестване на Kafka клъстера, ние също следяхме за неговото здраве, за да се уверим, че няма перезапускане на pod’овете, несинхронизирани реплики и максимална пропускна способност с минимални флуктуации:
- Генераторът на натоварване извежда стандартна статистика за броя на публикуваните съобщения и нивото на грешките. Процентът на грешките трябва да остане на стойност
0,00%. - , внедрен от kafka-operator, предоставя панел за мониторинг, на който можем също да наблюдаваме състоянието на клъстера. За да видите този панел, изпълнете:
supertubes cluster cruisecontrol show -n kafka --kubeconfig - Нивото ISR (броят на репликите "in-sync") shrink и expansion равен на 0.
Резултатите от измерванията
3 брокера, размер на съобщенията — 512 байта
С partition’ите, равномерно разпределени по трите брокера, успяхме да постигнем производителност ~500 Мб/с (приблизително 990 хил. съобщения в секунда):



Консумацията на памет от виртуалната машина JVM не надвиши 2 Гб:



Пропускната способност на диска достигна максималната I/O пропускна способност на възела на всички три инстанции, на които работиха брокерите:



Данните за използването на паметта от възлите показват, че системното буфериране и кеширане заеха около ~10-15 Гб:



3 брокера, размер на съобщенията — 100 байта
С намаляване на размера на съобщенията, пропускната способност намалява с около 15-20%: влияе времето, нужно за обработка на всяко съобщение. Освен това, натоварването на процесора нарасна почти двойно.



Тъй като в брокерските възли все още има неизползвани ядра, производителността може да се увеличи чрез променяне на конфигурацията на Kafka. Това е сложна задача, затова за увеличаване на пропускната способност е по-добре да работите с по-големи съобщения.
4 брокера, размер на съобщенията — 512 байта
Може лесно да увеличите производителността на Kafka клъстера, просто добавяйки нови брокери и запазвайки баланса на partition’ите (това осигурява равномерно разпределение на натоварването между брокерите). В нашия случай, след добавяне на брокер, пропускната способност на клъстера нарасна до ~580 Мб/с (~1,1 млн. съобщения в секунда). Ръстът се оказа по-малък от очакваното: предимно поради дисбаланс на partition’ите (не всички брокери работят на пълен капацитет).




Потреблението на памет от JVM машината остана под 2 Гб:




На работата на брокерите с хранилища повлия дисбалансът на партициите:




Изводи
Представеният по-горе итеративен подход може да бъде разширен, за да обхване по-сложни сценарии, включващи стотици консуматори, преразпределение, актуализации на място, рестартиране на подове и т.н. Всичко това ни позволява да оценим границите на възможностите на кластера Kafka при различни условия, да идентифицираме тесни места в работата му и да намерим начини да се справим с тях.
Разработихме Supertubes за бързо и лесно разгръщане на клъстера, неговата конфигурация, добавяне/изтриване на брокери и теми, реагиране на известия и осигуряване на правилната работа на Kafka в Kubernetes. Нашата цел е да помогнем да се фокусирате върху основната задача („генериране“ и „консумиране“ на съобщения Kafka), а цялата тежка работа да предоставите на Supertubes и Kafka оператора.
Ако се интересувате от технологии и Open Source проекти на Banzai Cloud, абонирайте се за компанията на , или .
P.S. от преводача
Прочетете също в нашия блог:
- «»;
- «»;
- «».
Източник: habr.com
