Bepaal de juiste grootte voor een Kafka-cluster in Kubernetes

Opmerking. vert.: In dit artikel deelt Banzai Cloud een voorbeeld van hoe de aangepaste tools kunnen worden gebruikt om Kafka gebruiksvriendelijker te maken binnen Kubernetes. De volgende instructies illustreren hoe u de optimale omvang van uw infrastructuur kunt bepalen en Kafka zelf kunt configureren om de vereiste doorvoer te bereiken.

Bepaal de juiste grootte voor een Kafka-cluster in Kubernetes

Apache Kafka is een gedistribueerd streamingplatform voor het creëren van betrouwbare, schaalbare en krachtige realtime streamingsystemen. De indrukwekkende mogelijkheden kunnen worden uitgebreid met Kubernetes. Hiervoor hebben wij ontwikkeld Open Source Kafka-operator en een tool genaamd superbuizen. Ze stellen u in staat Kafka op Kubernetes te draaien en de verschillende functies ervan te gebruiken, zoals het verfijnen van de brokerconfiguratie, op statistieken gebaseerde schaling met herbalancering, rackbewustzijn, ‘zacht’ (bevallig) updates uitrollen etc.

Probeer Supertubes in jouw cluster:

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

Of contacteer documentatie. U kunt ook lezen over enkele mogelijkheden van Kafka, waarvan het werk wordt geautomatiseerd met behulp van Supertubes en de Kafka-operator. We hebben er al over geschreven op de blog:

Wanneer u besluit een Kafka-cluster op Kubernetes te implementeren, wordt u waarschijnlijk geconfronteerd met de uitdaging om de optimale omvang van de onderliggende infrastructuur te bepalen en de noodzaak om uw Kafka-configuratie af te stemmen op de doorvoervereisten. De maximale prestaties van elke broker worden bepaald door de prestaties van de onderliggende infrastructuurcomponenten, zoals geheugen, processor, schijfsnelheid, netwerkbandbreedte, enz.

Idealiter zou de brokerconfiguratie zodanig moeten zijn dat alle infrastructuurelementen optimaal worden benut. In het echte leven is deze opzet echter behoorlijk complex. Het is waarschijnlijker dat gebruikers makelaars zullen configureren om het gebruik van een of twee componenten (schijf, geheugen of processor) te maximaliseren. Over het algemeen levert een makelaar maximale prestaties wanneer de configuratie ervan toestaat dat de langzaamste component volledig wordt gebruikt. Zo kunnen wij een globaal beeld krijgen van de last die één makelaar aankan.

Theoretisch kunnen we ook een schatting maken van het aantal makelaars dat nodig is om een ​​bepaalde lading af te handelen. In de praktijk zijn er echter zoveel configuratieopties op verschillende niveaus dat het erg moeilijk (zo niet onmogelijk) is om de potentiële prestaties van een bepaalde configuratie te beoordelen. Met andere woorden: het is erg moeilijk om een ​​configuratie te plannen op basis van bepaalde prestaties.

Voor Supertubes-gebruikers hanteren we meestal de volgende aanpak: we beginnen met een configuratie (infrastructuur + instellingen), meten vervolgens de prestaties ervan, passen de brokerinstellingen aan en herhalen het proces opnieuw. Dit gebeurt totdat het langzaamste onderdeel van de infrastructuur volledig is benut.

Op deze manier krijgen we een duidelijker beeld van hoeveel makelaars een cluster nodig heeft om een ​​bepaalde belasting af te handelen (het aantal makelaars hangt ook af van andere factoren, zoals het minimum aantal berichtreplica’s om veerkracht te garanderen, het aantal partitie leiders, enz.). Daarnaast krijgen we inzicht in welke infrastructuurcomponenten verticale schaalvergroting vereisen.

In dit artikel gaan we in op de stappen die we nemen om het meeste uit de langzaamste componenten in initiële configuraties te halen en de doorvoer van een Kafka-cluster te meten. Voor een zeer veerkrachtige configuratie zijn minimaal drie actieve makelaars vereist (min.insync.replicas=3), verdeeld over drie verschillende toegankelijkheidszones. Om de Kubernetes-infrastructuur te configureren, te schalen en te monitoren, gebruiken we ons eigen containerbeheerplatform voor hybride clouds - Pijpleiding. Het ondersteunt on-premise (bare metal, VMware) en vijf soorten clouds (Alibaba, AWS, Azure, Google, Oracle), evenals elke combinatie daarvan.

