Bestem den passende størrelse for en Kafka-klynge i Kubernetes
Bemærk. overs.: I denne artikel deler Banzai Cloud et eksempel på, hvordan dets brugerdefinerede værktøjer kan bruges til at gøre Kafka nemmere at bruge i Kubernetes. De følgende instruktioner illustrerer, hvordan du kan bestemme den optimale størrelse af din infrastruktur og konfigurere Kafka selv for at opnå den nødvendige gennemstrømning.
Apache Kafka er en distribueret streamingplatform til at skabe pålidelige, skalerbare og højtydende realtidsstreamingsystemer. Dens imponerende muligheder kan udvides ved hjælp af Kubernetes. Til dette har vi udviklet Open Source Kafka-operatør og et værktøj kaldet Superrør. De giver dig mulighed for at køre Kafka på Kubernetes og bruge dens forskellige funktioner, såsom finjustering af mæglerkonfigurationen, metrisk-baseret skalering med rebalancering, rack-bevidsthed, "blød" (yndefuld) udrulning af opdateringer mv.
Prøv Supertubes i din klynge:
curl https://getsupertubes.sh | sh и supertubes install -a --no-democluster --kubeconfig <path-to-eks-cluster-kubeconfig-file>
Eller kontakt dokumentation. Du kan også læse om nogle af mulighederne i Kafka, hvor arbejdet er automatiseret ved hjælp af Supertubes og Kafka-operatøren. Vi har allerede skrevet om dem på bloggen:
Når du beslutter dig for at implementere en Kafka-klynge på Kubernetes, vil du sandsynligvis blive stillet over for udfordringen med at bestemme den optimale størrelse af den underliggende infrastruktur og behovet for at finjustere din Kafka-konfiguration for at opfylde gennemløbskravene. Den maksimale ydeevne for hver mægler bestemmes af ydeevnen af de underliggende infrastrukturkomponenter, såsom hukommelse, processor, diskhastighed, netværksbåndbredde osv.
Ideelt set bør mæglerkonfigurationen være sådan, at alle infrastrukturelementer bruges til deres maksimale kapacitet. Men i det virkelige liv er denne opsætning ret kompleks. Det er mere sandsynligt, at brugere vil konfigurere mæglere til at maksimere brugen af en eller to komponenter (disk, hukommelse eller processor). Generelt viser en mægler maksimal ydeevne, når dens konfiguration tillader den langsomste komponent at blive brugt i sit fulde omfang. På denne måde kan vi få en nogenlunde idé om den belastning, som en mægler kan håndtere.
Teoretisk kan vi også estimere antallet af mæglere, der skal til for at håndtere en given belastning. Men i praksis er der så mange konfigurationsmuligheder på forskellige niveauer, at det er meget svært (hvis ikke umuligt) at evaluere den potentielle ydeevne af en bestemt konfiguration. Det er med andre ord meget svært at planlægge en konfiguration baseret på en given ydeevne.
For Supertubes-brugere tager vi normalt følgende tilgang: vi starter med en vis konfiguration (infrastruktur + indstillinger), måler derefter dens ydeevne, justerer mæglerindstillingerne og gentager processen igen. Dette sker, indtil den langsomste komponent af infrastrukturen er fuldt udnyttet.
På denne måde får vi en klarere idé om, hvor mange mæglere en klynge har brug for for at håndtere en bestemt belastning (antallet af mæglere afhænger også af andre faktorer, såsom minimumsantallet af beskedreplikaer for at sikre robusthed, antallet af partitioner ledere osv.). Derudover får vi indsigt i, hvilke infrastrukturkomponenter der kræver vertikal skalering.
Denne artikel vil tale om de trin, vi tager for at få mest muligt ud af de langsomste komponenter i indledende konfigurationer og måle gennemløbet af en Kafka-klynge. En meget robust konfiguration kræver mindst tre kørende mæglere (min.insync.replicas=3), fordelt på tre forskellige tilgængelighedszoner. For at konfigurere, skalere og overvåge Kubernetes-infrastrukturen bruger vi vores egen containerstyringsplatform til hybridskyer - Pipeline. Det understøtter on-premise (bare metal, VMware) og fem typer skyer (Alibaba, AWS, Azure, Google, Oracle) såvel som enhver kombination af dem.
Tanker om Kafka-klyngeinfrastruktur og -konfiguration
Til eksemplerne nedenfor valgte vi AWS som cloud-udbyder og EKS som Kubernetes-distribution. En lignende konfiguration kan implementeres vha P.K.E. - Kubernetes distribution fra Banzai Cloud, certificeret af CNCF.
disk
Amazon tilbyder forskellige EBS volumen typer. I kernen gp2 и io1 der er dog SSD-drev for at sikre høj gennemstrømning gp2 bruger akkumulerede kreditter (I/O-kreditter), så vi foretrak typen io1, som tilbyder ensartet høj gennemstrømning.
Forekomsttyper
Kafkas ydeevne er meget afhængig af operativsystemets sidecache, så vi har brug for instanser med nok hukommelse til mæglerne (JVM) og sidecache. Forekomst c5.2xlarge - en god start, da den har 16 GB hukommelse og optimeret til at arbejde med EBS. Dens ulempe er, at den kun er i stand til at yde maksimal ydeevne i højst 30 minutter hver 24. time. Hvis din arbejdsbyrde kræver maksimal ydeevne over en længere periode, kan du overveje andre instanstyper. Det var præcis, hvad vi gjorde, og stoppede ved c5.4xlarge. Det giver maksimal gennemstrømning ind 593,75 Mb/s. Maksimal gennemstrømning af et EBS-volumen io1 højere end tilfældet c5.4xlarge, så det langsomste element i infrastrukturen er sandsynligvis I/O-gennemstrømningen af denne instanstype (hvilket vores belastningstest også burde bekræfte).
netværk
Netværksgennemstrømningen skal være stor nok i forhold til ydeevnen af VM-instansen og disken, ellers bliver netværket en flaskehals. I vores tilfælde netværksgrænsefladen c5.4xlarge understøtter hastigheder på op til 10 Gb/s, hvilket er væsentligt højere end I/O-gennemstrømningen for en VM-instans.
Mæglerimplementering
Mæglere bør implementeres (planlagt i Kubernetes) til dedikerede noder for at undgå at konkurrere med andre processer for CPU, hukommelse, netværk og diskressourcer.
Java version
Det logiske valg er Java 11, fordi det er kompatibelt med Docker i den forstand, at JVM korrekt bestemmer de processorer og hukommelse, der er tilgængelig for den container, som mægleren kører i. Ved at vide, at CPU-grænser er vigtige, indstiller JVM internt og transparent antallet af GC-tråde og JIT-tråde. Vi brugte Kafka-billedet banzaicloud/kafka:2.13-2.4.0, som inkluderer Kafka version 2.4.0 (Scala 2.13) på Java 11.
Hvis du gerne vil lære mere om Java/JVM på Kubernetes, så tjek vores følgende indlæg:
Der er to nøgleaspekter ved konfiguration af mæglerhukommelse: indstillinger for JVM og for Kubernetes pod. Hukommelsesgrænsen, der er sat for en pod, skal være større end den maksimale heapstørrelse, så JVM'en har plads til Java-metaspacet, som ligger i dens egen hukommelse, og til operativsystemets sidecache, som Kafka aktivt bruger. I vores test lancerede vi Kafka-mæglere med parametre -Xmx4G -Xms2G, og hukommelsesgrænsen for poden var 10 Gi. Bemærk venligst, at hukommelsesindstillinger for JVM kan opnås automatisk vha -XX:MaxRAMPercentage и -X:MinRAMPercentage, baseret på hukommelsesgrænsen for poden.
Mægler processor indstillinger
Generelt kan du forbedre ydeevnen ved at øge paralleliteten ved at øge antallet af tråde, der bruges af Kafka. Jo flere processorer der er tilgængelige for Kafka, jo bedre. I vores test startede vi med en grænse på 6 processorer og hævede gradvist (gennem iterationer) deres antal til 15. Derudover satte vi num.network.threads=12 i mæglerindstillingerne for at øge antallet af tråde, der modtager data fra netværket og sender dem. Da de med det samme opdagede, at follower-mæglerne ikke kunne modtage replikaer hurtigt nok, rejste de num.replica.fetchers til 4 for at øge hastigheden, hvormed follower-mæglere replikerede beskeder fra ledere.
Indlæs Genereringsværktøj
Du bør sikre dig, at den valgte belastningsgenerator ikke løber tør for kapacitet, før Kafka-klyngen (som er ved at blive benchmarked) når sin maksimale belastning. Med andre ord er det nødvendigt at foretage en foreløbig vurdering af belastningsgenereringsværktøjets muligheder og også vælge instanstyper til det med et tilstrækkeligt antal processorer og hukommelse. I dette tilfælde vil vores værktøj producere mere belastning, end Kafka-klyngen kan klare. Efter mange eksperimenter slog vi os til tre eksemplarer c5.4xlarge, som hver havde en generator kørende.
Benchmarking
Præstationsmåling er en iterativ proces, der omfatter følgende faser:
opsætning af infrastruktur (EKS-klynge, Kafka-klynge, belastningsgenereringsværktøj samt Prometheus og Grafana);
generere en belastning i en vis periode for at filtrere tilfældige afvigelser i de indsamlede præstationsindikatorer;
justering af mæglerens infrastruktur og konfiguration baseret på observerede præstationsindikatorer;
gentagelse af processen, indtil det nødvendige niveau af Kafka-klyngegennemløb er opnået. Samtidig skal den være konsekvent reproducerbar og demonstrere minimale variationer i gennemløb.
Det næste afsnit beskriver de trin, der blev udført under testklyngebenchmarking-processen.
Værktøj
Følgende værktøjer blev brugt til hurtigt at implementere en baseline-konfiguration, generere belastninger og måle ydeevne:
Banzai Cloud Pipeline for at organisere en EKS-klynge fra Amazon c Prometheus (for at indsamle Kafka- og infrastrukturmålinger) og grafana (for at visualisere disse målinger). Vi udnyttede det integreret в Pipeline tjenester, der leverer fødereret overvågning, centraliseret logindsamling, sårbarhedsscanning, gendannelse af katastrofer, sikkerhed i virksomhedskvalitet og meget mere.
Sangrenel — et værktøj til belastningstest af en Kafka-klynge.
Supertubes CLI for den nemmeste måde at opsætte en Kafka-klynge på Kubernetes. Zookeeper, Kafka-operatør, Envoy og mange andre komponenter er installeret og korrekt konfigureret til at køre en produktionsklar Kafka-klynge på Kubernetes.
Til installation superrør CLI brug den medfølgende vejledning her.
EKS klynge
Forbered en EKS-klynge med dedikerede arbejdsknudepunkter c5.4xlarge i forskellige tilgængelighedszoner for pods med Kafka-mæglere, samt dedikerede noder til belastningsgeneratoren og overvågningsinfrastrukturen.
For hvert emne er replikationsfaktoren 3 – den mindste anbefalede værdi for højt tilgængelige produktionssystemer.
Indlæs Genereringsværktøj
Vi lancerede tre kopier af belastningsgeneratoren (hver skrev i et separat emne). For load generator pods skal du indstille nodeaffinitet, så de kun er planlagt på de noder, der er allokeret til dem:
Belastningsgeneratoren genererer meddelelser på 512 bytes i længden og udgiver dem til Kafka i batches på 500 meddelelser.
Ved at bruge et argument -required-acks=all Udgivelsen anses for at være vellykket, når alle synkroniserede replikaer af meddelelsen modtages og bekræftes af Kafka-mæglere. Det betyder, at vi i benchmark ikke kun målte hastigheden på ledere, der modtager beskeder, men også deres følgere, der replikerer beskeder. Formålet med denne test er ikke at evaluere forbrugernes læsehastighed (forbrugere) nyligt modtagne beskeder, der stadig forbliver i OS-sidecachen, og dens sammenligning med læsehastigheden af beskeder, der er gemt på disken.
Belastningsgeneratoren kører 20 arbejdere parallelt (-workers=20). Hver arbejder indeholder 5 producenter, der deler arbejderens tilknytning til Kafka-klyngen. Som følge heraf har hver generator 100 producenter, og de sender alle beskeder til Kafka-klyngen.
Overvågning af klyngens sundhed
Under belastningstest af Kafka-klyngen overvågede vi også dens helbred for at sikre, at der ikke var nogen pod-genstarter, ingen replikaer, der ikke var synkroniseret, og maksimal gennemstrømning med minimale udsving:
Belastningsgeneratoren skriver standardstatistik over antallet af publicerede meddelelser og fejlprocenten. Fejlprocenten bør forblive den samme 0,00%.
Fartpilot, implementeret af kafka-operatør, giver et dashboard, hvor vi også kan overvåge klyngens tilstand. For at se dette panel skal du gøre:
supertubes cluster cruisecontrol show -n kafka --kubeconfig <path-to-eks-cluster-kubeconfig-file>
ISR niveau (antal "synkroniserede" replikaer) krympning og ekspansion er lig med 0.
Måleresultater
3 mæglere, beskedstørrelse - 512 bytes
Med partitioner jævnt fordelt på tre mæglere var vi i stand til at opnå ydeevne ~500 Mb/s (ca. 990 tusind beskeder pr. sekund):
Hukommelsesforbruget på den virtuelle JVM-maskine oversteg ikke 2 GB:
Diskgennemløb nåede den maksimale I/O-nodegennemstrømning på alle tre forekomster, som mæglerne kørte på:
Fra dataene om hukommelsesbrug af noder, følger det, at systembuffring og caching tog ~10-15 GB:
3 mæglere, beskedstørrelse - 100 bytes
Efterhånden som beskedstørrelsen falder, falder gennemstrømningen med cirka 15-20 %: den tid, der bruges på at behandle hver besked, påvirker den. Derudover er processorbelastningen næsten fordoblet.
Da mæglernoder stadig har ubrugte kerner, kan ydeevnen forbedres ved at ændre Kafka-konfigurationen. Dette er ikke en nem opgave, så for at øge gennemstrømningen er det bedre at arbejde med større beskeder.
4 mæglere, beskedstørrelse - 512 bytes
Du kan nemt øge ydeevnen af en Kafka-klynge ved blot at tilføje nye mæglere og opretholde en balance mellem partitioner (dette sikrer, at belastningen er jævnt fordelt mellem mæglere). I vores tilfælde, efter at have tilføjet en mægler, steg klyngens gennemløb til ~580 Mb/s (~1,1 millioner beskeder pr. sekund). Væksten viste sig at være mindre end forventet: Dette forklares hovedsageligt af ubalancen mellem partitioner (ikke alle mæglere arbejder på toppen af deres evner).
Hukommelsesforbruget for JVM-maskinen forblev under 2 GB:
Mægleres arbejde med drev blev påvirket af ubalancen mellem partitioner:
Fund
Den iterative tilgang præsenteret ovenfor kan udvides til at dække mere komplekse scenarier, der involverer hundredvis af forbrugere, ompartitionering, rullende opdateringer, pod-genstarter osv. Alt dette giver os mulighed for at vurdere grænserne for Kafka-klyngens muligheder under forskellige forhold, identificere flaskehalse i dens drift og finde måder at bekæmpe dem på.
Vi har designet Supertubes til hurtigt og nemt at implementere en klynge, konfigurere den, tilføje/fjerne mæglere og emner, reagere på advarsler og sikre, at Kafka generelt fungerer korrekt på Kubernetes. Vores mål er at hjælpe dig med at koncentrere dig om hovedopgaven (“generere” og “forbruge” Kafka-beskeder), og overlade alt det hårde arbejde til Supertubes og Kafka-operatøren.
Hvis du er interesseret i Banzai Cloud-teknologier og Open Source-projekter, kan du abonnere på virksomheden på GitHub, LinkedIn eller Twitter.