{"id":35786,"date":"2019-10-31T22:06:19","date_gmt":"2019-10-31T19:06:19","guid":{"rendered":"https:\/\/prohoster.info\/blog\/kniga-kafka-streams-v-dejstvii-prilozheniya-i-mikroservisy-dlya-raboty-v-realnom-vremeni\/"},"modified":"2019-10-31T22:06:19","modified_gmt":"2019-10-31T19:06:19","slug":"kniga-kafka-streams-v-dejstvii-prilozheniya-i-mikroservisy-dlya-raboty-v-realnom-vremeni","status":"publish","type":"post","link":"https:\/\/prohoster.info\/sv\/blog\/administrirovanie\/kniga-kafka-streams-v-dejstvii-prilozheniya-i-mikroservisy-dlya-raboty-v-realnom-vremeni","title":{"rendered":"Boken \"Kafka Streams i praktiken. Applikationer och mikrotj\u00e4nster f\u00f6r realtidsarbete\"","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/piter\/blog\/457756\/\"><img decoding=\"async\" alt=\"Boken &quot;Kafka Streams i praktiken. Applikationer och mikrotj\u00e4nster f\u00f6r realtidsarbete&quot;\" src=\"\/wp-content\/uploads\/6f8bd2b31b87b0c760c1148515893c43.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex> Hej, Habr-n\u00e4tverksmedlemmar! Den h\u00e4r boken passar alla utvecklare som vill f\u00f6rst\u00e5 str\u00f6mmande bearbetning. Att f\u00f6rst\u00e5 distribuerad programmering kommer att hj\u00e4lpa till att l\u00e4ra sig mer om Kafka och Kafka Streams. Det skulle vara bra att k\u00e4nna till sj\u00e4lva Kafka-ramverket, men det \u00e4r inte n\u00f6dv\u00e4ndigt: jag kommer att ber\u00e4tta allt du beh\u00f6ver veta. B\u00e5de erfarna Kafka-utvecklare och nyb\u00f6rjare kommer med hj\u00e4lp av den h\u00e4r boken att kunna skapa intressanta applikationer f\u00f6r str\u00f6mmande bearbetning med Kafka Streams-biblioteket. Java-utvecklare p\u00e5 medelniv\u00e5 och h\u00f6gre, som redan \u00e4r bekanta med begrepp som serialisering, kommer att l\u00e4ra sig att anv\u00e4nda sina f\u00e4rdigheter f\u00f6r att skapa Kafka Streams-applikationer. K\u00e4llkoden till boken \u00e4r skriven i Java 8 och anv\u00e4nder i stor utstr\u00e4ckning syntaxen f\u00f6r lambda-uttryck i Java 8, s\u00e5 att kunna arbeta med lambda-funktioner (\u00e4ven om det \u00e4r p\u00e5 ett annat programmeringsspr\u00e5k) kommer att vara till nytta.<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h3>Utdrag. 5.3. Agregering och f\u00f6nsteroperationer<\/h3>\n<p>\nI den h\u00e4r sektionen g\u00e5r vi vidare med att utforska de mest lovande delarna av Kafka Streams. Hittills har vi unders\u00f6kt f\u00f6ljande aspekter av Kafka Streams:<\/p>\n<ul>\n<li>skapa en behandlings-topologi;<\/li>\n<li>anv\u00e4nda tillst\u00e5nd i str\u00f6mmande applikationer;<\/li>\n<li>utf\u00f6ra datastream-anslutningar;<\/li>\n<li>skillnaderna mellan h\u00e4ndelsestr\u00f6mmar (KStream) och uppdateringsstr\u00f6mmar (KTable).<\/li>\n<\/ul>\n<p>\nI de f\u00f6ljande exemplen kommer vi att s\u00e4tta ihop alla dessa element. Dessutom kommer du att bekanta dig med f\u00f6nsteroperationer \u2013 en annan fantastisk m\u00f6jlighet f\u00f6r str\u00f6mmande applikationer. V\u00e5rt f\u00f6rsta exempel kommer att handla om enkel aggregering.<\/p>\n<h3>5.3.1. Aggerering av aktief\u00f6rs\u00e4ljning efter branscher<\/h3>\n<p>\nAggreggering och gruppering \u00e4r livsn\u00f6dv\u00e4ndiga verktyg n\u00e4r man arbetar med str\u00f6mmade data. Att unders\u00f6ka individuella poster i takt med att de kommer in visar sig ofta vara otillr\u00e4ckligt. F\u00f6r att extrahera mer information fr\u00e5n data beh\u00f6ver de grupperas och kombineras.<\/p>\n<p>I det h\u00e4r exemplet kommer du att f\u00e5 prova en inrikesdagshandlares kostym, som beh\u00f6ver f\u00f6lja aktief\u00f6rs\u00e4ljning f\u00f6r f\u00f6retag i flera branscher. Specifikt \u00e4r du intresserad av fem f\u00f6retag med de h\u00f6gsta aktief\u00f6rs\u00e4ljningarna inom varje bransch.<\/p>\n<p>F\u00f6r att g\u00f6ra denna typ av aggregering kommer flera steg att beh\u00f6va tas f\u00f6r att \u00f6vers\u00e4tta data till \u00f6nskat format (om man talar i allm\u00e4nna termer).<\/p>\n<ol>\n<li>Skapa en k\u00e4lla baserad p\u00e5 \u00e4mnet som publicerar r\u00e5 information om aktiehandel. Vi m\u00e5ste avbilda ett objekt av typen StockTransaction till ett objekt av typen ShareVolume. Det handlar om att objektet StockTransaction inneh\u00e5ller metadata om f\u00f6rs\u00e4ljning, och vi beh\u00f6ver endast data om antalet s\u00e5lda aktier.<\/li>\n<li>Gruppera data i ShareVolume efter aktiesymboler. Efter gruppering efter symboler kan dessa data reduceras till mellanliggande summor av aktief\u00f6rs\u00e4ljningsvolymer. Det \u00e4r v\u00e4rt att notera att metoden KStream.groupBy returnerar en instans av typen KGroupedStream. En instans av KTable kan erh\u00e5llas genom att anropa metoden KGroupedStream.reduce.<\/li>\n<\/ol>\n<p><\/p>\n<blockquote><p><b>Vad \u00e4r gr\u00e4nssnittet KGroupedStream?<\/b><\/p>\n<p>Metoderna KStream.groupBy och KStream.groupByKey returnerar en instans av KGroupedStream. KGroupedStream \u00e4r en mellanliggande representation av en str\u00f6m av h\u00e4ndelser efter gruppering av nycklar. Den \u00e4r inte avsedd f\u00f6r direkt arbete. Ist\u00e4llet anv\u00e4nds KGroupedStream f\u00f6r aggregationsoperationer vars resultat alltid \u00e4r en KTable. Eftersom resultatet av aggregationsoperationer \u00e4r en KTable och dessa anv\u00e4nder ett tillst\u00e5ndslager, kan det h\u00e4nda att inte alla uppdateringar i resultatet skickas vidare i kedjan.<\/p>\n<p>Metoden KTable.groupBy returnerar en motsvarande KGroupedTable \u2014 en mellanliggande representation av en str\u00f6m av uppdateringar omgrupperade efter nyckel.<\/p><\/blockquote>\n<p>\nL\u00e5t oss ta en kort paus och titta p\u00e5 fig. 5.9, som visar vad vi har \u00e5stadkommit. Denna topologi b\u00f6r redan vara bekant f\u00f6r dig.<\/p>\n<p><img decoding=\"async\" alt=\"Boken &quot;Kafka Streams i praktiken. Applikationer och mikrotj\u00e4nster f\u00f6r realtidsarbete&quot;\" src=\"\/wp-content\/uploads\/9fd61317cde376362adcaeec72908919.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nL\u00e5t oss nu titta p\u00e5 koden f\u00f6r denna topologi (den finns i filen src\/main\/java\/bbejeck\/chapter_5\/AggregationsAndReducingExample.java) (listning 5.2).<\/p>\n<p><img decoding=\"async\" alt=\"Boken &quot;Kafka Streams i praktiken. Applikationer och mikrotj\u00e4nster f\u00f6r realtidsarbete&quot;\" src=\"\/wp-content\/uploads\/f937287e448295fbd467c283ceca316a.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nKoden som presenteras \u00e4r kompakt och utf\u00f6r en stor m\u00e4ngd \u00e5tg\u00e4rder p\u00e5 n\u00e5gra f\u00e5 rader. I den f\u00f6rsta parametern av metoden builder.stream kan du se n\u00e5got nytt: v\u00e4rdet av den uppr\u00e4knade typen AutoOffsetReset.EARLIEST (det finns ocks\u00e5 LATEST), som st\u00e4lls in med hj\u00e4lp av metoden Consumed.withOffsetResetPolicy. Med denna uppr\u00e4knade typ kan du ange en strategi f\u00f6r offset\u00e5terst\u00e4llning f\u00f6r varje KStream eller KTable, vilket har h\u00f6gre prioritet \u00e4n parametern f\u00f6r offset\u00e5terst\u00e4llning i konfigurationen.<\/p>\n<blockquote><p><b>GroupByKey och GroupBy<\/b><\/p>\n<p>I gr\u00e4nssnittet KStream finns det tv\u00e5 metoder f\u00f6r att gruppera poster: GroupByKey och GroupBy. B\u00e5da returnerar en KGroupedTable, s\u00e5 du kanske undrar: vad \u00e4r skillnaden mellan dem och n\u00e4r ska man anv\u00e4nda vilken?<\/p>\n<p>Metoden GroupByKey anv\u00e4nds n\u00e4r nycklarna i KStream redan \u00e4r icke-tomma. Viktigt \u00e4r att flaggan \"kr\u00e4ver ompartitionering\" aldrig har satt.<\/p>\n<p>Metoden GroupBy f\u00f6resl\u00e5r att du har \u00e4ndrat nycklarna f\u00f6r grupperingen, s\u00e5 flaggan f\u00f6r ompartitionering \u00e4r satt till true. Genomf\u00f6rande efter metoden GroupBy avkopplingar, aggregering och liknande kommer att leda till automatisk ompartitionering.<br \/>\nSammanfattning: anv\u00e4nd alltid GroupByKey vid minsta m\u00f6jlighet, snarare \u00e4n GroupBy.<\/p><\/blockquote>\n<p>\nVad metoderna mapValues och groupBy g\u00f6r \u00e4r sj\u00e4lvklart, s\u00e5 l\u00e5t oss titta p\u00e5 metoden sum() (den kan hittas i filen src\/main\/java\/bbejeck\/model\/ShareVolume.java) (listing 5.3).<\/p>\n<p><img decoding=\"async\" alt=\"Boken &quot;Kafka Streams i praktiken. Applikationer och mikrotj\u00e4nster f\u00f6r realtidsarbete&quot;\" src=\"\/wp-content\/uploads\/8e9a6f873594f9b5fef9a96c42353a61.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nMetoden ShareVolume.sum returnerar det mellanliggande summan av aktief\u00f6rs\u00e4ljningsvolymen, och resultatet av hela ber\u00e4kningskedjan representerar ett objekt KTable. Nu f\u00f6rst\u00e5r du vilken roll KTable spelar. N\u00e4r objekt ShareVolume kommer in, sparas den senaste aktuella uppdateringen i den motsvarande KTable-objektet. Det \u00e4r viktigt att komma ih\u00e5g att alla uppdateringar \u00e5terspeglas i f\u00f6reg\u00e5ende shareVolumeKTable, men inte alla skickas vidare.<\/p>\n<p>Vidare anv\u00e4nder vi denna KTable f\u00f6r att utf\u00f6ra aggregering (baserat p\u00e5 antalet s\u00e5lda aktier) f\u00f6r att f\u00e5 fram fem f\u00f6retag med st\u00f6rst f\u00f6rs\u00e4ljningsvolymer av aktier inom varje bransch. V\u00e5ra \u00e5tg\u00e4rder kommer att vara liknande dem som vid den f\u00f6rsta aggregeringen.<\/p>\n<ol>\n<li>Utf\u00f6r ytterligare en groupBy-operation f\u00f6r att gruppera individuella ShareVolume-objekt efter branscher.<\/li>\n<li>B\u00f6rja summera ShareVolume-objekten. Denna g\u00e5ng representerar aggregationsobjektet en prioritetsk\u00f6 med fast storlek. I en s\u00e5dan k\u00f6 med fast storlek lagras endast fem f\u00f6retag med de st\u00f6rsta m\u00e4ngderna s\u00e5lda aktier.<\/li>\n<li>Konvertera k\u00f6erna fr\u00e5n f\u00f6reg\u00e5ende punkt till ett str\u00e4ngv\u00e4rde och returnera de fem mest s\u00e5lda aktierna per bransch.<\/li>\n<li>Skriv resultaten i str\u00e4ngformat till \u00e4mnet.<\/li>\n<\/ol>\n<p>\nFigur 5.10 visar topologin f\u00f6r datar\u00f6relsen. Som du kan se, \u00e4r den andra bearbetningscykeln ganska enkel.<\/p>\n<p><img decoding=\"async\" alt=\"Boken &quot;Kafka Streams i praktiken. Applikationer och mikrotj\u00e4nster f\u00f6r realtidsarbete&quot;\" src=\"\/wp-content\/uploads\/dabd1507eee267038edb7f8d76d8d8ae.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nNu, efter att tydligt ha f\u00f6rst\u00e5tt strukturen av denna andra bearbetningscykel, kan du g\u00e5 till dess k\u00e4llkod (du hittar den i filen src\/main\/java\/bbejeck\/chapter_5\/AggregationsAndReducingExample.java) (listing 5.4).<\/p>\n<p>I den h\u00e4r initialiseringen finns en variabel fixedQueue. Det \u00e4r ett anpassat objekt - en adapter f\u00f6r java.util.TreeSet, som anv\u00e4nds f\u00f6r att sp\u00e5ra de N st\u00f6rsta resultaten i fallande ordning av s\u00e5lda aktier.<\/p>\n<p><img decoding=\"async\" alt=\"Boken &quot;Kafka Streams i praktiken. Applikationer och mikrotj\u00e4nster f\u00f6r realtidsarbete&quot;\" src=\"\/wp-content\/uploads\/488b072b0d91b81c925ca72291e69e48.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nDu har redan st\u00f6tt p\u00e5 anropen groupBy och mapValues, s\u00e5 vi kommer inte att stanna vid dem (vi anropar metoden KTable.toStream, eftersom metoden KTable.print anses vara f\u00f6r\u00e5ldrad). Men du har \u00e4nnu inte sett KTable-versionen av metoden aggregate(), s\u00e5 vi kommer att ta lite tid f\u00f6r att diskutera den.<\/p>\n<p>Som du kommer ih\u00e5g, k\u00e4nnetecknas KTable av att poster med samma nycklar betraktas som uppdateringar. KTable ers\u00e4tter den gamla posten med den nya. Aggering sker p\u00e5 liknande s\u00e4tt: senaste poster med samma nyckel aggeras. N\u00e4r en post kommer in l\u00e4ggs den till en instans av klassen FixedSizePriorityQueue med hj\u00e4lp av en summerare (den andra parametern i anropet till metoden aggregate), men om det redan finns en annan post med samma nyckel, tas den gamla posten bort med hj\u00e4lp av en subtraherar (den tredje parametern i anropet till metoden aggregate).<\/p>\n<p>Detta betyder att v\u00e5r aggregator, FixedSizePriorityQueue, inte aggerar alla v\u00e4rden med samma nyckel, utan lagrar det glidande medelv\u00e4rdet av de N mest s\u00e5lda aktietyperna. I varje inkommande post finns det totala antalet aktier som s\u00e5lts hittills. KTable ger dig information om vilka f\u00f6retags aktier som s\u00e4ljer mest just nu; glidande aggering av varje uppdatering beh\u00f6vs inte.<\/p>\n<p>Vi har l\u00e4rt oss att g\u00f6ra tv\u00e5 viktiga saker:<\/p>\n<ul>\n<li>gruppera v\u00e4rden i KTable efter en gemensam nyckel;<\/li>\n<li>utf\u00f6ra nyttiga operationer p\u00e5 dessa grupperade v\u00e4rden, s\u00e5som reduktion och aggering.<\/li>\n<\/ul>\n<p>\nF\u00f6rm\u00e5gan att utf\u00f6ra dessa operationer \u00e4r viktig f\u00f6r att f\u00f6rst\u00e5 betydelsen av de data som r\u00f6r sig genom Kafka Streams-applikationen och att ta reda p\u00e5 vilken information de b\u00e4r.<\/p>\n<p>Vi har ocks\u00e5 sammanf\u00f6rt n\u00e5gra av de centrala begreppen som diskuterats tidigare i denna bok. I kapitel 4 ber\u00e4ttade vi hur viktigt det \u00e4r f\u00f6r en streamingapplikation att ha ett motst\u00e5ndskraftigt, lokalt tillst\u00e5nd. Det f\u00f6rsta exemplet fr\u00e5n detta kapitel visade varf\u00f6r lokalt tillst\u00e5nd \u00e4r s\u00e5 viktigt \u2013 det m\u00f6jligg\u00f6r sp\u00e5rning av vilken information du redan har sett. Lokalt tilltr\u00e4de eliminerar n\u00e4tverksf\u00f6rdr\u00f6jningar, vilket g\u00f6r att applikationen blir mer presterande och felresistent.<\/p>\n<p>Vid utf\u00f6rande av n\u00e5gon form av aggregerings- eller sammanfogning m\u00e5ste namnet p\u00e5 tillst\u00e5ndslagringen anges. Aggregerings- och sammanfogningsoperationer returnerar en instans av KTable, och KTable anv\u00e4nder tillst\u00e5ndslagringen f\u00f6r att ers\u00e4tta gamla resultat med nya. Som du har sett skickas l\u00e5ngt ifr\u00e5n alla uppdateringar vidare i kedjan, och detta \u00e4r viktigt eftersom aggregeringsoperationer \u00e4r avsedda f\u00f6r att skaffa slutgiltig information. Om du inte anv\u00e4nder lokalt tillst\u00e5nd kommer KTable att skicka vidare alla aggregerings- och sammanfogningsresultat.<\/p>\n<p>N\u00e4st ska vi titta p\u00e5 utf\u00f6randet av operationer som aggregering inom angiven tidsram \u2013 de s\u00e5 kallade f\u00f6nsteroperationerna (windowing operations).<\/p>\n<h3>5.3.2. F\u00f6nsteroperationer<\/h3>\n<p>\nI f\u00f6reg\u00e5ende avsnitt bekantade vi oss med \"glidande\" sammanfogning och aggregering. Applikationen genomf\u00f6rde en kontinuerlig sammanfogning av aktief\u00f6rs\u00e4ljningsvolymen f\u00f6ljt av aggregering av de fem mest s\u00e5lda aktierna p\u00e5 b\u00f6rsen.<\/p>\n<p>Ibland \u00e4r s\u00e5dana kontinuerliga aggregeringar och sammanfogningar av resultat n\u00f6dv\u00e4ndiga. Och ibland m\u00e5ste operationer utf\u00f6ras endast \u00f6ver en angiven tidsperiod. Till exempel ber\u00e4kna hur m\u00e5nga aktieaff\u00e4rer som gjordes med en specifik f\u00f6retagets aktie under de senaste 10 minuterna. Eller hur m\u00e5nga anv\u00e4ndare som klickade p\u00e5 den nya reklam bannern under de senaste 15 minuterna. Applikationen kan genomf\u00f6ra s\u00e5dana operationer flera g\u00e5nger, men med resultat som endast g\u00e4ller f\u00f6r angivna tidsperioder (tidsf\u00f6nster).<\/p>\n<h3>R\u00e4kna aktietransaktioner per k\u00f6pare<\/h3>\n<p>\nI n\u00e4sta exempel kommer vi att sp\u00e5ra aktietransaktioner f\u00f6r flera handlare \u2013 antingen stora organisationer eller smarta finansierare som agerar ensamma.<\/p>\n<p>Det finns tv\u00e5 m\u00f6jliga sk\u00e4l f\u00f6r s\u00e5dan sp\u00e5rning. Det ena \u00e4r behovet av att veta vad marknadsledare k\u00f6per\/s\u00e4ljer. Om dessa stora akt\u00f6rer och erfarna investerare ser m\u00f6jligheter f\u00f6r sig sj\u00e4lva, \u00e4r det v\u00e4rt att f\u00f6lja deras strategi. Den andra anledningen \u00e4r att uppt\u00e4cka tecken p\u00e5 olagliga aff\u00e4rer med anv\u00e4ndning av insiderinformation. F\u00f6r detta beh\u00f6ver du analysera korrelationen mellan stora f\u00f6rs\u00e4ljnings\u00f6kningar och viktiga pressmeddelanden.<\/p>\n<p>Denna sp\u00e5rning best\u00e5r av f\u00f6ljande steg:<\/p>\n<ul>\n<li>skapa en str\u00f6m f\u00f6r att l\u00e4sa fr\u00e5n \u00e4mnet stock-transactions;<\/li>\n<li>gruppera inkommande poster efter k\u00f6parens identifierare och aktiens b\u00f6rssymbol. Anrop av metoden groupBy returnerar en instans av klassen KGroupedStream;<\/li>\n<li>\u00e5terv\u00e4nda med metoden KGroupedStream.windowedBy en datastream begr\u00e4nsad av ett tidsf\u00f6nster, vilket g\u00f6r det m\u00f6jligt att utf\u00f6ra f\u00f6nsteraggregat. Beroende p\u00e5 f\u00f6nstertypen returneras antingen TimeWindowedKStream eller SessionWindowedKStream;<\/li>\n<li>r\u00e4kna transaktioner f\u00f6r aggregationsoperationen. Det f\u00f6nsterdatafl\u00f6de som definieras avg\u00f6r om en specifik post r\u00e4knas med;<\/li>\n<li>skriva resultaten till \u00e4mnet eller skriva ut dem till konsolen under utvecklingen.<\/li>\n<\/ul>\n<p>\nTopologin f\u00f6r denna applikation \u00e4r enkel, men en visuell representation kan vara till hj\u00e4lp. L\u00e5t oss titta p\u00e5 fig. 5.11.<\/p>\n<p>D\u00e4refter kommer vi att titta p\u00e5 funktionerna hos f\u00f6nsteroperationer och motsvarande kod.<\/p>\n<p><img decoding=\"async\" alt=\"Boken &quot;Kafka Streams i praktiken. Applikationer och mikrotj\u00e4nster f\u00f6r realtidsarbete&quot;\" src=\"\/wp-content\/uploads\/67d9d8d8acb1370a7c7fe5cd9a8b6aa7.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<h3>Typer av f\u00f6nster<\/h3>\n<p>\nI Kafka Streams finns det tre typer av f\u00f6nster:<\/p>\n<ul>\n<li>sessionsf\u00f6nster;<\/li>\n<li>tumbling f\u00f6nster;<\/li>\n<li>glidande\/p\u00e5hoppande f\u00f6nster.<\/li>\n<\/ul>\n<p>\nVilket du v\u00e4ljer beror p\u00e5 aff\u00e4rskrav. Tumbling och hoppande f\u00f6nster begr\u00e4nsas av tid, medan sessionsf\u00f6nstrens begr\u00e4nsningar \u00e4r kopplade till anv\u00e4ndarnas handlingar \u2014 l\u00e4ngden p\u00e5 sessionen(-erna) best\u00e4ms enbart av hur aktivt anv\u00e4ndaren beter sig. Huvudsaken \u00e4r att komma ih\u00e5g att alla typer av f\u00f6nster baseras p\u00e5 tidsst\u00e4mplar f\u00f6r posterna, och inte p\u00e5 systemtiden.<\/p>\n<p>D\u00e4refter implementerar vi v\u00e5r topologi med varje typ av f\u00f6nster. Fullst\u00e4ndig kod kommer att ges endast i det f\u00f6rsta exemplet, f\u00f6r de andra typerna av f\u00f6nster kommer inget att f\u00f6r\u00e4ndras f\u00f6rutom typen av f\u00f6nsteroperation.<\/p>\n<h3>Sessionsf\u00f6nster<\/h3>\n<p>\nSessionsf\u00f6nster skiljer sig starkt fr\u00e5n alla andra typer av f\u00f6nster. De begr\u00e4nsas inte s\u00e5 mycket av tid som av anv\u00e4ndarens aktivitet (eller aktiviteten hos den enhet som du vill sp\u00e5ra). Sessionsf\u00f6nster avgr\u00e4nsas av perioder av inaktivitet.<\/p>\n<p>Figur 5.12 illustrerar begreppet sessionsf\u00f6nster. En mindre session kommer att glida samman med sessionen till v\u00e4nster om den. Och sessionen till h\u00f6ger kommer att vara separat, eftersom den f\u00f6ljer efter en l\u00e5ng period av inaktivitet. Sessionsf\u00f6nster baseras p\u00e5 anv\u00e4ndaraktiviteter, men anv\u00e4nder tidsst\u00e4mpel-taggar fr\u00e5n poster f\u00f6r att avg\u00f6ra vilken session posten tillh\u00f6r.<\/p>\n<p><img decoding=\"async\" alt=\"Boken &quot;Kafka Streams i praktiken. Applikationer och mikrotj\u00e4nster f\u00f6r realtidsarbete&quot;\" src=\"\/wp-content\/uploads\/d39a5db7af7d6aa2194802622b2b47fd.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<h3>Anv\u00e4ndning av sessionsf\u00f6nster f\u00f6r att sp\u00e5ra b\u00f6rstransaktioner.<\/h3>\n<p>\nVi anv\u00e4nder sessionsf\u00f6nster f\u00f6r att f\u00e5nga information om b\u00f6rstransaktioner. Implementeringen av sessionsf\u00f6nster visas i listing 5.5 (som kan hittas i filen src\/main\/java\/bbejeck\/chapter_5\/CountingWindowingAndKTableJoinExample.java).<\/p>\n<p><img decoding=\"async\" alt=\"Boken &quot;Kafka Streams i praktiken. Applikationer och mikrotj\u00e4nster f\u00f6r realtidsarbete&quot;\" src=\"\/wp-content\/uploads\/2dcbd9a36baec0e746aad165121451b3.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nDe flesta operationerna i denna topologi har du redan st\u00f6tt p\u00e5, s\u00e5 det finns ingen anledning att g\u00e5 igenom dem igen h\u00e4r. Men h\u00e4r finns ocks\u00e5 n\u00e5gra nya element som vi nu kommer att diskutera.<\/p>\n<p>Vid varje operation groupBy utf\u00f6rs vanligtvis n\u00e5gon form av aggregering (aggregering, sammanst\u00e4llning eller r\u00e4kning). Antingen kan du utf\u00f6ra en ackumulerande aggregering med l\u00f6pande totalsummor, eller ett f\u00f6nsteraggregat d\u00e4r poster beaktas inom ett givet tidsf\u00f6nster.<\/p>\n<p>Koden fr\u00e5n listing 5.5 r\u00e4knar antalet transaktioner inom sessionsf\u00f6nster. I figur 5.13 analyseras dessa \u00e5tg\u00e4rder steg f\u00f6r steg.<\/p>\n<p>Med anropet windowedBy(SessionWindows.with(twentySeconds).until(fifteenMinutes)) skapade vi ett sessionsf\u00f6nster med en inaktivitetsperiod p\u00e5 20 sekunder och en bevarandeperiod p\u00e5 15 minuter. Inaktivitetsperioden p\u00e5 20 sekunder inneb\u00e4r att applikationen kommer att inkludera varje post som kommer in inom 20 sekunder efter slutet eller b\u00f6rjan av den aktuella sessionen i den nuvarande (aktiva) sessionen.<\/p>\n<p><img decoding=\"async\" alt=\"Boken &quot;Kafka Streams i praktiken. Applikationer och mikrotj\u00e4nster f\u00f6r realtidsarbete&quot;\" src=\"\/wp-content\/uploads\/9bd47b04698086872fd135b4c67eb938.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nH\u00e4r anger vi vilken aggregationsoperation som ska utf\u00f6ras i sessionsf\u00f6nstret \u2013 i detta fall count. Om den inkommande posten g\u00e5r utanf\u00f6r inaktivitetens intervall (p\u00e5 valfri sida av tidsst\u00e4mpeln), skapar applikationen en ny session. Bevarandeintervallet inneb\u00e4r att sessionen h\u00e5lls aktiv under en viss tid och till\u00e5ter f\u00f6rdr\u00f6jda data som g\u00e5r utanf\u00f6r inaktivitetsperioden f\u00f6r sessionen men som fortfarande kan kopplas. Dessutom motsvarar b\u00f6rjan och slutet p\u00e5 den nya sessionen, som skapats genom sammanslagning, den tidigaste och den senaste tidsst\u00e4mpeln.<\/p>\n<p>L\u00e5t oss titta p\u00e5 n\u00e5gra poster fr\u00e5n count-metoden f\u00f6r att se hur sessioner fungerar (tabell 5.1).<\/p>\n<p><img decoding=\"async\" alt=\"Boken &quot;Kafka Streams i praktiken. Applikationer och mikrotj\u00e4nster f\u00f6r realtidsarbete&quot;\" src=\"\/wp-content\/uploads\/ec04aae466d88c2d2349474069c8d541.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nN\u00e4r poster kommer in, letar vi efter redan existerande sessioner med samma nyckel, d\u00e4r slutetiden \u00e4r tidigare \u00e4n den aktuella tidsst\u00e4mpeln \u2013 inaktivitetsintervallet, och starttiden \u00e4r senare \u00e4n den aktuella tidsst\u00e4mpeln + inaktivitetsintervallet. Med detta i \u00e5tanke sl\u00e5s fyra poster fr\u00e5n tabell 5.1 samman till en enda session p\u00e5 f\u00f6ljande s\u00e4tt.<\/p>\n<p>1. F\u00f6rst kommer post 1, s\u00e5 starttiden \u00e4r lika med sluttiden och \u00e4r 00:00:00.<\/p>\n<p>2. D\u00e4refter kommer post 2, och vi letar efter sessioner som slutar senast 23:59:55 och b\u00f6rjar senast 00:00:35. Vi hittar post 1 och sl\u00e5r samman sessionerna 1 och 2. Vi tar starttiden f\u00f6r session 1 (den tidigare) och sluttiden f\u00f6r session 2 (den senare), s\u00e5 v\u00e5r nya session b\u00f6rjar kl. 00:00:00 och slutar kl. 00:00:15.<\/p>\n<p>3. Post 3 kommer in, vi letar efter sessioner mellan 00:00:30 och 00:01:10 och hittar inga. Vi l\u00e4gger till den andra sessionen f\u00f6r nyckeln 123-345-654,FFBE, som b\u00f6rjar och slutar kl. 00:00:50.<\/p>\n<p>4. Post 4 kommer in, och vi letar efter sessioner mellan 23:59:45 och 00:00:25. Denna g\u00e5ng hittar vi b\u00e5da sessionerna \u2013 1 och 2. Alla tre sessionerna sl\u00e5s samman i en, med starttid 00:00:00 och sluttid 00:00:15.<\/p>\n<p>Fr\u00e5n det som har beskrivits i detta avsnitt \u00e4r det viktigt att komma ih\u00e5g f\u00f6ljande kriterier:<\/p>\n<ul>\n<li>sessioner \u00e4r inte f\u00f6nster av fast storlek. Sessionens l\u00e4ngd best\u00e4ms av aktiviteten inom det angivna tidsintervallet;<\/li>\n<li>tidsst\u00e4mplarna i data avg\u00f6r om en h\u00e4ndelse faller inom en befintlig session eller i inaktivitetsintervallet.<\/li>\n<\/ul>\n<p>\nD\u00e4refter kommer vi att diskutera den n\u00e4sta typen av f\u00f6nster \u2013 \"rullande\" f\u00f6nster.<\/p>\n<h3>\"Rullande\" f\u00f6nster<\/h3>\n<p>\n\u00abKullande\u00bb (tumbling) f\u00f6nster f\u00e5ngar h\u00e4ndelser som intr\u00e4ffar under en viss tidsperiod. T\u00e4nk dig att du beh\u00f6ver f\u00e5nga alla aktietransaktioner f\u00f6r ett f\u00f6retag var 20:e sekund, s\u00e5 att du samlar alla h\u00e4ndelser under denna tidsperiod. I slutet av den 20-sekundersintervallet \"kullar\" f\u00f6nstret och g\u00e5r vidare till det nya 20-sekunders observationsintervallet. Figur 5.14 illustrerar denna situation.<\/p>\n<p><img decoding=\"async\" alt=\"Boken &quot;Kafka Streams i praktiken. Applikationer och mikrotj\u00e4nster f\u00f6r realtidsarbete&quot;\" src=\"\/wp-content\/uploads\/e90e560d9ddda5e2e524b7c387ad9874.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nSom du kan se inkluderar alla h\u00e4ndelser som kommit in under de senaste 20 sekunderna i f\u00f6nstret. I slutet av denna tidsperiod skapas ett nytt f\u00f6nster.<\/p>\n<p>I listing 5.6 visas koden som demonstrerar anv\u00e4ndningen av \u00abkullande\u00bb f\u00f6nster f\u00f6r att f\u00e5nga aktietransaktioner var 20:e sekund (den kan hittas i filen src\/main\/java\/bbejeck\/chapter_5\/CountingWindowingAndKtableJoinExample.java).<\/p>\n<p><img decoding=\"async\" alt=\"Boken &quot;Kafka Streams i praktiken. Applikationer och mikrotj\u00e4nster f\u00f6r realtidsarbete&quot;\" src=\"\/wp-content\/uploads\/e055bb1b288c7d500b64372fe3fbf064.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nTack vare denna lilla f\u00f6r\u00e4ndring i metoden TimeWindows.of kan ett \u00abkullande\u00bb f\u00f6nster anv\u00e4ndas. I det h\u00e4r exemplet finns det ingen metodanrop till until(), vilket inneb\u00e4r att standardbevarandet av intervall, som \u00e4r 24 timmar, kommer att anv\u00e4ndas.<\/p>\n<p>Slutligen \u00e4r det dags att g\u00e5 till den sista av f\u00f6nsteralternativen - \u00abhoppar\u00bb (hopping) f\u00f6nster.<\/p>\n<h3>Glidande (\u00abhoppar\u00bb) f\u00f6nster<\/h3>\n<p>\nGlidande\/\u00abhoppar\u00bb (sliding\/hopping) f\u00f6nster liknar \u00abkullande\u00bb, men med en liten skillnad. Glidande f\u00f6nster v\u00e4ntar inte tills tidsintervallet \u00e4r slut innan ett nytt f\u00f6nster skapas f\u00f6r att bearbeta nyligen intr\u00e4ffade h\u00e4ndelser. De initierar nya ber\u00e4kningar efter ett v\u00e4ntetidsintervall som \u00e4r kortare \u00e4n f\u00f6nstrets varaktighet.<\/p>\n<p>F\u00f6r att illustrera skillnaderna mellan \u00abkullande\u00bb och \u00abhoppar\u00bb f\u00f6nster, \u00e5terv\u00e4nder vi till exemplet med aktietransaktionsr\u00e4kning. V\u00e5rt m\u00e5l \u00e4r fortfarande att r\u00e4kna antalet transaktioner, men vi vill inte v\u00e4nta hela tidsintervallet innan vi uppdaterar r\u00e4knaren. Ist\u00e4llet kommer vi att uppdatera r\u00e4knaren genom kortare tidsperioder. Till exempel, vi kommer fortfarande att r\u00e4kna antalet transaktioner var 20:e sekund, men uppdatera r\u00e4knaren var 5:e sekund, som visas i fig. 5.15. P\u00e5 s\u00e5 s\u00e4tt f\u00e5r vi tre resultatf\u00f6nster med \u00f6verlappande data.<\/p>\n<p><img decoding=\"async\" alt=\"Boken &quot;Kafka Streams i praktiken. Applikationer och mikrotj\u00e4nster f\u00f6r realtidsarbete&quot;\" src=\"\/wp-content\/uploads\/415c8cd9f2b60d453a1a01c3bc99331f.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nI listing 5.7 visas koden f\u00f6r att st\u00e4lla in glidande f\u00f6nster (den kan hittas i filen src\/main\/java\/bbejeck\/chapter_5\/CountingWindowingAndKtableJoinExample.java).<\/p>\n<p><img decoding=\"async\" alt=\"Boken &quot;Kafka Streams i praktiken. Applikationer och mikrotj\u00e4nster f\u00f6r realtidsarbete&quot;\" src=\"\/wp-content\/uploads\/ab2d1a64380d256d3fb084e16597417c.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nDet \"rullande\" f\u00f6nstret kan omvandlas till ett \"hoppa\" genom att l\u00e4gga till anropet till metoden advanceBy(). I det angivna exemplet \u00e4r intervallet f\u00f6r lagring 15 minuter.<\/p>\n<p>I detta avsnitt har du sett hur man begr\u00e4nsar aggregatresultat med tidsf\u00f6nster. I synnerhet vill jag att du ska komma ih\u00e5g f\u00f6ljande tre saker fr\u00e5n detta avsnitt:<\/p>\n<ul>\n<li>storleken p\u00e5 sessionf\u00f6nster begr\u00e4nsas inte av tidsspannet, utan av anv\u00e4ndarnas aktivitet;<\/li>\n<li>de \"rullande\" f\u00f6nstren ger en \u00f6versikt \u00f6ver h\u00e4ndelser under en given tidsperiod;<\/li>\n<li>l\u00e4ngden p\u00e5 \"hoppa\" f\u00f6nster \u00e4r fast, men de uppdateras ofta och kan inneh\u00e5lla \u00f6verlappande poster i alla f\u00f6nster.<\/li>\n<\/ul>\n<p>\nVi kommer nu att l\u00e4ra oss hur man omvandlar KTable tillbaka till KStream f\u00f6r anslutning.<\/p>\n<h3>5.3.3. Anslutning av KStream- och KTable-objekt<\/h3>\n<p>\nI kapitel 4 diskuterade vi anslutningen av tv\u00e5 KStream-objekt. Nu ska vi l\u00e4ra oss att koppla KTable och KStream. Detta kan vara n\u00f6dv\u00e4ndigt av f\u00f6ljande enkla anledning. KStream \u00e4r en str\u00f6m av poster, medan KTable \u00e4r en str\u00f6m av uppdateringar av poster, men ibland kan det vara n\u00f6dv\u00e4ndigt att l\u00e4gga till ytterligare kontext till str\u00f6mmen av poster med hj\u00e4lp av uppdateringar fr\u00e5n KTable.<\/p>\n<p>L\u00e5t oss ta data om antalet b\u00f6rshandler och koppla dem till b\u00f6rsnyheter inom de relevanta branscherna. H\u00e4r \u00e4r vad vi beh\u00f6ver g\u00f6ra f\u00f6r att uppn\u00e5 detta med den redan existerande koden.<\/p>\n<ol>\n<li>Omvandla KTable-objektet med data om antal b\u00f6rshandler till KStream med efterf\u00f6ljande byte av nyckeln till den som representerar branschen som motsvarar denna aktiesymbol.<\/li>\n<li>Skapa ett KTable-objekt som l\u00e4ser data fr\u00e5n \u00e4mnet med b\u00f6rsnyheter. Denna nya KTable kommer att kategoriseras efter branscher.<\/li>\n<li>Koppla nyhetsuppdateringar med information om antalet b\u00f6rshandler efter branscher.<\/li>\n<\/ol>\n<p>\nNu ska vi se hur vi genomf\u00f6r den h\u00e4r handlingsplanen.<\/p>\n<h3>Omvandling av KTable till KStream<\/h3>\n<p>\nF\u00f6r att omvandla KTable till KStream beh\u00f6ver man g\u00f6ra f\u00f6ljande.<\/p>\n<ol>\n<li>Anropa metoden KTable.toStream().<\/li>\n<li>Genom att anropa metoden KStream.map, ers\u00e4tt nyckeln med namnet p\u00e5 branschen, och extrahera sedan objektet TransactionSummary fr\u00e5n instansen av Windowed.<\/li>\n<\/ol>\n<p>\nVi kommer att kedja dessa operationer p\u00e5 f\u00f6ljande s\u00e4tt (koden finns i filen src\/main\/java\/bbejeck\/chapter_5\/CountingWindowingAndKtableJoinExample.java) (listning 5.8).<\/p>\n<p><img decoding=\"async\" alt=\"Boken &quot;Kafka Streams i praktiken. Applikationer och mikrotj\u00e4nster f\u00f6r realtidsarbete&quot;\" src=\"\/wp-content\/uploads\/0d43c2650f6e66e2816ed383da3a29c2.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nEftersom vi utf\u00f6r operationen KStream.map kommer om-sektioneringen av den returnerade KStream-instansen att g\u00f6ras automatiskt n\u00e4r den anv\u00e4nds i en sammanfogning.<\/p>\n<p>Vi har slutf\u00f6rt konverteringsprocessen, nu beh\u00f6ver vi skapa ett KTable-objekt f\u00f6r att l\u00e4sa b\u00f6rsnyheter.<\/p>\n<h3>Skapande av KTable f\u00f6r b\u00f6rsnyheter<\/h3>\n<p>\nLyckligtvis r\u00e4cker det med en rad kod f\u00f6r att skapa KTable-objektet (denna kod finns i filen src\/main\/java\/bbejeck\/chapter_5\/CountingWindowingAndKtableJoinExample.java) (listing 5.9).<\/p>\n<p><img decoding=\"async\" alt=\"Boken &quot;Kafka Streams i praktiken. Applikationer och mikrotj\u00e4nster f\u00f6r realtidsarbete&quot;\" src=\"\/wp-content\/uploads\/6e83a393fdc9ab74fda4cbdddddb5213.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nDet b\u00f6r noteras att inga Serde-objekt beh\u00f6ver anges, eftersom str\u00e4ng-Surde anv\u00e4nds i inst\u00e4llningarna. Dessutom fylls tabellen med poster i b\u00f6rjan tack vare anv\u00e4ndningen av uppr\u00e4kningen EARLIEST.<\/p>\n<p>Nu kan vi g\u00e5 vidare till det sista steget \u2013 sammanfogning.<\/p>\n<h3>Sammanfogning av nyhetsuppdateringar med data om antalet transaktionen<\/h3>\n<p>\nAtt skapa sammanfogningen \u00e4r inte sv\u00e5rt. Vi kommer att anv\u00e4nda en v\u00e4nster-sammanfogning f\u00f6r att hantera fallet d\u00e4r det inte finns n\u00e5gra b\u00f6rsnyheter f\u00f6r den aktuella branschen (den n\u00f6dv\u00e4ndiga koden kan hittas i filen src\/main\/java\/bbejeck\/chapter_5\/CountingWindowingAndKtableJoinExample.java) (listing 5.10).<\/p>\n<p><img decoding=\"async\" alt=\"Boken &quot;Kafka Streams i praktiken. Applikationer och mikrotj\u00e4nster f\u00f6r realtidsarbete&quot;\" src=\"\/wp-content\/uploads\/92ed70f98927d2f778ad14dbc2a5aa26.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nDenna leftJoin-operator \u00e4r ganska enkel. Till skillnad fr\u00e5n sammanfogningarna i kapitel 4 anv\u00e4nds metoden JoinWindow inte, eftersom det f\u00f6r varje nyckel i KTable finns endast en post vid KStream-KTable-sammanfogningen. Denna sammanfogning \u00e4r inte tidsbegr\u00e4nsad: posten antingen finns i KTable eller inte. Den viktigaste insikten \u00e4r att KTable-objekt kan berika KStream med mindre frekvent uppdaterad referensdata.<\/p>\n<p>Nu ska vi titta p\u00e5 ett mer effektivt s\u00e4tt att berika h\u00e4ndelser fr\u00e5n KStream.<\/p>\n<h3>5.3.4. GlobalKTable-objekt<\/h3>\n<p>\nSom ni f\u00f6rst\u00e5tt finns det ett behov av att berika h\u00e4ndelsefl\u00f6den eller l\u00e4gga till kontext till dem. I kapitel 4 s\u00e5g ni sammanfogningarna av tv\u00e5 KStream-objekt, och i det f\u00f6reg\u00e5ende avsnittet sammanfogningen av KStream och KTable. I alla dessa fall \u00e4r det n\u00f6dv\u00e4ndigt att om-sektera datan vid kartl\u00e4ggning av nycklar till en ny typ eller v\u00e4rde. Ibland g\u00f6rs om-sektering explicit, och ibland g\u00f6r Kafka Streams det automatiskt. Om-sektering \u00e4r n\u00f6dv\u00e4ndig eftersom nycklarna har \u00e4ndrats och posterna m\u00e5ste hamna i nya sektioner, annars kommer sammanfogningen att vara om\u00f6jlig (detta diskuterades i kapitel 4, avsnittet 'Om-sektering av data' del 4.2.4).<\/p>\n<h3>Ominaraktivering har sitt pris<\/h3>\n<p>\nOminaraktivering kr\u00e4ver resurser - ytterligare resurskostnader f\u00f6r att skapa mellanliggande \u00e4mnen, lagra duplicerade data i ytterligare ett \u00e4mne; det inneb\u00e4r ocks\u00e5 en \u00f6kad latens p\u00e5 grund av skrivning och l\u00e4sning fr\u00e5n det \u00e4mnet. Dessutom, om man beh\u00f6ver utf\u00f6ra en f\u00f6rening ut\u00f6ver en aspekt eller dimension, m\u00e5ste man organisera f\u00f6reningarna i en kedja, avbilda poster med nya nycklar och \u00e5terigen genomf\u00f6ra processen f\u00f6r omaraktivering.<\/p>\n<h3>F\u00f6rening med mindre datam\u00e4ngder<\/h3>\n<p>\nI vissa fall \u00e4r volymen av referensdata som planeras f\u00f6r f\u00f6rening relativt liten, s\u00e5 att hela deras kopior kan rymmas lokalt p\u00e5 varje nod. F\u00f6r s\u00e5dana situationer finns det en klass som heter GlobalKTable i Kafka Streams.<\/p>\n<p>Exemplaren av GlobalKTable \u00e4r unika eftersom applikationen replikeras alla data p\u00e5 varje nod. Och eftersom alla noder inneh\u00e5ller all data, \u00e4r det inte n\u00f6dv\u00e4ndigt att omarakterisera h\u00e4ndelsefl\u00f6det efter referensdatanyckeln f\u00f6r att den ska vara tillg\u00e4nglig f\u00f6r alla sektioner. Med hj\u00e4lp av objekten GlobalKTable kan man \u00e4ven utf\u00f6ra nyckell\u00f6sa f\u00f6reningar. L\u00e5t oss \u00e5terkomma till ett av de tidigare exemplen f\u00f6r att demonstrera den h\u00e4r funktionen.<\/p>\n<h3>F\u00f6rening av KStream-objekt med GlobalKTable-objekt<\/h3>\n<p>\nI avsnitt 5.3.2 genomf\u00f6rde vi f\u00f6nsteraggregering av b\u00f6rstransaktioner utifr\u00e5n k\u00f6pare. Resultaten av denna aggregering s\u00e5g ungef\u00e4r ut s\u00e5 h\u00e4r:<\/p>\n<pre><code class=\"plaintext\">{customerId='074-09-3705', stockTicker='GUTM'}, 17\n{customerId='037-34-5184', stockTicker='CORK'}, 16<\/code><\/pre>\n<p>\n\u00c4ven om dessa resultat motsvarade det uppsatta m\u00e5let skulle det vara mer praktiskt om ocks\u00e5 kundens namn och f\u00f6retagets fullst\u00e4ndiga namn visades. F\u00f6r att l\u00e4gga till kundens namn och f\u00f6retagets namn kan man utf\u00f6ra vanliga f\u00f6reningar, men d\u00e5 beh\u00f6ver man g\u00f6ra tv\u00e5 nyckelavbildningar och omaraktivering. Med GlobalKTable kan man undvika kostnader f\u00f6r s\u00e5dana operationer.<\/p>\n<p>F\u00f6r detta kommer vi att anv\u00e4nda objektet countStream fr\u00e5n listings 5.11 (den motsvarande koden kan hittas i filen src\/main\/java\/bbejeck\/chapter_5\/GlobalKTableExample.java), och f\u00f6rena det med tv\u00e5 GlobalKTable-objekt.<\/p>\n<p><img decoding=\"async\" alt=\"Boken &quot;Kafka Streams i praktiken. Applikationer och mikrotj\u00e4nster f\u00f6r realtidsarbete&quot;\" src=\"\/wp-content\/uploads\/fc4d91bbe062ceb94f5650224840b81e.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nVi har redan diskuterat detta tidigare, s\u00e5 jag ska inte upprepa mig. Jag vill dock notera att koden i funktionen toStream().map \u00e4r abstraherad i ett funktionellt objekt ist\u00e4llet f\u00f6r en inb\u00e4ddad lambda-uttryck f\u00f6r l\u00e4sbarhetens skull.<\/p>\n<p>N\u00e4sta steg \u00e4r att deklarera tv\u00e5 instanser av GlobalKTable (den medf\u00f6ljande koden finns i filen src\/main\/java\/bbejeck\/chapter_5\/GlobalKTableExample.java) (lista 5.12).<\/p>\n<p><img decoding=\"async\" alt=\"Boken &quot;Kafka Streams i praktiken. Applikationer och mikrotj\u00e4nster f\u00f6r realtidsarbete&quot;\" src=\"\/wp-content\/uploads\/db3918895f174c8cfb5fc927b55f87a1.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>Observera att \u00e4mnesnamnen anges med hj\u00e4lp av uppr\u00e4kningsbara typer.<\/p>\n<p>Nu n\u00e4r vi har f\u00f6rberett alla komponenter \u00e5terst\u00e5r det att skriva koden f\u00f6r f\u00f6reningen (som kan hittas i filen src\/main\/java\/bbejeck\/chapter_5\/GlobalKTableExample.java) (lista 5.13).<\/p>\n<p><img decoding=\"async\" alt=\"Boken &quot;Kafka Streams i praktiken. Applikationer och mikrotj\u00e4nster f\u00f6r realtidsarbete&quot;\" src=\"\/wp-content\/uploads\/799360cc99f1920c190a61fd4685d4ff.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n\u00c4ven om det finns tv\u00e5 f\u00f6reningar i denna kod, \u00e4r de organiserade i en kedja eftersom inget av resultaten anv\u00e4nds separat. Resultaten visas i slutet av hela operationen.<\/p>\n<p>N\u00e4r du k\u00f6r den ovanst\u00e5ende f\u00f6reningsoperationen f\u00e5r du resultat av f\u00f6ljande slag:<\/p>\n<pre><code class=\"plaintext\">{customer='Barney, Smith' company=\"Exxon\", transactions= 17}<\/code><\/pre>\n<p>\nK\u00e4rnan \u00e4r of\u00f6r\u00e4ndrad, men dessa resultat ser mer f\u00f6rst\u00e5eliga ut.<\/p>\n<p>Om vi r\u00e4knar med kapitel 4 har du redan sett flera typer av f\u00f6reningar i aktion. De listas i tabell 5.2. Denna tabell \u00e5terspeglar f\u00f6reningsm\u00f6jligheterna som \u00e4r aktuella f\u00f6r version 1.0.0 av Kafka Streams; i framtida utg\u00e5vor kan n\u00e5got f\u00f6r\u00e4ndras.<\/p>\n<p><img decoding=\"async\" alt=\"Boken &quot;Kafka Streams i praktiken. Applikationer och mikrotj\u00e4nster f\u00f6r realtidsarbete&quot;\" src=\"\/wp-content\/uploads\/8e4cf35c64a8431bda43a5e748de275f.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nSom en sammanfattning p\u00e5minner jag om det viktigaste: du kan f\u00f6rena h\u00e4ndelsestr\u00f6mmar (KStream) och uppdateringsfl\u00f6den (KTable) med hj\u00e4lp av lokal stat. Dessutom, om storleken p\u00e5 referensdata inte \u00e4r f\u00f6r stor, kan du anv\u00e4nda objektet GlobalKTable. GlobalKTable replikerar alla partitioner p\u00e5 varje nod i Kafka Streams-applikationen, vilket garanterar tillg\u00e5ngen till all data oavsett vilken partition nyckeln tillh\u00f6r.<\/p>\n<p>D\u00e4refter kommer vi att se en funktion i Kafka Streams som g\u00f6r det m\u00f6jligt att \u00f6vervaka f\u00f6r\u00e4ndringar i tillst\u00e5ndet utan att konsumera data fr\u00e5n Kafka-\u00e4mnet.<\/p>\n<h3>5.3.5. Tillg\u00e4ngligt f\u00f6r fr\u00e5getillst\u00e5nd<\/h3>\n<p>\nVi har redan utf\u00f6rt flera operationer som involverar tillst\u00e5nd och alltid skrivit ut resultaten i konsolen (f\u00f6r utvecklings\u00e4ndam\u00e5l) eller skrivit dem till ett \u00e4mne (f\u00f6r industriellt bruk). N\u00e4r resultaten skrivs till ett \u00e4mne m\u00e5ste du anv\u00e4nda en Kafka-konsument f\u00f6r att se dem.<\/p>\n<p>Att l\u00e4sa data fr\u00e5n dessa \u00e4mnen kan betraktas som en form av materialiserade vyer. F\u00f6r v\u00e5ra \u00e4ndam\u00e5l kan vi anv\u00e4nda definitionen av en materialiserad vy fr\u00e5n \"Wikipedia\": \u201e... ett fysiskt objekt i databasen som inneh\u00e5ller resultaten av en fr\u00e5ga. Det kan till exempel vara en lokal kopia av fj\u00e4rrdata, eller en delm\u00e4ngd av rader och\/eller kolumner fr\u00e5n en tabell eller resultaten av en sammanfogning, eller en pivottabell som erh\u00e5llits genom aggregering\" (https:\/\/en.wikipedia.org\/wiki\/Materialized_view).<\/p>\n<p>Kafka Streams m\u00f6jligg\u00f6r ocks\u00e5 interaktiva fr\u00e5gor mot tillst\u00e5ndslager, vilket ger betydelsen av direkt l\u00e4sning av dessa materialiserade vyer. Det \u00e4r viktigt att notera att en f\u00f6rfr\u00e5gan till tillst\u00e5ndslagret \u00e4r en \"endast l\u00e4sning\"-operation. Tack vare detta beh\u00f6ver du inte vara r\u00e4dd f\u00f6r att oavsiktligt g\u00f6ra tillst\u00e5ndet inkonsekvent under databehandlingen i applikationen.<\/p>\n<p>M\u00f6jligheten att direkt fr\u00e5ga tillst\u00e5ndslager \u00e4r mycket betydelsefull. Det inneb\u00e4r att man kan skapa applikationer \u2014 instrumentpaneler utan att f\u00f6rst beh\u00f6va f\u00e5 data fr\u00e5n Kafka-konsumenten. Den \u00f6kar ocks\u00e5 effektiviteten i applikationen, eftersom det inte beh\u00f6vs att skriva om data:<\/p>\n<ul>\n<li>tack vare datalokaliteten kan de snabbt n\u00e5s;<\/li>\n<li>dataduplicering utesluts, eftersom de inte skrivs till ett externt lagringsutrymme.<\/li>\n<\/ul>\n<p>\nDet viktigaste jag vill att du ska komma ih\u00e5g: du kan direkt utf\u00f6ra fr\u00e5gor mot tillst\u00e5ndet fr\u00e5n applikationen. M\u00f6jligheterna som detta ger dig kan inte \u00f6verskattas. Ist\u00e4llet f\u00f6r att konsumera data fr\u00e5n Kafka och lagra poster i en databas f\u00f6r applikationen, kan du fr\u00e5ga tillst\u00e5ndslager med samma resultat. Direkt fr\u00e5gor mot tillst\u00e5ndslager inneb\u00e4r mindre kod (ingen konsument) och mindre mjukvara (ingen behov av en databastabell f\u00f6r att lagra resultaten).<\/p>\n<p>Vi har t\u00e4ckt en stor m\u00e4ngd information i detta kapitel, s\u00e5 vi kommer att pausa v\u00e5r diskussion om interaktiva f\u00f6rfr\u00e5gningar till tillst\u00e5ndslager. Men oroa dig inte: i kapitel 9 kommer vi att skapa en enkel applikation \u2013 en informationspanel med interaktiva f\u00f6rfr\u00e5gningar. F\u00f6r att demonstrera interaktiva f\u00f6rfr\u00e5gningar och m\u00f6jligheterna att l\u00e4gga till dem i Kafka Streams-applikationer kommer vi att anv\u00e4nda n\u00e5gra av exemplen fr\u00e5n detta och f\u00f6reg\u00e5ende kapitel.<\/p>\n<h3>Sammanfattning<\/h3>\n<p><\/p>\n<ul>\n<li>KStream-objekt representerar fl\u00f6den av h\u00e4ndelser, j\u00e4mf\u00f6rbara med ins\u00e4ttningar i en databas. KTable-objekt representerar fl\u00f6den av uppdateringar och liknar mer uppdateringar i en databas. Storleken p\u00e5 KTable-objekt v\u00e4xer inte, gamla poster ers\u00e4tts med nya.<\/li>\n<li>KTable-objekt beh\u00f6vs f\u00f6r aggregeringsoperationer.<\/li>\n<li>Med hj\u00e4lp av f\u00f6nsteroperationer kan man dela upp aggregerade data i tidsfack.<\/li>\n<li>Tack vare GlobalKTable-objekt kan man f\u00e5 tillg\u00e5ng till referensdata var som helst i applikationen, oavsett partitionering.<\/li>\n<li>Det \u00e4r m\u00f6jligt att g\u00f6ra anslutningar mellan KStream-, KTable- och GlobalKTable-objekt.<\/li>\n<\/ul>\n<p>\nHitintills har vi fokuserat p\u00e5 att skapa Kafka Streams-applikationer med hj\u00e4lp av det h\u00f6gre niv\u00e5ns DSL KStream. \u00c4ven om den h\u00f6gre niv\u00e5ns metod m\u00f6jligg\u00f6r skapandet av rena och koncisa program, \u00e4r det en viss kompromiss. Att arbeta med DSL KStream inneb\u00e4r en \u00f6kning av koden koncishet p\u00e5 bekostnad av kontrollniv\u00e5. I n\u00e4sta kapitel kommer vi att titta p\u00e5 det l\u00e4gre niv\u00e5ns API f\u00f6r bearbetningsnoder och \u00f6verv\u00e4ga andra kompromisser. Programmen kommer att bli l\u00e4ngre \u00e4n de har varit tidigare, men vi kommer att ha m\u00f6jlighet att skapa n\u00e4stan vilken bearbetningsnod vi \u00e4n kan beh\u00f6va.<\/p>\n<p>\u2192 L\u00e4s mer om boken p\u00e5 <noindex><a rel=\"nofollow\" href=\"https:\/\/www.piter.com\/collection\/best\/product\/kafka-streams-v-deystvii-prilozheniya-i-mikroservisy-dlya-raboty-v-realnom-vremeni\">f\u00f6rlagets webbplats<\/a><\/noindex><\/p>\n<p>\u2192 F\u00f6r Habr-anh\u00e4ngare finns det 25% rabatt med kupong \u2014 <b>Kafka Streams<\/b><\/p>\n<p>\u2192 Vid betalning av den tryckta versionen av boken skickas e-boken via e-post.<br \/>\n<br \/>K\u00e4lla: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/piter\/blog\/457756\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041f\u0440\u0438\u0432\u0435\u0442, \u0425\u0430\u0431\u0440\u043e\u0436\u0438\u0442\u0435\u043b\u0438! \u042d\u0442\u0430 \u043a\u043d\u0438\u0433\u0430 \u043f\u043e\u0434\u043e\u0439\u0434\u0435\u0442 \u0434\u043b\u044f \u043b\u044e\u0431\u043e\u0433\u043e \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0445\u043e\u0447\u0435\u0442 \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c\u0441\u044f \u0432 \u043f\u043e\u0442\u043e\u043a\u043e\u0432\u043e\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0435. \u041f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u043e\u043c\u043e\u0436\u0435\u0442 \u043b\u0443\u0447\u0448\u0435 \u0438\u0437\u0443\u0447\u0438\u0442\u044c Kafka \u0438 Kafka Streams. \u0411\u044b\u043b\u043e \u0431\u044b \u043d\u0435\u043f\u043b\u043e\u0445\u043e \u0437\u043d\u0430\u0442\u044c \u0438 \u0441\u0430\u043c \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a Kafka, \u043d\u043e \u044d\u0442\u043e \u043d\u0435 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e: \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u0432\u0430\u043c \u0432\u0441\u0435, \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u043e. \u041e\u043f\u044b\u0442\u043d\u044b\u0435 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 Kafka, \u043a\u0430\u043a \u0438 \u043d\u043e\u0432\u0438\u0447\u043a\u0438, \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u044d\u0442\u043e\u0439 \u043a\u043d\u0438\u0433\u0435 \u043e\u0441\u0432\u043e\u044f\u0442 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-35786","post","type-post","status-publish","format-standard","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.4 - aioseo.com -->\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/sv\/blog\/administrirovanie\/kniga-kafka-streams-v-dejstvii-prilozheniya-i-mikroservisy-dlya-raboty-v-realnom-vremeni\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.4\" \/>\n\t\t<meta property=\"og:locale\" content=\"sv_SE\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u041a\u043d\u0438\u0433\u0430 \u00abKafka Streams \u0432 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0438. \u041f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0438 \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u044b \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u043c \u0432\u0440\u0435\u043c\u0435\u043d\u0438\u00bb | ProHoster\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/sv\/blog\/administrirovanie\/kniga-kafka-streams-v-dejstvii-prilozheniya-i-mikroservisy-dlya-raboty-v-realnom-vremeni\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-10-31T19:06:19+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T19:06:19+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Boken \"Kafka Streams in Action. Applikationer och mikrotj\u00e4nster f\u00f6r realtidsarbete\" | ProHoster","description":"","canonical_url":"https:\/\/prohoster.info\/sv\/blog\/administrirovanie\/kniga-kafka-streams-v-dejstvii-prilozheniya-i-mikroservisy-dlya-raboty-v-realnom-vremeni","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"sv_SE","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u041a\u043d\u0438\u0433\u0430 \u00abKafka Streams \u0432 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0438. \u041f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0438 \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u044b \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u043c \u0432\u0440\u0435\u043c\u0435\u043d\u0438\u00bb | ProHoster","og:url":"https:\/\/prohoster.info\/sv\/blog\/administrirovanie\/kniga-kafka-streams-v-dejstvii-prilozheniya-i-mikroservisy-dlya-raboty-v-realnom-vremeni","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-10-31T19:06:19+00:00","article:modified_time":"2019-10-31T19:06:19+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"35786","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-22 00:45:19","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-03-01 01:56:32","updated":"2026-01-22 00:45:19","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/posts\/35786","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/comments?post=35786"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/posts\/35786\/revisions"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/media?parent=35786"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/categories?post=35786"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/tags?post=35786"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}