Določite ustrezno velikost za gručo Kafka v Kubernetesu

Opomba. prevod: V tem članku Banzai Cloud deli primer, kako je mogoče njegova orodja po meri uporabiti za lažjo uporabo Kafke znotraj Kubernetesa. Naslednja navodila ponazarjajo, kako lahko določite optimalno velikost vaše infrastrukture in konfigurirate samo Kafko, da doseže zahtevano prepustnost.

Določite ustrezno velikost za gručo Kafka v Kubernetesu

Apache Kafka je distribuirana pretočna platforma za ustvarjanje zanesljivih, razširljivih in visoko zmogljivih sistemov pretakanja v realnem času. Njegove impresivne zmogljivosti je mogoče razširiti z uporabo Kubernetesa. Za to smo razvili Odprtokodni operater Kafka in orodje, imenovano Supertubes. Omogočajo vam zagon Kafke v Kubernetesu in uporabo njenih različnih funkcij, kot je natančna nastavitev konfiguracije posrednika, skaliranje na podlagi metrike s ponovnim uravnoteženjem, zaznavanje stojala, »soft« (ljubek) uvajanje posodobitev itd.

Preizkusite Supertubes v vaši skupini:

curl https://getsupertubes.sh | sh и supertubes install -a --no-democluster --kubeconfig <path-to-eks-cluster-kubeconfig-file>

Ali kontakt dokumentacijo. Preberete lahko tudi o nekaterih zmožnostih Kafke, delo s katero je avtomatizirano s pomočjo Supertubes in operaterja Kafka. O njih smo na blogu že pisali:

Ko se odločite za uvedbo gruče Kafka v Kubernetes, se boste verjetno soočili z izzivom določanja optimalne velikosti osnovne infrastrukture in potrebo po natančnejši nastavitvi vaše konfiguracije Kafka, da bo izpolnila zahteve glede prepustnosti. Največja zmogljivost vsakega posrednika je določena z zmogljivostjo komponent osnovne infrastrukture, kot so pomnilnik, procesor, hitrost diska, pasovna širina omrežja itd.

V idealnem primeru bi morala biti konfiguracija posrednika takšna, da so vsi infrastrukturni elementi izkoriščeni v največji možni meri. Vendar je v resničnem življenju ta nastavitev precej zapletena. Bolj verjetno je, da bodo uporabniki konfigurirali posrednike za čim večjo uporabo ene ali dveh komponent (diska, pomnilnika ali procesorja). Na splošno posrednik pokaže največjo zmogljivost, ko njegova konfiguracija omogoča uporabo najpočasnejše komponente v največji možni meri. Tako lahko dobimo približno predstavo o obremenitvi, ki jo en posrednik lahko prenese.

Teoretično lahko ocenimo tudi število posrednikov, potrebnih za obvladovanje določene obremenitve. Vendar pa je v praksi na različnih ravneh toliko konfiguracijskih možnosti, da je zelo težko (če ne nemogoče) oceniti potencialno zmogljivost določene konfiguracije. Z drugimi besedami, zelo težko je načrtovati konfiguracijo na podlagi določene zmogljivosti.

Za uporabnike Supertubes običajno uporabimo naslednji pristop: začnemo z določeno konfiguracijo (infrastruktura + nastavitve), nato izmerimo njeno zmogljivost, prilagodimo nastavitve posrednika in znova ponovimo postopek. To se dogaja, dokler ni v celoti izkoriščena najpočasnejša komponenta infrastrukture.

Na ta način dobimo jasnejšo predstavo o tem, koliko posrednikov potrebuje gruča za obvladovanje določene obremenitve (število posrednikov je odvisno tudi od drugih dejavnikov, kot je minimalno število replik sporočil za zagotavljanje odpornosti, število particij voditelji itd.). Poleg tega pridobimo vpogled v to, katere komponente infrastrukture zahtevajo vertikalno skaliranje.

