Best Practices voor het schalen van Kafka-gebaseerde workloads

Apache Kafka staat bekend om zijn vermogen om een enorme hoeveelheid gebeurtenissen in real-time te verwerken. Om echter miljoenen gebeurtenissen te kunnen verwerken, moeten we bepaalde best practices volgen bij het implementeren van zowel Kafka-producerdiensten als consumenten diensten.

Voordat we beginnenmet het gebruik van Kafkain je projecten, laten we begrijpen wanneer we Kafka moeten gebruiken:

  • Hoge-volume gebeurtenisstromenWanneer je applicatie/dienst een continue stroom van gebeurtenissen genereert, zoals gebruikersactiviteit, websiteklikgebeurtenissen, sensorgegevens, logboekgebeurtenissen of updates van de aandelenmarkt, is de mogelijkheid van Kafka om grote volumes met lage latentie te verwerken zeer nuttig.
  • Real-time analytics. Kafka is vooralzeer nuttig bij het bouwen van real-time dataverwerkingspijpleidingen, waar gegevens moeten worden verwerkt zodra ze binnenkomen. Het stelt je in staat om gegevens naar analytics-engines zoals Kafka streams, Apache Spark of Flink te streamen voor onmiddellijke analytics/inzichten en stream- of batchverwerking.
  • Ontkoppelen van applicaties. Als centrale berichtenhub kan het verschillende delen van een applicatie ontkoppelen, waardoor onafhankelijke ontwikkeling en schaalvergroting van diensten mogelijk is en het verantwoordelijk segregatieprincipe wordt aangemoedigd.
  • Data-integratie over systemenBij het integreren van gedistribueerde systemen kan Kafka efficiënt gegevens overdragen tussen verschillende toepassingen over teams/projecten heen, als betrouwbare gegevensmakelaar.

Belangrijkste verschillen met andere wachtrij systemen 

Hieronder staan de verschillen van Apache Kafka ten opzichte van systemen zoals ActiveMQ, ZeroMQ en VerneMQ:

Permanente Opslag

Kafka slaat gebeurtenissen op in een gedistribueerd logboek, waardoor het mogelijk is om gegevens op elk moment opnieuw af te spelen en gegevenspersistentie zelfs in geval van systeem-/node-storingen mogelijk is, in tegenstelling tot sommige traditionele berichtenwachtrijen, die kunnen vertrouwen op in-memory opslag zoals Redis.

Partitionering

Gegevens zijn verdeeld over brokers/topics, waardoor parallelle verwerking van grote gegevensstromen en een hoge doorvoer mogelijk is. Dit helpt consumentendraden om verbinding te maken met individuele partitionering, waardoor horizontale schaalbaarheid wordt bevorderd.

Consumentengroepen

Meerdere consumenten kunnen zich abonneren op hetzelfde onderwerp en van verschillende offsets binnen een partitie lezen, wat duplicaatconsumptiepatronen mogelijk maakt voor verschillende teams om dezelfde gegevens voor verschillende doeleinden te consumeren en te verwerken. Enkele voorbeelden zijn:

  • Gebruikersactiviteit geconsumeerd door ML-teams om verdachte activiteiten te detecteren
  • Aanbevelingsteam om aanbevelingen te bouwen
  • Advertentieteam om relevante advertenties te genereren

Kafka Producer Best Practices

Batchgrootte en Wachttijd

Door batch.size en linger.ms te configureren, kunt u de doorvoer van uw Kafka-producent verhogen. batch.size is de maximale grootte van de batch in bytes. Kafka zal proberen deze te batchen voordat deze naar producenten wordt verzonden. 

linger.ms bepaalt de maximale tijd in milliseconden dat de producent zal wachten op aanvullende berichten die aan de batch moeten worden toegevoegd voor verwerking. 