Gedachten over de Kafka-clusterinfrastructuur en -configuratie

Voor de onderstaande voorbeelden hebben we AWS als cloudprovider en EKS als Kubernetes-distributie gekozen. Een soortgelijke configuratie kan worden geïmplementeerd met behulp van P.K.E. - Kubernetes-distributie vanuit Banzai Cloud, gecertificeerd door CNCF.

schijf

Amazon biedt verschillende EBS-volumetypen. In de kern gp2 и io1 er zijn echter SSD-schijven die een hoge doorvoer garanderen gp2 verbruikt opgebouwde credits (I/O-credits), dus we gaven de voorkeur aan het type io1, wat een consistente hoge doorvoer biedt.

Instantietypen

De prestaties van Kafka zijn sterk afhankelijk van de paginacache van het besturingssysteem, dus we hebben instances nodig met voldoende geheugen voor de brokers (JVM) en paginacache. Voorbeeld c5.2xgroot - een goed begin, aangezien het 16 GB geheugen heeft en geoptimaliseerd om met EBS te werken. Het nadeel is dat hij maximaal 30 minuten per 24 uur maximale prestaties kan leveren. Als uw werklast gedurende een langere periode topprestaties vereist, kunt u andere exemplaartypen overwegen. Dat is precies wat we deden: we stopten bij c5.4xgroot. Het biedt maximale doorvoer in 593,75 Mb/sec. Maximale doorvoer van een EBS-volume io1 hoger dan de instantie c5.4xgroot, dus het langzaamste element van de infrastructuur is waarschijnlijk de I/O-doorvoer van dit instantietype (wat onze belastingtests ook zouden moeten bevestigen).

Сеть

De netwerkdoorvoer moet groot genoeg zijn in vergelijking met de prestaties van de VM-instantie en schijf, anders wordt het netwerk een knelpunt. In ons geval de netwerkinterface c5.4xgroot ondersteunt snelheden tot 10 Gb/s, wat aanzienlijk hoger is dan de I/O-doorvoer van een VM-instantie.

Inzet makelaar

Brokers moeten worden ingezet (gepland in Kubernetes) op specifieke knooppunten om te voorkomen dat ze concurreren met andere processen om CPU-, geheugen-, netwerk- en schijfbronnen.

Java-versie

De logische keuze is Java 11 omdat het compatibel is met Docker in die zin dat de JVM correct bepaalt welke processors en geheugen beschikbaar zijn voor de container waarin de broker draait. Wetende dat processorlimieten belangrijk zijn, stelt de JVM intern en transparant het aantal GC-threads en JIT-threads in. We gebruikten de afbeelding van Kafka banzaicloud/kafka:2.13-2.4.0, inclusief Kafka-versie 2.4.0 (Scala 2.13) op Java 11.

Als je meer wilt weten over Java/JVM op Kubernetes, bekijk dan onze volgende berichten:

Instellingen voor makelaargeheugen

Er zijn twee belangrijke aspecten bij het configureren van brokergeheugen: instellingen voor de JVM en voor de Kubernetes-pod. De geheugenlimiet die is ingesteld voor een pod moet groter zijn dan de maximale heapgrootte, zodat de JVM ruimte heeft voor de Java-metaruimte, die zich in zijn eigen geheugen bevindt, en voor de paginacache van het besturingssysteem, die Kafka actief gebruikt. In onze tests hebben we Kafka-makelaars met parameters gelanceerd -Xmx4G -Xms2G, en de geheugenlimiet voor de pod was 10 Gi. Houd er rekening mee dat geheugeninstellingen voor de JVM automatisch kunnen worden verkregen met behulp van -XX:MaxRAMPercentage и -X:MinRAMPercentage, gebaseerd op de geheugenlimiet voor de pod.

Broker-processorinstellingen