Ta članek bo govoril o korakih, ki jih naredimo, da kar najbolje izkoristimo najpočasnejše komponente v začetnih konfiguracijah in izmerimo prepustnost gruče Kafka. Zelo prožna konfiguracija zahteva vsaj tri delujoče posrednike (min.insync.replicas=3), porazdeljene po treh različnih območjih dostopnosti. Za konfiguriranje, prilagajanje in spremljanje infrastrukture Kubernetes uporabljamo lastno platformo za upravljanje vsebnikov za hibridne oblake – Pipeline. Podpira lokalne (bare metal, VMware) in pet vrst oblakov (Alibaba, AWS, Azure, Google, Oracle) ter poljubno kombinacijo le-teh.

Razmišljanje o infrastrukturi in konfiguraciji gruče Kafka

Za spodnje primere smo izbrali AWS kot ponudnika oblaka in EKS kot distribucijo Kubernetes. Podobno konfiguracijo je mogoče izvesti z uporabo PKE - Distribucija Kubernetes iz Banzai Cloud, certificirana s strani CNCF.

disk

Amazon ponuja različne Vrste glasnosti EBS. V jedru gp2 и io1 obstajajo pa pogoni SSD, ki zagotavljajo visoko prepustnost gp2 porablja nakopičene kredite (I/O krediti), zato smo raje izbrali vrsto io1, ki ponuja dosledno visoko prepustnost.

Vrste primerkov

Učinkovitost Kafke je močno odvisna od predpomnilnika strani operacijskega sistema, zato potrebujemo primerke z dovolj pomnilnika za posrednike (JVM) in predpomnilnik strani. Primerek c5.2 večji - dober začetek, saj ima 16 GB pomnilnika in optimiziran za delo z EBS. Njegova pomanjkljivost je, da je sposoben zagotoviti največjo zmogljivost največ 30 minut vsakih 24 ur. Če vaša delovna obremenitev zahteva največjo zmogljivost v daljšem časovnem obdobju, boste morda želeli razmisliti o drugih vrstah primerkov. Točno to smo naredili, pri čemer smo se ustavili c5.4 večji. Zagotavlja največjo prepustnost 593,75 Mb/s. Največja prepustnost nosilca EBS io1 višji od instance c5.4 večji, zato bo najpočasnejši element infrastrukture verjetno V/I prepustnost te vrste primerka (kar bi morali potrditi tudi naši testi obremenitve).

Сеть

Prepustnost omrežja mora biti dovolj velika v primerjavi z zmogljivostjo primerka VM in diska, sicer postane omrežje ozko grlo. V našem primeru omrežni vmesnik c5.4 večji podpira hitrosti do 10 Gb/s, kar je bistveno višje od V/I prepustnosti instance VM.

Uvajanje posrednika

Posrednike je treba namestiti (načrtovano v Kubernetesu) v namenska vozlišča, da se izognete tekmovanju z drugimi procesi za CPE, pomnilnik, omrežje in diskovne vire.

Java različica

Logična izbira je Java 11, ker je združljiva z Dockerjem v smislu, da JVM pravilno določi procesorje in pomnilnik, ki so na voljo vsebniku, v katerem se izvaja posrednik. Ker ve, da so omejitve procesorja pomembne, JVM interno in pregledno nastavi število niti GC in JIT niti. Uporabili smo podobo Kafke banzaicloud/kafka:2.13-2.4.0, ki vključuje različico Kafka 2.4.0 (Scala 2.13) na Javi 11.

Če želite izvedeti več o Javi/JVM na Kubernetesu, si oglejte naše naslednje objave:

Nastavitve pomnilnika posrednika

Pri konfiguriranju pomnilnika posrednika sta dva ključna vidika: nastavitve za JVM in za Kubernetes pod. Omejitev pomnilnika, nastavljena za pod, mora biti večja od največje velikosti kopice, tako da ima JVM prostor za metaprostor Java, ki se nahaja v njegovem lastnem pomnilniku, in za predpomnilnik strani operacijskega sistema, ki ga Kafka aktivno uporablja. V naših testih smo zagnali posrednike Kafka s parametri -Xmx4G -Xms2G, omejitev pomnilnika za pod je bila 10 Gi. Upoštevajte, da je mogoče nastavitve pomnilnika za JVM pridobiti samodejno z uporabo -XX:MaxRAMPercentage и -X:MinRAMPercentage, glede na omejitev pomnilnika za pod.

Nastavitve procesorja posrednika