Het configureren van de instellingen batch size en linger.ms helpt aanzienlijk bij de prestaties van het systeem door te bepalen hoeveel gegevens worden geaccumuleerd voordat ze naar verwerkingssystemen worden verzonden, waardoor een betere doorvoer en verminderde latenties mogelijk zijn bij het omgaan met grote hoeveelheden gegevens. Het kan ook lichte vertragingen introduceren, afhankelijk van de gekozen waarden. Vooral een grote batchgrootte met een juiste linger.ms kan de efficiëntie van gegevensoverdracht optimaliseren.

Compressie

Een andere manier om de doorvoer te verhogen, is door compressie in te schakelen via de configuratie compression.type. De producent kan gegevens comprimeren met gzip, snappy of lz4 voordat deze naar de brokers worden verzonden. Voor grote datavolumes helpt deze configuratie de compressie-overhead met netwerkefficiëntie. Het bespaart ook bandbreedte en verhoogt de doorvoer van het systeem. Daarnaast kunnen we door de juiste serializer en sleutelserializer in te stellen, ervoor zorgen dat gegevens worden geserialiseerd in een formaat dat compatibel is met uw consumenten.

Herhalingen en Idempotentie

Om de betrouwbaarheid van de Kafka-producent te waarborgen, moet u herhalingen en idempotentie inschakelen. Door retries te configureren, kan de producent automatisch elke batch gegevens opnieuw verzenden die niet binnen een bepaald aantal pogingen door de broker is ack.

Acknowledgments

Deze configuratie controleert het niveau van bevestiging dat van de broker vereist is voordat een bericht als succesvol verzonden wordt beschouwd. Door het juiste acks-niveau te kiezen, kunt u de betrouwbaarheid van uw applicatie controleren. Hieronder staan de geaccepteerde waarden voor deze configuratie.

  • 0 – snelst, maar geen garantie voor berichtbezorging.
  • 1 – het bericht wordt bevestigd zodra het naar de leidende broker is geschreven, wat basisbetrouwbaarheid biedt.
  • all – het bericht wordt pas als afgeleverd beschouwd wanneer alle replica’s het hebben bevestigd, wat hoge duurzaamheid garandeert.

Configuratie-afstemming op basis van workload

Je zou moeten beginnen met het bijhouden van metrieken zoals berichtverzendsnelheid, batchgrootte en foutenpercentages om prestatieknelpunten te identificeren. Controleer en pas regelmatig de producentinstellingen aan op basis van de wijzigingen of updates van de functie/gegevens.

Beste praktijken voor Kafka Consumer

Consumentengroepen

Elke Kafka-consument moet tot een consumentengroep behoren; een consumentengroep kan één of meer consumenten bevatten. Door meer consumenten in de groep te creëren, kunt u opschalen om van alle partities te lezen, waardoor u een grote hoeveelheid gegevens kunt verwerken. De configuratie group.id helpt bij het identificeren van de consumentengroep waartoe de consument behoort, waardoor er een evenwichtige belasting is over meerdere consumenten die van hetzelfde onderwerp consumeren. De beste praktijk is om zinvolle groeps-ID’s te gebruiken om consumentengroepen binnen uw toepassing gemakkelijk te identificeren. Deze configuratie helpt bij het identificeren van de consumentengroep waartoe de consument behoort en zorgt voor een evenwichtige belasting over meerdere consumenten die van hetzelfde onderwerp consumeren. De beste praktijk is om zinvolle groeps-ID’s te gebruiken om consumentengroepen binnen uw toepassing gemakkelijk te identificeren. 

Offset vastleggen