Over het algemeen kunt u de prestaties verbeteren door de parallelliteit te vergroten door het aantal threads dat door Kafka wordt gebruikt te vergroten. Hoe meer processors beschikbaar zijn voor Kafka, hoe beter. In onze test zijn we begonnen met een limiet van 6 processors en hebben we dit aantal geleidelijk (via iteraties) verhoogd naar 15. Daarnaast hebben we num.network.threads=12 in de brokerinstellingen om het aantal threads te vergroten dat gegevens van het netwerk ontvangt en verzendt. Ze ontdekten onmiddellijk dat de volgersmakelaars niet snel genoeg replica's konden ontvangen en verhoogden num.replica.fetchers naar 4 om de snelheid te verhogen waarmee volgersmakelaars berichten van leiders repliceerden.

Hulpmiddel voor het genereren van ladingen

U moet ervoor zorgen dat de geselecteerde belastinggenerator niet zonder capaciteit komt te zitten voordat het Kafka-cluster (dat wordt gebenchmarkt) zijn maximale belasting bereikt. Met andere woorden, het is noodzakelijk om een ​​voorlopige beoordeling uit te voeren van de mogelijkheden van de tool voor het genereren van belasting, en er ook instantietypen voor te selecteren met een voldoende aantal processors en geheugen. In dit geval zal onze tool meer belasting produceren dan het Kafka-cluster aankan. Na veel experimenteren zijn we uitgekomen op drie exemplaren c5.4xgroot, die elk een draaiende generator hadden.

Benchmarking

Prestatiemeting is een iteratief proces dat de volgende fasen omvat:

  • het opzetten van infrastructuur (EKS-cluster, Kafka-cluster, tool voor het genereren van belasting, evenals Prometheus en Grafana);
  • het genereren van een belasting voor een bepaalde periode om willekeurige afwijkingen in de verzamelde prestatie-indicatoren te filteren;
  • het aanpassen van de infrastructuur en configuratie van de makelaar op basis van waargenomen prestatie-indicatoren;
  • het proces herhalen totdat het vereiste niveau van Kafka-clusterdoorvoer is bereikt. Tegelijkertijd moet het consistent reproduceerbaar zijn en minimale variaties in de doorvoer vertonen.

In het volgende gedeelte worden de stappen beschreven die zijn uitgevoerd tijdens het benchmarkingproces van het testcluster.

Gereedschap

De volgende tools zijn gebruikt om snel een basisconfiguratie te implementeren, belastingen te genereren en de prestaties te meten:

  • Banzai Cloud-pijplijn voor het organiseren van een EKS-cluster van Amazon c Prometheus (om Kafka- en infrastructuurstatistieken te verzamelen) en grafana (om deze statistieken te visualiseren). Wij hebben geprofiteerd geïntegreerd в Pijpleiding services die federatieve monitoring, gecentraliseerde verzameling van logbestanden, scannen op kwetsbaarheden, noodherstel, beveiliging op bedrijfsniveau en nog veel meer bieden.
  • Sangrenel — een hulpmiddel voor het testen van de belasting van een Kafka-cluster.
  • Grafana-dashboards voor het visualiseren van Kafka-statistieken en infrastructuur: Kubernetes Kafka, Knooppuntexporteur.
  • Supertubes CLI voor de eenvoudigste manier om een ​​Kafka-cluster op Kubernetes op te zetten. Zookeeper, Kafka-operator, Envoy en vele andere componenten zijn geïnstalleerd en correct geconfigureerd om een ​​productieklaar Kafka-cluster op Kubernetes te draaien.
    • Voor installatie superbuizen CLI gebruik de meegeleverde instructies hier.

Bepaal de juiste grootte voor een Kafka-cluster in Kubernetes

EKS-cluster

Bereid een EKS-cluster voor met speciale werkknooppunten c5.4xgroot in verschillende beschikbaarheidszones voor pods met Kafka-makelaars, evenals speciale knooppunten voor de belastinggenerator en monitoringinfrastructuur.

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

Zodra het EKS-cluster actief is, schakelt u de integratie ervan in bewakingsdienst – ze zal Prometheus en Grafana in een cluster inzetten.

Kafka-systeemcomponenten

Installeer Kafka-systeemcomponenten (Zookeeper, kafka-operator) in EKS met behulp van supertubes CLI:

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

Kafka-cluster