Na splošno lahko izboljšate zmogljivost s povečanjem vzporednosti s povečanjem števila niti, ki jih uporablja Kafka. Več procesorjev kot je na voljo za Kafko, bolje je. V našem testu smo začeli z omejitvijo 6 procesorjev in jih postopoma (skozi iteracije) dvignili na 15. Poleg tega smo nastavili num.network.threads=12 v nastavitvah posrednika, da povečate število niti, ki prejemajo podatke iz omrežja in jih pošiljajo. Takoj ko so odkrili, da sledilni posredniki ne morejo dovolj hitro prejeti replik, so dvignili num.replica.fetchers na 4 za povečanje hitrosti, s katero posredniki sledilcev posnemajo sporočila vodij.

Orodje za ustvarjanje obremenitve

Zagotoviti morate, da izbranemu generatorju obremenitve ne zmanjka zmogljivosti, preden gruča Kafka (ki se primerja) doseže največjo obremenitev. Z drugimi besedami, potrebno je izvesti predhodno oceno zmogljivosti orodja za ustvarjanje obremenitve in zanj izbrati tudi vrste primerkov z zadostnim številom procesorjev in pomnilnika. V tem primeru bo naše orodje proizvedlo večjo obremenitev, kot jo lahko prenese grozd Kafka. Po številnih poskusih smo se odločili za tri kopije c5.4 večji, od katerih je vsak imel delujoč generator.

Primerjalna analiza

Merjenje uspešnosti je ponavljajoč se proces, ki vključuje naslednje stopnje:

  • postavitev infrastrukture (gruča EKS, gruča Kafka, orodje za generiranje obremenitev ter Prometheus in Grafana);
  • generiranje obremenitve za določeno obdobje za filtriranje naključnih odstopanj v zbranih indikatorjih uspešnosti;
  • prilagoditev infrastrukture in konfiguracije posrednika na podlagi opaženih kazalnikov uspešnosti;
  • ponavljanje postopka, dokler ni dosežena zahtevana raven prepustnosti gruče Kafka. Hkrati mora biti dosledno ponovljiv in pokazati minimalne razlike v pretoku.

Naslednji razdelek opisuje korake, ki so bili izvedeni med postopkom primerjalne analize testne gruče.

Orodja

Naslednja orodja so bila uporabljena za hitro uvedbo osnovne konfiguracije, ustvarjanje obremenitev in merjenje zmogljivosti:

  • Banzai Cloud Pipeline za organizacijo EKS grozda iz Amazona c Prometej (za zbiranje Kafkinih in infrastrukturnih meritev) in grafana (za vizualizacijo teh meritev). Izkoristili smo integrirano в Pipeline storitve, ki zagotavljajo zvezno spremljanje, centralizirano zbiranje dnevnikov, skeniranje ranljivosti, obnovitev po katastrofi, varnost na ravni podjetja in še veliko več.
  • Sangrenel — orodje za obremenitveno testiranje gruče Kafka.
  • Nadzorne plošče Grafana za vizualizacijo Kafkinih meritev in infrastrukture: Kubernetes Kafka, Izvoznik vozlišč.
  • Supertubes CLI za najlažji način za postavitev gruče Kafka na Kubernetes. Zookeeper, operater Kafka, Envoy in številne druge komponente so nameščene in pravilno konfigurirane za zagon gruče Kafka na Kubernetesu, pripravljene za proizvodnjo.
    • Za namestitev nadcevke CLI uporabite priložena navodila tukaj.

Določite ustrezno velikost za gručo Kafka v Kubernetesu

Grozd EKS

Pripravite gručo EKS z namenskimi delovnimi vozlišči c5.4 večji v različnih območjih razpoložljivosti za pode s posredniki Kafka, kot tudi namenska vozlišča za generator obremenitve in infrastrukturo za spremljanje.

banzai cluster create -f https://raw.githubusercontent.com/banzaicloud/kafka-operator/master/docs/benchmarks/infrastructure/cluster_eks_202001.json

Ko je gruča EKS pripravljena in zagnana, omogočite njeno integracijo storitev spremljanja — Prometeja in Grafana bo razporedila v gručo.

Komponente sistema Kafka

Namestite komponente sistema Kafka (Zookeeper, kafka-operator) v EKS z uporabo supertubes CLI:

supertubes install -a --no-democluster --kubeconfig <path-to-eks-cluster-kubeconfig-file>

