Kas yra Apache Kafka ir kodėl ji taip populiari
Jei kada nors bandėte perkelti milžinišką duomenų kiekį tarp skirtingų sistemų realiuoju laiku, tikriausiai suprantate, kokia tai gali būti galvos skausmas. Apache Kafka atsirado būtent tam, kad išspręstų šią problemą – tai paskirstyta srautinio duomenų perdavimo platforma, kuri tapo de facto standartu daugelyje šiuolaikinių organizacijų.
LinkedIn inžinieriai sukūrė Kafka 2011 metais, kai susidūrė su iššūkiu – kaip efektyviai tvarkyti vis didėjantį duomenų srautą tarp įvairių sistemų. Tradiciniai sprendimai tiesiog nebeišlaikė apkrovos. Dabar Kafka yra Apache Software Foundation projektas ir naudojamas tokių gigantų kaip Netflix, Uber, Spotify ir tūkstančių kitų kompanijų.
Pagrindinis Kafka privalumas – gebėjimas apdoroti milijonus įvykių per sekundę su minimaliu vėlavimu. Tai ne paprastas pranešimų brokeris, o pilnavertė srautinio duomenų apdorojimo platforma, kuri gali saugoti, perduoti ir apdoroti duomenis realiuoju laiku.
Kaip veikia Kafka architektūra
Kafka architektūra iš pirmo žvilgsnio gali atrodyti sudėtinga, bet pagrindinės koncepcijos yra gana paprastos. Viskas sukasi apie kelis pagrindinius komponentus.
Topics ir partitions – tai pagrindas. Topic galima įsivaizduoti kaip kategoriją ar srautą, į kurį rašomi pranešimai. Pavyzdžiui, galite turėti topic’ą „user-clicks” arba „payment-transactions”. Kiekvienas topic’as skaidomas į partitions – tai leidžia Kafka horizontaliai plėstis ir apdoroti duomenis lygiagrečiai.
Producers – tai aplikacijos, kurios siunčia duomenis į Kafka. Jie rašo pranešimus į konkrečius topic’us. Producer’is gali būti bet kas – web serveris, IoT įrenginys, kita aplikacija. Svarbu tai, kad producer’is nežino ir jam nerūpi, kas tuos duomenis skaitys.
Consumers – tai aplikacijos, kurios skaito duomenis iš Kafka. Jie prenumeruoja topic’us ir gauna pranešimus. Consumer’iai gali būti organizuoti į consumer groups, kas leidžia paskirstyti apkrovą tarp kelių instancijų.
Brokers – tai Kafka serveriai, kurie saugo duomenis ir aptarnauja producer’ius bei consumer’ius. Kafka cluster’yje paprastai būna keli brokeriai, kad būtų užtikrintas aukštas prieinamumas.
Vienas iš genialių Kafka sprendimų – duomenų saugojimas. Skirtingai nuo tradicinių pranešimų eilių, Kafka nesunaikina pranešimų iškart po to, kai jie nuskaitomi. Duomenys saugomi nustatytą laiką (pavyzdžiui, 7 dienas) ir gali būti skaitomi kelis kartus. Tai atveria daug galimybių – galite „atsukti laiką atgal” ir perskaityti senus duomenis, jei reikia.
Realūs panaudojimo scenarijai
Teorija teorija, bet kur Kafka tikrai spindi praktikoje? Pažiūrėkime į konkrečius pavyzdžius.
Realaus laiko analitika – įsivaizduokite e-komercijos platformą, kuri nori stebėti vartotojų elgesį realiuoju laiku. Kiekvienas klikštelėjimas, peržiūra, pirkimas siunčiami į Kafka. Iš ten duomenys gali tekti į analitikos sistemas, kurios generuoja insights’us tuo pat metu, kai vyksta įvykiai.
Log agregacija – jei turite mikroservisų architektūrą su šimtais servisų, logų surinkimas tampa košmaru. Kafka puikiai tinka centralizuotam logų rinkimui. Kiekvienas servisas siunčia savo logus į Kafka, o iš ten jie keliauja į Elasticsearch, Splunk ar kitą analizės įrankį.
Event sourcing – vietoj to, kad saugotumėte tik dabartinę būseną, saugote visų įvykių istoriją. Pavyzdžiui, banko sistemoje saugote ne tik dabartinį balanso stovį, bet ir kiekvieną transakciją. Kafka idealiai tinka tokiam pattern’ui, nes ji patikimai saugo įvykių seką.
Stream processing – naudojant Kafka Streams API arba Apache Flink, galite apdoroti duomenis jų kelionės metu. Pavyzdžiui, galite filtruoti, agregaoti, jungti kelis srautus – visa tai realiuoju laiku.
Netflix naudoja Kafka savo rekomendacijų sistemai – kiekvienas jūsų veiksmas platformoje keliauja per Kafka ir padeda formuoti, ką matysite toliau. Uber naudoja Kafka savo surge pricing sistemai – milijonai įvykių iš vairuotojų ir keleivių apdorojami realiuoju laiku.
Kafka diegimas ir konfigūracija
Gerai, norite išbandyti Kafka? Pradėkime nuo pagrindų. Paprasčiausias būdas – naudoti Docker. Štai minimali docker-compose.yml konfigūracija:
„`yaml
version: ‘3’
services:
zookeeper:
image: confluentinc/cp-zookeeper:latest
environment:
ZOOKEEPER_CLIENT_PORT: 2181
kafka:
image: confluentinc/cp-kafka:latest
depends_on:
– zookeeper
ports:
– „9092:9092”
environment:
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://localhost:9092
„`
Taip, jums reikės ZooKeeper (bent jau kol kas – naujos Kafka versijos pereina prie KRaft režimo be ZooKeeper). Paleiskite `docker-compose up` ir turite veikiančią Kafka instanciją.
Svarbiausios konfigūracijos, į kurias verta atkreipti dėmesį:
`retention.ms` – kiek laiko saugoti pranešimus. Numatytasis – 7 dienos, bet galite nustatyti ir neribotą saugojimą.
`num.partitions` – kiek partition’ų sukurti naujam topic’ui. Daugiau partition’ų = geresnė paralelizacija, bet ir daugiau overhead’o.
`replication.factor` – kiek kopijų kiekvieno partition’o turėti. Bent 2-3 production’e, kad užtikrintumėte aukštą prieinamumą.
`min.insync.replicas` – kiek replikų turi patvirtinti įrašą, kad jis būtų laikomas sėkmingu. Tai balanso tarp našumo ir patikimumo klausimas.
Praktinis patarimas – pradėkite su konservatyviomis nuostatomis ir optimizuokite pagal savo poreikius. Kafka gali būti labai greita, bet neteisingas konfigūravimas gali sukelti problemų.
Kafka Streams ir duomenų apdorojimas
Viena galingiausių Kafka dalių – Kafka Streams biblioteka. Ji leidžia kurti sudėtingas duomenų apdorojimo pipeline’us be papildomų cluster’ių ar framework’ų.
Paprastas pavyzdys Java kalba:
„`java
StreamsBuilder builder = new StreamsBuilder();
KStream
KStream
.filter((key, value) -> value.length() > 10)
.mapValues(value -> value.toUpperCase());
processed.to(„output-topic”);
„`
Šis kodas skaito duomenis iš „input-topic”, filtruoja tik tuos, kurių ilgis didesnis nei 10 simbolių, paverčia juos didžiosiomis raidėmis ir siunčia į „output-topic”. Viskas vyksta realiuoju laiku, su exactly-once semantika.
Windowing – viena iš galingiausių funkcijų. Galite grupuoti įvykius pagal laiko langus:
„`java
KTable
.groupByKey()
.windowedBy(TimeWindows.of(Duration.ofMinutes(5)))
.count();
„`
Tai suskaičiuoja įvykius kas 5 minutes. Puiku analitikai, agregacijoms, anomalijų aptikimui.
Joins – galite jungti kelis srautus. Pavyzdžiui, sujungti vartotojų klikštelėjimus su jų profilių informacija:
„`java
KStream
KTable
KStream
users,
(click, user) -> new EnrichedClick(click, user)
);
„`
Kafka Streams automatiškai tvarko būsenos valdymą, fault tolerance, paralelizaciją. Jums tereikia parašyti verslo logiką.
Našumo optimizavimas ir best practices
Kafka gali būti nepaprastai greita, bet tik jei žinote, ką darote. Štai keletas praktinių patarimų, kuriuos išmokau sunkiu keliu.
Batch’inimas – nesiunčiate kiekvieno pranešimo atskirai. Producer’iai automatiškai grupuoja pranešimus į batch’us, bet galite tai kontroliuoti per `linger.ms` ir `batch.size` parametrus. Didesni batch’ai = geresnis throughput, bet šiek tiek didesnis latency.
Compression – įjunkite kompresiją. `compression.type=snappy` arba `lz4` gali sumažinti duomenų kiekį 50-70% be didelio CPU kaštų. Tai reiškia mažiau network’o, mažiau disk I/O, geresnį našumą.
Partition’ų skaičius – daugiau ne visada geriau. Kiekvienas partition’as turi overhead’ą. Praktinis patarimas: pradėkite su partition’ų skaičiumi, lygiu maksimaliam consumer’ių skaičiui, kurį planuojate turėti. Galite padidinti vėliau (bet negalite sumažinti be topic’o perkūrimo).
Key’ų pasirinkimas – kaip pasirenkate partition’ą? Kafka naudoja key’ų hash’ą. Jei jūsų key’ai netolygiai paskirstyti, gausite „hot partition’us” – kai vienas partition’as gauna daug daugiau duomenų nei kiti. Stenkitės turėti tolygiai paskirstytus key’us.
Monitoring – be monitoringo Kafka production’e – savižudybė. Stebėkite: under-replicated partition’us (reiškia problemų), consumer lag (ar consumer’iai spėja apdoroti duomenis), broker metrics (CPU, disk, network). JMX metrics + Prometheus + Grafana – klasikinis setup’as.
Dar vienas dalykas – testing. Kafka turi puikią testcontainers integraciją. Galite lengvai rašyti integration testus:
„`java
@Container
KafkaContainer kafka = new KafkaContainer(
DockerImageName.parse(„confluentinc/cp-kafka:latest”)
);
// Naudokite kafka.getBootstrapServers() testuose
„`
Saugumo aspektai
Kafka saugumas dažnai būna užmirštas, kol nevėlu. Štai ką turite žinoti.
Authentication – Kafka palaiko SASL (Simple Authentication and Security Layer) su įvairiais mechanizmais: PLAIN, SCRAM, GSSAPI (Kerberos). Production’e niekada nenaudokite PLAINTEXT – visada SSL/TLS.
Authorization – ACL (Access Control Lists) leidžia kontroliuoti, kas gali skaityti/rašyti į konkrečius topic’us. Pavyzdžiui:
„`bash
kafka-acls –add –allow-principal User:alice \
–operation Read –topic payments \
–bootstrap-server localhost:9092
„`
Encryption – duomenys turėtų būti šifruojami tiek transit’e (SSL/TLS), tiek rest’e (disk encryption). Kafka palaiko SSL tarp client’ų ir broker’ių, taip pat tarp broker’ių.
Audit logging – žinokite, kas ir kada pasiekė jūsų duomenis. Confluent Platform turi įtaisytą audit logging, open source Kafka – galite naudoti trečiųjų šalių sprendimus.
Praktinis patarimas: pradėkite su saugumu nuo pat pradžių. Pridėti saugumą vėliau – skausmingas procesas, reikalaujantis downtime’o ir konfigūracijos migracijos.
Alternatyvos ir kada Kafka nėra geriausias pasirinkimas
Kafka yra nuostabi, bet ne visada tinkamiausia. Būkime sąžiningi.
RabbitMQ – jei jums reikia sudėtingo routing’o, priority queues, arba jūsų duomenų kiekiai nedideli, RabbitMQ gali būti paprastesnis pasirinkimas. Jis lengviau konfiguruojamas ir turi mažesnį operational overhead’ą.
AWS Kinesis – jei jau naudojate AWS ir nenorite valdyti infrastruktūros, Kinesis yra puikus managed alternatyva. Bet jis brangesnis ir turi mažiau features nei Kafka.
Apache Pulsar – naujesnis žaidėjas, kuris teigia esąs „next generation Kafka”. Turi įdomių features kaip multi-tenancy, geografinė replikacija out-of-the-box. Bet ekosistema dar nesubrendusi.
Redis Streams – jei jūsų use case’as paprastas ir jau naudojate Redis, Redis Streams gali būti pakankami. Bet jie neturi Kafka skalės ir patikimumo.
Kada Kafka nėra geriausias pasirinkimas? Jei turite mažą duomenų kiekį (tūkstančiai įvykių per dieną, ne per sekundę), jei jums reikia request-reply pattern’o, jei neturite resursų Kafka cluster’io priežiūrai. Kafka reikalauja investicijų – tiek infrastruktūros, tiek žinių.
Ateities perspektyvos ir nauji horizontai
Kafka ekosistema nuolat vystosi. KRaft (Kafka Raft) – naujas consensus mechanizmas, kuris pakeičia ZooKeeper – jau production ready. Tai supaprastina deployment’ą ir pagerina našumą.
Tiered Storage – galimybė saugoti senus duomenis pigesnėse storage sistemose (S3, Azure Blob) išlaikant juos prieinamus per Kafka API. Tai keičia žaidimo taisykles – galite saugoti terabytes duomenų be didelių kaštų.
Kafka Connect ekosistema plečiasi – jau yra šimtai ready-made connector’ių įvairioms sistemoms. Galite integruoti Kafka su beveik bet kuo be kodo rašymo.
ksqlDB – SQL interface Kafka srautams – tampa vis brandesnė. Galite rašyti SQL queries realiojo laiko duomenims:
„`sql
CREATE STREAM enriched_clicks AS
SELECT c.user_id, c.url, u.name, u.country
FROM clicks c
LEFT JOIN users u ON c.user_id = u.id;
„`
Tai demokratizuoja stream processing – nebereikia būti Java guru, kad dirbtumėte su Kafka.
Kafka tapo ne tik technologija, bet ir architektūrinis pattern’as. Event-driven architecture, event sourcing, CQRS – visi šie pattern’ai natūraliai dera su Kafka. Matome vis daugiau organizacijų, kurios stato savo duomenų infrastruktūrą aplink Kafka kaip centrinę nervų sistemą.
Ar Kafka išliks dominuojanti per ateinančius 5-10 metų? Tikėtina, taip. Ji turi stiprią bendruomenę, brandžią ekosistemą, ir svarbiausia – išsprendžia realias problemas. Bet technologijų pasaulis keičiasi greitai, tad būkite atviri naujovėms ir alternatyvoms.
Jei dar neišbandėte Kafka – dabar puikus laikas pradėti. Pradėkite su paprastu Docker setup’u, pažaiskite su producer’iais ir consumer’iais, pabandykite Kafka Streams. Teorija svarbi, bet tikras mokymasis vyksta praktikoje. Ir nepaisant to, kad kartais Kafka gali atrodyti sudėtinga, kai pagauni pagrindines koncepcijas, viskas susidėlioja į vietą. Sėkmės jūsų srautinio duomenų apdorojimo kelionėje!