Standaard gebruikt EKS EBS-volumes van het type gp2, dus u moet een afzonderlijke opslagklasse maken op basis van volumes io1 voor Kafka-cluster:

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

Stel de parameter voor makelaars in min.insync.replicas=3 en implementeer brokerpods op knooppunten in drie verschillende beschikbaarheidszones:

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

Onderwerpen

We hebben drie instanties van de laadgenerator parallel uitgevoerd. Elk van hen schrijft over zijn eigen onderwerp, dat wil zeggen dat we in totaal drie onderwerpen nodig hebben:

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

Voor elk onderwerp is de replicatiefactor 3: de minimaal aanbevolen waarde voor productiesystemen met hoge beschikbaarheid.

Hulpmiddel voor het genereren van ladingen

We hebben drie exemplaren van de belastinggenerator gelanceerd (elk geschreven in een apart onderwerp). Voor load generator-pods moet u de knooppuntaffiniteit zo instellen dat deze alleen worden gepland op de knooppunten die eraan zijn toegewezen:

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

Een paar aandachtspunten:

  • De laadgenerator genereert berichten met een lengte van 512 bytes en publiceert deze naar Kafka in batches van 500 berichten.
  • Een argument gebruiken -required-acks=all De publicatie wordt als succesvol beschouwd wanneer alle gesynchroniseerde replica's van het bericht zijn ontvangen en bevestigd door Kafka-makelaars. Dit betekent dat we in de benchmark niet alleen de snelheid hebben gemeten van leiders die berichten ontvangen, maar ook van hun volgers die berichten repliceren. Het doel van deze test is niet om de leessnelheid van de consument te evalueren (consumenten) onlangs ontvangen berichten die nog steeds in de cache van de besturingssysteempagina staan, en de vergelijking ervan met de leessnelheid van berichten die op schijf zijn opgeslagen.
  • De belastinggenerator laat 20 werknemers parallel draaien (-workers=20). Elke werker bevat vijf producenten die de verbinding van de werker met het Kafka-cluster delen. Als gevolg hiervan heeft elke generator 5 producenten en ze sturen allemaal berichten naar het Kafka-cluster.

Bewaken van de status van het cluster