Kafkov grozd

EKS privzeto uporablja nosilce tipa EBS gp2, zato morate ustvariti ločen razred shranjevanja na podlagi nosilcev io1 za grozd 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

Nastavite parameter za posrednike min.insync.replicas=3 in razmesti posredniške enote na vozliščih v treh različnih območjih razpoložljivosti:

supertubes cluster create -n kafka --kubeconfig <path-to-eks-cluster-kubeconfig-file> -f https://raw.githubusercontent.com/banzaicloud/kafka-operator/master/docs/benchmarks/infrastructure/kafka_202001_3brokers.yaml --wait --timeout 600

Teme

Vzporedno smo izvajali tri primerke generatorja obremenitve. Vsak od njih piše v svojo temo, torej potrebujemo skupaj tri teme:

supertubes cluster topic create -n kafka --kubeconfig <path-to-eks-cluster-kubeconfig-file> -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 <path-to-eks-cluster-kubeconfig-file> -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 <path-to-eks-cluster-kubeconfig-file> -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

Za vsako temo je faktor podvajanja 3 – najmanjša priporočena vrednost za zelo razpoložljive proizvodne sisteme.

Orodje za ustvarjanje obremenitve

Zagnali smo tri kopije generatorja obremenitve (vsak je pisal v svoji temi). Za sklope generatorja obremenitve morate nastaviti afiniteto vozlišč, tako da so razporejeni samo na vozliščih, ki so jim dodeljena:

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

Upoštevajte nekaj točk:

  • Generator nalaganja ustvari sporočila dolžine 512 bajtov in jih objavi v Kafki v paketih po 500 sporočil.
  • Uporaba argumenta -required-acks=all Objava se šteje za uspešno, ko so vse sinhronizirane replike sporočila prejete in potrjene s strani Kafka brokers. To pomeni, da v merilu uspešnosti nismo merili le hitrosti voditeljev, ki so prejemali sporočila, ampak tudi njihove sledilce, ki so sporočila replicirali. Namen tega testa ni ocenjevanje hitrosti branja potrošnikov (potrošniki) nedavno prejetih sporočil, ki še vedno ostanejo v predpomnilniku strani OS, in primerjava s hitrostjo branja sporočil, shranjenih na disku.
  • Generator obremenitve poganja 20 delavcev vzporedno (-workers=20). Vsak delavec vsebuje 5 proizvajalcev, ki si delijo povezavo delavca z grozdom Kafka. Posledično ima vsak generator 100 proizvajalcev in vsi pošiljajo sporočila grozdu Kafka.

Spremljanje zdravja grozda

Med obremenitvenim testiranjem gruče Kafka smo spremljali tudi njeno zdravje, da bi zagotovili, da ni bilo ponovnih zagonov sklopa, nesinhroniziranih replik in največjo prepustnost z minimalnimi nihanji:

  • Generator obremenitve piše standardno statistiko o številu objavljenih sporočil in stopnji napak. Stopnja napak bi morala ostati enaka 0,00%.
  • Tempomat, ki ga je namestil kafka-operator, ponuja nadzorno ploščo, kjer lahko spremljamo tudi stanje gruče. Za ogled te plošče naredite:
    supertubes cluster cruisecontrol show -n kafka --kubeconfig <path-to-eks-cluster-kubeconfig-file>
  • raven ISR (število "sinhroniziranih" replik) krčenje in razširitev sta enaka 0.

Rezultati meritev

3 posredniki, velikost sporočila - 512 bajtov

S particijami, enakomerno porazdeljenimi med tri posrednike, smo lahko dosegli uspešnost ~500 Mb/s (približno 990 tisoč sporočil na sekundo):

Določite ustrezno velikost za gručo Kafka v Kubernetesu

Določite ustrezno velikost za gručo Kafka v Kubernetesu

Določite ustrezno velikost za gručo Kafka v Kubernetesu

Poraba pomnilnika virtualnega stroja JVM ni presegla 2 GB:

Določite ustrezno velikost za gručo Kafka v Kubernetesu

Določite ustrezno velikost za gručo Kafka v Kubernetesu

Določite ustrezno velikost za gručo Kafka v Kubernetesu