Je kunt controleren wanneer je applicatie offsets vastlegt, wat kan helpen om gegevensverlies te voorkomen. Er zijn twee manieren om offsets vast te leggen: automatisch en handmatig. Voor toepassingen met een hoge doorvoer moet je overwegen om handmatig vastleggen te gebruiken voor meer controle.

  • auto.offset.reset – definieert wat te doen wanneer een consument begint met het consumeren van een onderwerp zonder vastgelegde offsets (bijv. een nieuw onderwerp of een consument die voor de eerste keer lid wordt van een groep). Opties zijn onder andere earliest (lezen vanaf het begin), latest (lezen vanaf het einde) of none (een fout genereren). Kies “earliest” voor de meeste gebruiksscenario’s om te voorkomen dat er gegevens worden gemist wanneer een nieuwe consument zich bij een groep voegt.Regelt hoe een consument begint met het consumeren van gegevens, zodat het juiste gedrag wordt gewaarborgd wanneer een consument opnieuw wordt gestart of aan een groep wordt toegevoegd.
  • enable.auto.commithelpt bij het configureren om offsets periodiek automatisch vast te leggen. Over het algemeen stellen we de waarde in op false voor de meeste productiescenario’s waar we geen hoge betrouwbaarheid nodig hebben en offsets handmatig binnen uw toepassingslogica vastleggen om verwerking exact eenmaal te garanderen.Biedt controle om offset-vastlegging te beheren, waardoor meer controle over gegevensverwerking mogelijk is.
  • auto.commit.interval.ms interval in milliseconden waarop offsets automatisch worden vastgelegd als enable.auto.commit is ingesteld op true. Pas aan op basis van de verwerkingstijd van uw applicatie om gegevensverlies te voorkomen als gevolg van onverwachte fouten.

Ophaalgrootte en Max Poll Records

Deze configuratie helpt bij het regelen van het aantal records dat wordt opgehaald in elke aanvraag, configureer de fetch.min.bytes en max.poll.records. Het verhogen van deze waarde kan de doorvoer van uw applicaties verbeteren, terwijl het CPU-gebruik vermindert en het aantal oproepen naar brokers vermindert.

  • fetch.min.bytes – het minimum aantal bytes dat moet worden opgehaald van een broker in een enkel pollverzoek. Stel een kleine waarde in om onnodige netwerkoproepen te voorkomen, maar niet te klein om overmatige polling te voorkomen. Het helpt bij het optimaliseren van de netwerkefficiëntie door kleine, frequente verzoeken te voorkomen.
  • fetch.max.bytes – the maximum aantal bytes dat moet worden opgehaald bij een broker in één pollverzoek. Pas aan op basis van beschikbaar geheugen om overbelasting van de consumentenwerkers te voorkomen. Hierdoor wordt de hoeveelheid opgehaalde gegevens in één poll verminderd, waardoor geheugenproblemen worden voorkomen.
  • max.poll.interval.ms – de maximale wachttijd voor een pollverzoek om gegevens terug te geven voordat het time-out raakt. Stel een goede time-out in om consumentenblokkeringen/vertragingen te voorkomen als er geen gegevens beschikbaar zijn. Het helpt om te voorkomen dat consumenten vast komen te zitten terwijl ze te lang op berichten wachten. (Soms kunnen k8s-pods opnieuw opstarten als de liveness probes worden beïnvloed).

Partition Assignment

Dit is de strategie die wordt gebruikt om partities (partition.assignment.strategy) toe te wijzen aan consumenten binnen een groep (bijv., range, roundrobin). Gebruik range voor de meeste scenario’s om partities gelijkmatig over consumenten te verdelen. Dit maakt de belasting gelijkmatig verdeeld onder consumenten in een groep.

Hier zijn enkele belangrijke overwegingen voordat u Kafka gebruikt:

  • Complexiteit. Het implementeren van Kafka vereist een dieper begrip van concepten van gedistribueerde systemen zoals partitionering en offsetbeheer vanwege de geavanceerde functies en configuraties.
  • Monitoring en beheer. Het implementeren van monitoring en beheer van Kafka-clusters is belangrijk om hoge beschikbaarheid en prestaties te waarborgen.
  • Beveiliging. Het implementeren van robuuste beveiligingspraktijken om gevoelige gegevens die door de Kafka-onderwerpen stromen te beschermen is ook belangrijk.

Het implementeren van deze beste praktijken kan je helpen om je op Kafka gebaseerde toepassingen te schalen om miljoenen/miljarden evenementen te verwerken. Het is echter belangrijk om te onthouden dat de optimale configuratie kan variëren op basis van de specifieke vereisten van je toepassing.

Source:
https://dzone.com/articles/best-practices-for-scaling-kafka-based-workloads