Tijdens het testen van de belasting van het Kafka-cluster hebben we ook de status ervan gecontroleerd om er zeker van te zijn dat er geen pod-herstarts waren, geen niet-gesynchroniseerde replica's en maximale doorvoer met minimale fluctuaties:

  • De loadgenerator schrijft standaardstatistieken over het aantal gepubliceerde berichten en het foutenpercentage. Het foutenpercentage moet hetzelfde blijven 0,00%.
  • Cruise Control, ingezet door kafka-operator, biedt een dashboard waarop we ook de status van het cluster kunnen monitoren. Om dit paneel te bekijken, doet u het volgende:
    supertubes cluster cruisecontrol show -n kafka --kubeconfig <path-to-eks-cluster-kubeconfig-file>
  • ISR-niveau (aantal "gesynchroniseerde" replica's) krimp en uitzetting zijn gelijk aan 0.

Meetresultaten

3 makelaars, berichtgrootte - 512 bytes

Met partities gelijkmatig verdeeld over drie makelaars konden we prestaties behalen ~500 Mb/s (ongeveer 990 berichten per seconde):

Bepaal de juiste grootte voor een Kafka-cluster in Kubernetes

Bepaal de juiste grootte voor een Kafka-cluster in Kubernetes

Bepaal de juiste grootte voor een Kafka-cluster in Kubernetes

Het geheugenverbruik van de virtuele JVM-machine was niet groter dan 2 GB:

Bepaal de juiste grootte voor een Kafka-cluster in Kubernetes

Bepaal de juiste grootte voor een Kafka-cluster in Kubernetes

Bepaal de juiste grootte voor een Kafka-cluster in Kubernetes

De schijfdoorvoer bereikte de maximale doorvoer van het I/O-knooppunt op alle drie de instanties waarop de brokers actief waren:

Bepaal de juiste grootte voor een Kafka-cluster in Kubernetes

Bepaal de juiste grootte voor een Kafka-cluster in Kubernetes

Bepaal de juiste grootte voor een Kafka-cluster in Kubernetes

Uit de gegevens over het geheugengebruik door knooppunten volgt dat systeembuffering en caching ongeveer 10-15 GB in beslag namen:

Bepaal de juiste grootte voor een Kafka-cluster in Kubernetes

Bepaal de juiste grootte voor een Kafka-cluster in Kubernetes

Bepaal de juiste grootte voor een Kafka-cluster in Kubernetes

3 makelaars, berichtgrootte - 100 bytes

Naarmate de berichtgrootte kleiner wordt, daalt de doorvoer met ongeveer 15-20%: de tijd die wordt besteed aan het verwerken van elk bericht heeft hierop invloed. Bovendien is de processorbelasting bijna verdubbeld.

Bepaal de juiste grootte voor een Kafka-cluster in Kubernetes

Bepaal de juiste grootte voor een Kafka-cluster in Kubernetes

Bepaal de juiste grootte voor een Kafka-cluster in Kubernetes

Omdat brokerknooppunten nog steeds ongebruikte kernen hebben, kunnen de prestaties worden verbeterd door de Kafka-configuratie te wijzigen. Dit is geen gemakkelijke taak, dus om de doorvoer te vergroten is het beter om met grotere berichten te werken.

4 makelaars, berichtgrootte - 512 bytes

U kunt de prestaties van een Kafka-cluster eenvoudig verhogen door eenvoudigweg nieuwe makelaars toe te voegen en een evenwicht tussen partities te behouden (dit zorgt ervoor dat de belasting gelijkmatig over de makelaars wordt verdeeld). In ons geval nam de clusterdoorvoer toe na het toevoegen van een makelaar ~580 Mb/s (~1,1 miljoen berichten per seconde). De groei bleek minder dan verwacht: dit wordt voornamelijk verklaard door de onevenwichtigheid van de partities (niet alle makelaars werken op het hoogtepunt van hun kunnen).

Bepaal de juiste grootte voor een Kafka-cluster in Kubernetes

Bepaal de juiste grootte voor een Kafka-cluster in Kubernetes

Bepaal de juiste grootte voor een Kafka-cluster in Kubernetes

Bepaal de juiste grootte voor een Kafka-cluster in Kubernetes

Het geheugenverbruik van de JVM-machine bleef onder de 2 GB:

Bepaal de juiste grootte voor een Kafka-cluster in Kubernetes

Bepaal de juiste grootte voor een Kafka-cluster in Kubernetes

Bepaal de juiste grootte voor een Kafka-cluster in Kubernetes

Bepaal de juiste grootte voor een Kafka-cluster in Kubernetes

Het werk van makelaars met schijven werd beïnvloed door de onbalans van partities:

Bepaal de juiste grootte voor een Kafka-cluster in Kubernetes

Bepaal de juiste grootte voor een Kafka-cluster in Kubernetes

Bepaal de juiste grootte voor een Kafka-cluster in Kubernetes

Bepaal de juiste grootte voor een Kafka-cluster in Kubernetes

Bevindingen

De hierboven gepresenteerde iteratieve aanpak kan worden uitgebreid om complexere scenario's te dekken waarbij honderden consumenten betrokken zijn, herpartitionering, rolling updates, herstarten van pods, enz. Dit alles stelt ons in staat de grenzen van de capaciteiten van het Kafka-cluster onder verschillende omstandigheden te beoordelen, knelpunten in de werking ervan te identificeren en manieren te vinden om deze te bestrijden.

We hebben Supertubes ontworpen om snel en eenvoudig een cluster te implementeren, te configureren, makelaars en onderwerpen toe te voegen/verwijderen, op waarschuwingen te reageren en ervoor te zorgen dat Kafka in het algemeen goed werkt op Kubernetes. Ons doel is om u te helpen zich te concentreren op de hoofdtaak (“Kafka-berichten genereren” en “consumeren”), en al het harde werk over te laten aan Supertubes en de Kafka-operator.

Als u geïnteresseerd bent in Banzai Cloud-technologieën en Open Source-projecten, abonneer u dan op het bedrijf op GitHub, LinkedIn of Twitter.

PS van vertaler

Lees ook op onze blog:

Bron: www.habr.com

Voeg een reactie