Prepustnost diska je dosegla največjo prepustnost V/I vozlišča na vseh treh instancah, na katerih so delovali posredniki:

Določite ustrezno velikost za gručo Kafka v Kubernetesu

Določite ustrezno velikost za gručo Kafka v Kubernetesu

Določite ustrezno velikost za gručo Kafka v Kubernetesu

Iz podatkov o porabi pomnilnika po vozliščih izhaja, da je sistemsko medpomnjenje in predpomnjenje zavzelo ~10-15 GB:

Določite ustrezno velikost za gručo Kafka v Kubernetesu

Določite ustrezno velikost za gručo Kafka v Kubernetesu

Določite ustrezno velikost za gručo Kafka v Kubernetesu

3 posredniki, velikost sporočila - 100 bajtov

Ko se velikost sporočila zmanjša, se prepustnost zmanjša za približno 15–20 %: čas, porabljen za obdelavo posameznega sporočila, vpliva na to. Poleg tega se je obremenitev procesorja skoraj podvojila.

Določite ustrezno velikost za gručo Kafka v Kubernetesu

Določite ustrezno velikost za gručo Kafka v Kubernetesu

Določite ustrezno velikost za gručo Kafka v Kubernetesu

Ker imajo posredniška vozlišča še vedno neuporabljena jedra, je zmogljivost mogoče izboljšati s spremembo konfiguracije Kafka. To ni lahka naloga, zato je za povečanje prepustnosti bolje delati z večjimi sporočili.

4 posredniki, velikost sporočila - 512 bajtov

Učinkovitost gruče Kafka lahko enostavno povečate tako, da preprosto dodate nove posrednike in vzdržujete ravnovesje particij (to zagotavlja, da je obremenitev enakomerno porazdeljena med posredniki). V našem primeru se je po dodajanju posrednika prepustnost gruče povečala na ~580 Mb/s (~1,1 milijona sporočil na sekundo). Rast se je izkazala za nižjo od pričakovane: to je predvsem posledica neravnovesja particij (vsi posredniki ne delujejo na vrhuncu svojih zmožnosti).

Določite ustrezno velikost za gručo Kafka v Kubernetesu

Določite ustrezno velikost za gručo Kafka v Kubernetesu

Določite ustrezno velikost za gručo Kafka v Kubernetesu

Določite ustrezno velikost za gručo Kafka v Kubernetesu

Poraba pomnilnika stroja JVM je ostala pod 2 GB:

Določite ustrezno velikost za gručo Kafka v Kubernetesu

Določite ustrezno velikost za gručo Kafka v Kubernetesu

Določite ustrezno velikost za gručo Kafka v Kubernetesu

Določite ustrezno velikost za gručo Kafka v Kubernetesu

Na delo posrednikov s pogoni je vplivalo neravnovesje particij:

Določite ustrezno velikost za gručo Kafka v Kubernetesu

Določite ustrezno velikost za gručo Kafka v Kubernetesu

Določite ustrezno velikost za gručo Kafka v Kubernetesu

Določite ustrezno velikost za gručo Kafka v Kubernetesu

Ugotovitve

Iterativni pristop, predstavljen zgoraj, je mogoče razširiti tako, da zajema bolj zapletene scenarije, ki vključujejo na stotine potrošnikov, ponovno razdelitev, tekoče posodobitve, ponovne zagone sklopov itd. Vse to nam omogoča, da ocenimo meje zmogljivosti grozda Kafka v različnih pogojih, prepoznamo ozka grla v njegovem delovanju in poiščemo načine za boj proti njim.

Supertubes smo zasnovali za hitro in preprosto uvajanje gruče, njeno konfiguracijo, dodajanje/odstranjevanje posrednikov in tem, odzivanje na opozorila in zagotavljanje, da Kafka na splošno pravilno deluje v Kubernetesu. Naš cilj je, da vam pomagamo, da se osredotočite na glavno nalogo (»generiranje« in »poraba« Kafkinih sporočil), vse trdo delo pa prepustite Supertubesu in operaterju Kafka.

Če vas zanimajo tehnologije Banzai Cloud in odprtokodni projekti, se naročite na podjetje na GitHub, LinkedIn ali Twitter.

PS od prevajalca

Preberite tudi na našem blogu:

Vir: www.habr.com

Dodaj komentar