Gebeurtenisgestuurde gegevens met Apache Druid

1. Inleiding

In deze zelfstudie zullen we begrijpen hoe u met gebeurtenisgegevens en Apache Druid kunt werken. We behandelen de basisprincipes van gebeurtenisgegevens en druïde architectuur. Als onderdeel daarvan zullen we een eenvoudige gegevenspijplijn maken die gebruikmaakt van verschillende functies van Druid die verschillende manieren van gegevensopname omvat en verschillende manieren om de voorbereide gegevens op te vragen.

2. Basisconcepten

Voordat we ingaan op de bedieningsdetails van Apache Druid, laten we eerst enkele basisconcepten doornemen. De ruimte waarin we geïnteresseerd zijn, is realtime analyse van gebeurtenisgegevens op grote schaal.

Daarom is het absoluut noodzakelijk om te begrijpen wat we bedoelen met gebeurtenisgegevens en wat er nodig is om ze in realtime op schaal te analyseren.

2.1. Wat zijn gebeurtenisgegevens?

Gebeurtenisgegevens verwijzen naar een stukje informatie over een verandering die op een bepaald moment in de tijd plaatsvindt. Gebeurtenisgegevens zijn bijna alomtegenwoordig in hedendaagse toepassingen. Van de klassieke applicatielogboeken tot moderne sensordata die door dingen worden gegenereerd, het is praktisch overal. Deze worden vaak gekenmerkt door machinaal leesbare informatie die op grote schaal wordt gegenereerd.

Ze ondersteunen verschillende functies, zoals voorspelling, automatisering, communicatie en integratie, om er maar een paar te noemen. Bovendien zijn ze van belang in gebeurtenisgestuurde architectuur.

2.2. Wat is Apache Druid?

Apache Druid is een realtime analysedatabase die is ontworpen voor snelle analyse van gebeurtenisgeoriënteerde gegevens. Druid is gestart in 2011, open source onder de GPL-licentie in 2012 en verhuisd naar Apache License in 2015. Het wordt beheerd door de Apache Foundation met bijdragen van de gemeenschap van verschillende organisaties. Het biedt realtime opname, snelle queryprestaties en hoge beschikbaarheid.

De naam Druid verwijst naar het feit dat de architectuur kan verschuiven om verschillende soorten dataproblemen op te lossen. Het wordt vaak gebruikt in business intelligence-toepassingen om een ​​groot aantal realtime en historische gegevens te analyseren.

3. Druïde architectuur

Druïde is een kolomgeoriënteerde en gedistribueerde gegevensbron geschreven in Java. Het is in staat om enorme hoeveelheden gebeurtenisgegevens op te nemen en naast deze gegevens ook query's met een lage latentie aan te bieden. Bovendien biedt het de mogelijkheid om de gegevens willekeurig te snijden en in blokjes te snijden.

Het is best interessant om te begrijpen hoe Druid-architectuur deze functies ondersteunt. In dit gedeelte zullen we enkele van de belangrijke delen van de druïde architectuur bespreken.

3.1. Ontwerp van gegevensopslag

Het is belangrijk om te begrijpen hoe Druid zijn gegevens structureert en opslaat, wat partitionering en distributie mogelijk maakt. Druïde verdeelt de gegevens standaard tijdens de verwerking en slaat ze op in brokken en segmenten:

Druïde slaat gegevens op in wat we kennen als 'gegevensbron', wat logischerwijs vergelijkbaar is met tabellen in relationele databases. Een druïde cluster kan meerdere databronnen parallel verwerken, opgenomen uit verschillende bronnen.

Elke gegevensbron is gepartitioneerd - standaard op basis van tijd en verder op basis van andere kenmerken, indien geconfigureerd. EEN het tijdbereik van gegevens staat bekend als een 'brok' - bijvoorbeeld de gegevens van een uur als de gegevens op uurbasis zijn verdeeld.

Elke brok is verder onderverdeeld in een of meer "segmenten", dit zijn enkele bestanden die uit veel rijen gegevens bestaan. Een gegevensbron kan variëren van enkele segmenten tot miljoenen segmenten.

3.2. Druïde processen

Druid heeft een multi-proces en gedistribueerde architectuur. Daarom kan elk proces onafhankelijk worden geschaald, waardoor we flexibele clusters kunnen creëren. Laten we de belangrijke processen begrijpen die deel uitmaken van Druid:

  • Coördinator: Dit proces is voornamelijk verantwoordelijk voor segmentbeheer en distributie en communiceert met historische processen om segmenten te laden of te verwijderen op basis van configuraties
  • Opperheer: Dit is het hoofdproces dat verantwoordelijk is voor het accepteren van taken, het coördineren van taakverdeling, het creëren van vergrendelingen rond taken en het teruggeven van de status aan bellers
  • Makelaar: Dit is het proces waarnaar alle query's worden gestuurd om te worden uitgevoerd in een gedistribueerd cluster; het verzamelt metadata van Zookeeper en routeert zoekopdrachten naar processen met de juiste segmenten
  • Router: Dit is een optioneel proces dat kan worden gebruikt om query's naar verschillende brokerprocessen te leiden, waardoor query-isolatie wordt geboden aan query's voor belangrijkere gegevens
  • Historisch: Dit zijn de processen die opvraagbare gegevens opslaan; ze onderhouden een constante verbinding met Zookeeper en letten op segmentinformatie die ze moeten laden en serveren
  • Middenkader: Dit zijn de werkprocessen die de aangeleverde taken uitvoeren; ze sturen de taken door naar Peons die in afzonderlijke JVM's worden uitgevoerd, en bieden zo isolatie van bronnen en logboeken

3.3. Externe afhankelijkheden

Afgezien van de kernprocessen, Druid is afhankelijk van verschillende externe afhankelijkheden om het cluster te laten functioneren zoals verwacht.

Laten we eens kijken hoe een druïde cluster wordt gevormd samen met kernprocessen en externe afhankelijkheden:

Druïde gebruikt diepe opslag om alle opgenomen gegevens op te slaan in het systeem. Deze worden niet gebruikt om op de vragen te reageren, maar als back-up van gegevens en om gegevens tussen processen uit te wisselen. Dit kan van alles zijn, van een lokaal bestandssysteem tot een gedistribueerd objectarchief zoals S3 en HDFS.

De metadata-opslag wordt gebruikt om gedeelde systeemmetadata te bewaren zoals segmentgebruiksinformatie en taakinformatie. Het wordt echter nooit gebruikt om de feitelijke gegevens op te slaan. Het is een relationele database zoals Apache Derby, PostgreSQL of MySQL.

Druïde gebruikt Apache Zookeeper voor beheer van de huidige clusterstatus. Het vergemakkelijkt een aantal bewerkingen in een druïde cluster, zoals de verkiezing van coördinatoren / opperleiders, het publicatieprotocol voor segmenten en het protocol voor het laden / neerzetten van segmenten.

4. Druïde setup

Druid is ontworpen om te worden ingezet als een schaalbaar, fouttolerant cluster. Echter, het opzetten van een Druid-cluster van productiekwaliteit is niet triviaal. Zoals we eerder hebben gezien, zijn er veel processen en externe afhankelijkheden die moeten worden ingesteld en geconfigureerd. Omdat het mogelijk is om op een flexibele manier een cluster te creëren, moeten we aandacht besteden aan onze vereisten om individuele processen op de juiste manier in te richten.

Ook Druid wordt alleen ondersteund in Unix-achtige omgevingen en niet op Windows. Bovendien is Java 8 of hoger vereist om Druid-processen uit te voeren. Er zijn verschillende configuraties met één server beschikbaar om Druid op een enkele machine in te stellen voor het uitvoeren van tutorials en voorbeelden. Voor het uitvoeren van een productieworkload is het echter aan te raden om een ​​volwaardig Druid-cluster op te zetten met meerdere machines.

Voor deze tutorial zullen we installeer Druid op een enkele machine met behulp van de officiële Docker-image gepubliceerd op de Docker Hub. Hierdoor kunnen we Druid ook op Windows draaien, wat, zoals we eerder hebben besproken, verder niet wordt ondersteund. Er is een Docker-compose-bestand beschikbaar, dat een container maakt voor elk Druid-proces en zijn externe afhankelijkheden.

We moeten geef configuratiewaarden aan Druid als omgevingsvariabelen. De eenvoudigste manier om dit te bereiken is door een bestand met de naam "environment" aan te bieden in dezelfde map als het Docker-opstelbestand.

Zodra we de Docker-compose en het omgevingsbestand hebben geïnstalleerd, is het opstarten van Druid net zo eenvoudig als het uitvoeren van een commando in dezelfde map:

docker-compose

Hiermee worden alle containers weergegeven die nodig zijn voor een Druid-installatie met één machine. We moeten voorzichtig zijn om voldoende geheugen aan de Docker-machine te geven, aangezien Druid een aanzienlijke hoeveelheid bronnen verbruikt.

5. Gegevens opnemen

De eerste stap bij het bouwen van een datapijplijn met Druid is het laden van data in Druid. Dit proces wordt gegevensopname of indexering genoemd in de Druïde-architectuur. We moeten een geschikte dataset vinden om verder te gaan met deze tutorial.

Nu, zoals we tot nu toe hebben gezien, moeten we gegevens oppikken die gebeurtenissen zijn en een tijdelijk karakter hebben, om het meeste uit de Druïde-infrastructuur te halen.

De officiële gids voor druïde maakt gebruik van eenvoudige en elegante gegevens met bewerkingen van Wikipedia-pagina's voor een specifieke datum. We zullen dat blijven gebruiken voor onze tutorial hier.

5.1. Gegevensmodel

Laten we beginnen met het onderzoeken van de structuur van de gegevens die we bij ons hebben. Het grootste deel van de datapijplijn die we maken, is vrij gevoelig voor data-anomalieën, en daarom is het noodzakelijk om de data zo veel mogelijk op te schonen.

Hoewel er geavanceerde manieren en hulpmiddelen zijn om gegevensanalyses uit te voeren, beginnen we met visuele inspectie. Een snelle analyse leert dat de invoergegevens hebben gebeurtenissen die zijn vastgelegd in JSON-indeling, met een enkele gebeurtenis die typische kenmerken bevat:

{"time": "2015-09-12T02: 10: 26.679Z", "channel": "# pt.wikipedia", "cityName": null, "comment": "Hou het probleem bij een última edição e tive de refazê- las, junto com as atualizações da página. "," countryIsoCode ":" BR "," countryName ":" Brazilië "," isAnonymous ": true," isMinor ": false," isNew ": false," isRobot ": false , "isUnpatrolled": true, "metroCode": null, "namespace": "Main", "page": "Catarina Muniz", "regionIsoCode": null, "regionName": null, "user": "181.213.37.148 "," delta ": 197," toegevoegd ": 197," verwijderd ": 0}

Hoewel er nogal wat attributen zijn die deze gebeurtenis definiëren, zijn er een paar die speciaal voor ons interessant zijn wanneer we met Druid werken:

  • Tijdstempel
  • Dimensies
  • Metrische gegevens

Druïde vereist een bepaald kenmerk om te identificeren als een tijdstempelkolom. In de meeste situaties kan de dataparser van Druid automatisch de beste kandidaat detecteren. Maar we hebben altijd een keuze om uit te kiezen, vooral als we geen passend kenmerk in onze gegevens hebben.

Dimensies zijn de attributen die Druid as-is opslaat. We kunnen ze voor elk doel gebruiken, zoals groeperen, filteren of aggregators toepassen. We hebben de keuze om dimensies te selecteren in de opname-specificatie, die we verderop in de tutorial zullen bespreken.

Statistieken zijn de kenmerken die, in tegenstelling tot dimensies, in geaggregeerde vorm worden opgeslagen standaard. We kunnen een aggregatiefunctie kiezen voor Druid om toe te passen op deze attributen tijdens opname. Samen met roll-up ingeschakeld, kunnen deze leiden tot compacte dataweergaven.

5.2. Inslikken Methoden

Nu zullen we verschillende manieren bespreken waarop we de gegevensopname in Druid kunnen uitvoeren. Doorgaans worden gebeurtenisgestuurde gegevens van nature gestreamd, wat betekent dat ze in de loop van de tijd in verschillende snelheden blijven genereren, zoals bij Wikipedia-bewerkingen.

Het is echter mogelijk dat we gegevens in batches hebben om door te nemen, waar de gegevens statischer van aard zijn, zoals alle Wikipedia-bewerkingen die vorig jaar hebben plaatsgevonden.

We kunnen ook verschillende gevallen van gegevensgebruik hebben om op te lossen, en Druid heeft voor de meeste daarvan fantastische ondersteuning. Laten we twee van de meest voorkomende manieren bekijken om Druid in een datapijplijn te gebruiken:

  • Streaming opname
  • Batchopname

De De meest gebruikelijke manier om gegevens in Druid op te nemen, is via de Apache Streaming-service, waar Druid gegevens rechtstreeks uit Kafka kan lezen. Druid ondersteunt ook andere platforms zoals Kinesis. We moeten supervisors starten met het overbelastingsproces, dat Kafka-indexeringstaken maakt en beheert. We kunnen de supervisor starten door een supervisorspecificatie in te dienen als een JSON-bestand via de HTTP POST-opdracht van het overbelastingsproces.

Als alternatief kunnen we gegevens in batch opnemen - bijvoorbeeld vanuit een lokaal of extern bestand. Het biedt een keuze voor op Hadoop gebaseerde batchopname voor het opnemen van gegevens uit het Hadoop-bestandssysteem in het Hadoop-bestandsformaat. Vaker kunnen we de native batch-opname achtereenvolgens of parallel kiezen. Het is een gemakkelijkere en eenvoudigere aanpak omdat het geen externe afhankelijkheden heeft.

5.3. De taakspecificatie definiëren

Voor deze tutorial zullen we een systeemeigen batchopname-taak instellen voor de invoergegevens we hebben. We hebben de mogelijkheid om de taak te configureren vanuit de Druid-console, wat ons een intuïtieve grafische interface geeft. Afwisselend, wij kan de taakspecificatie definiëren als een JSON-bestand en deze indienen bij het overlord-proces met behulp van een script of de opdrachtregel.

Laten we eerst een eenvoudige taakspecificatie definiëren voor het opnemen van onze gegevens in een bestand met de naam wikipedia-index.json:

{"type": "index_parallel", "spec": {"dataSchema": {"dataSource": "wikipedia", "DimensionsSpec": {"Dimensions": ["channel", "cityName", "comment", " countryIsoCode "," countryName "," isAnonymous "," isMinor "," isNew "," isRobot "," isUnpatrolled "," metroCode "," namespace "," page "," regionIsoCode "," regionName "," user " , {"naam": "toegevoegd", "type": "lang"}, {"naam": "verwijderd", "type": "lang"}, {"naam": "delta", "type": "long"}]}, "timestampSpec": {"column": "time", "format": "iso"}, "metricsSpec": [], "granularitySpec": {"type": "uniform", " segmentGranularity ":" day "," queryGranularity ":" none "," intervallen ": [" 2015-09-12 / 2015-09-13 "]," rollup ": false}}," ioConfig ": {" type ":" index_parallel "," inputSource ": {" type ":" local "," baseDir ":" quickstart / tutorial / "," filter ":" wikiticker-2015-09-12-sampled.json.gz "} , "inputFormat": {"type": "json"}, "appendToExisting": false}, "tuningConfig": {"type": "index_parallel", "maxRowsPerSegment": 5000000, "maxRo wsInMemory ": 25000}}}

Laten we deze taakspecificatie begrijpen met betrekking tot de basisprincipes die we hebben doorlopen in eerdere subsecties:

  • We hebben gekozen voor de index_parallel task, die ons parallelle native batch-opname biedt
  • De gegevensbron die we in deze taak zullen gebruiken, heeft de naam “wikipedia ”
  • Het tijdstempel voor onze gegevens is afkomstig van het kenmerk 'tijd'
  • Er zijn een aantal gegevensattributen die we als dimensies toevoegen
  • We gebruiken geen statistieken voor onze gegevens in de huidige taak
  • Roll-up, dat standaard is ingeschakeld, moet voor deze taak worden uitgeschakeld
  • De invoerbron voor de taak is een lokaal bestand met de naam wikiticker-2015-09-12-sampled.json.gz
  • We gebruiken geen secundaire partitie, die we kunnen definiëren in het tuningConfig

Deze taakspec gaat ervan uit dat we het gegevensbestand hebben gedownloadwikiticker-2015-09-12-sampled.json.gz en bewaarde het op de lokale computer waarop Druid draait. Dit kan lastiger zijn als we Druid gebruiken als een Docker-container. Gelukkig, Druid wordt standaard geleverd met deze voorbeeldgegevens op de locatie snelstart / tutorial.

5.4. De taakspecificatie indienen

Ten slotte kunnen we deze taakspecificatie via de opdrachtregel indienen bij het overlord-proces met behulp van een tool zoals krullen:

curl -X 'POST' -H 'Content-Type: application / json' -d @ wikipedia-index.json // localhost: 8081 / druid / indexer / v1 / task

Normaal gesproken, het bovenstaande commando geeft de ID van de taak terug als de inzending succesvol is. We kunnen de status van onze innametaak verifiëren via de Druid-console of door query's uit te voeren, die we in de volgende sectie zullen bespreken.

5.5. Geavanceerde opnameconcepten

Druid is het meest geschikt als we een enorme hoeveelheid gegevens hebben om mee om te gaan - zeker niet het soort gegevens dat we in deze tutorial hebben gezien! Om functies op schaal mogelijk te maken, moet de Druïde-architectuur geschikte tools en trucs bieden.

Hoewel we ze in deze tutorial niet zullen gebruiken, laten we het snel hebben over het oprollen en partitioneren.

Gebeurtenisgegevens kunnen snel in omvang toenemen tot enorme volumes, wat van invloed kan zijn op de queryprestaties die we kunnen bereiken. In veel scenario's kan het zijn mogelijk voor ons om gegevens in de loop van de tijd samen te vatten. Dit is wat we kennen als roll-up in Druid. Als roll-up is ingeschakeld, doet Druid er moeite voor oprolrijen met identieke afmetingen en tijdstempels tijdens opname. Hoewel het ruimte kan besparen, leidt het samenvoegen tot een verlies aan queryprecisie, daarom moeten we het rationeel gebruiken.

Een andere mogelijke manier om betere prestaties te bereiken bij een toenemend datavolume, is het verdelen van de gegevens en daarmee de werklast. Standaard is Druid verdeelt de gegevens op basis van tijdstempels in tijdsdelen met een of meer segmenten. Verder kunnen we besluiten om secundaire partitionering uit te voeren met natuurlijke dimensies om de datalocatie te verbeteren. Bovendien sorteert Druid gegevens binnen elk segment eerst op tijdstempel en vervolgens op andere dimensies die we configureren.

6. Gegevens opvragen

Zodra we de gegevensopname met succes hebben uitgevoerd, zou deze klaar moeten zijn om door ons te worden opgevraagd. Er zijn meerdere manieren om gegevens in Druid op te vragen. De De eenvoudigste manier om een ​​query in Druid uit te voeren, is via de Druid-console. We kunnen echter ook zoekopdrachten uitvoeren door HTTP-opdrachten te verzenden of een opdrachtregelprogramma te gebruiken.

De twee prominente manieren om queries in Druid te construeren zijn native queries en SQL-achtige queries. Zouden gaan construeer op beide manieren enkele basisquery's en verstuur ze via HTTP gebruik makend van krullen. Laten we eens kijken hoe we enkele eenvoudige zoekopdrachten kunnen maken op basis van de gegevens die we eerder in Druid hebben opgenomen.

6.1. Native zoekopdrachten

Native zoekopdrachten in Druid gebruik JSON-objecten, die we voor verwerking naar een makelaar of router kunnen sturen. We kunnen de vragen onder andere via het HTTP POST-commando verzenden om hetzelfde te doen.

Laten we een JSON-bestand maken met de naam simple_query_native.json:

{"queryType": "topN", "dataSource": "wikipedia", "intervallen": ["2015-09-12 / 2015-09-13"], "granularity": "all", "dimension": " pagina "," metric ":" count "," threshold ": 10," aggregations ": [{" type ":" count "," name ":" count "}]}

Dit is een eenvoudige zoekopdracht die de top tien pagina's ophaalt die het hoogste aantal paginabewerkingen hebben ontvangen tussen 12 en 13 september 2019.

Laten we dit posten via HTTP met krullen:

curl -X 'POST' -H 'Content-Type: application / json' -d @ simple_query_native.json // localhost: 8888 / druid / v2?

Dit antwoord bevat de details van de top tien pagina's in JSON-indeling:

[{"timestamp": "2015-09-12T00: 46: 58.771Z", "result": [{"count": 33, "page": "Wikipedia: Vandalismusmeldung"}, {"count": 28, " page ":" Gebruiker: Cyde / Lijst met kandidaten voor snelle verwijdering / Subpagina "}, {" count ": 27," page ":" Jeremy Corbyn "}, {" count ": 21," page ":" Wikipedia: Prikbord / incidenten voor beheerders "}, {" count ": 20," page ":" Flavia Pennetta "}, {" count ": 18," page ":" Total Drama Presents: The Ridonculous Race "}, {" count ": 18," page ":" User talk: Dudeperson176123 "}, {" count ": 18," page ":" Wikipédia: Le Bistro / 12 septembre 2015 "}, {" count ": 17," page ": "Wikipedia: In het nieuws / kandidaten"}, {"count": 17, "page": "Wikipedia: verzoeken om paginabescherming"}]}]

6.2. Druïde SQL

Druid heeft een ingebouwde SQL-laag, die ons de vrijheid biedt om queries te construeren in vertrouwde SQL-achtige constructies. Het maakt gebruik van Apache Calcite om de queries te analyseren en te plannen. Druid SQL converteert de SQL-query's echter naar native query's op de querybroker voordat ze naar gegevensprocessen worden verzonden.

Laten we eens kijken hoe we dezelfde query als voorheen kunnen maken, maar met behulp van Druid SQL. Zoals eerder maken we een JSON-bestand met de naam simple_query_sql.json:

{"query": "SELECTEER pagina, COUNT (*) AS counts / FROM wikipedia WHERE \" __ time \ "/ TUSSEN TIMESTAMP '2015-09-12 00:00:00' AND TIMESTAMP '2015-09-13 00:00 : 00 '/ GROUP BY pagina ORDER BY Bewerkingen DESC LIMIT 10 "}

Houd er rekening mee dat de zoekopdracht voor leesbaarheid is opgesplitst in meerdere regels, maar dat deze op één regel moet verschijnen. Nogmaals, zoals eerder, zullen we deze query via HTTP posten, maar naar een ander eindpunt:

curl -X 'POST' -H 'Content-Type: application / json' -d @ simple_query_sql.json // localhost: 8888 / druid / v2 / sql

De uitvoer moet erg lijken op wat we eerder hebben bereikt met de native query.

6.3. Querytypen

We zagen in het eerdere gedeelte een type zoekopdracht waarbij we de top tien resultaten voor de statistiek "count" hebben opgehaald op basis van een interval. Dit is slechts één type vraag dat Druid ondersteunt, en het staat bekend als de TopN vraag. Natuurlijk kunnen we dit eenvoudig maken TopN query veel interessanter door filters en aggregaties te gebruiken. Maar dat valt niet binnen het bestek van deze tutorial. Er zijn echter verschillende andere vragen in Druid die ons mogelijk interesseren.

Enkele van de populaire zijn Timeseries en GroupBy.

Tijdreeksen query's retourneren een array van JSON-objecten, waarbij elk object een waarde vertegenwoordigt zoals beschreven in de tijdreeksquery, bijvoorbeeld het dagelijkse gemiddelde van een dimensie voor de afgelopen maand.

GroupBy queries retourneren een array van JSON-objecten, waarbij elk object een groepering vertegenwoordigt zoals beschreven in de group-by-query. We kunnen bijvoorbeeld het dagelijkse gemiddelde van een dimensie voor de afgelopen maand opvragen, gegroepeerd op een andere dimensie.

Er zijn verschillende andere soorten zoekopdrachten, waaronder Scannen, Zoeken, Tijdsgrens, SegmentMetadata, en DatasourceMetadata.

6.4. Geavanceerde queryconcepten

Druid biedt wat complexe methoden om geavanceerde query's te maken voor het maken van interessante datatoepassingen. Deze omvatten verschillende manieren om de gegevens te splitsen en te dobbelen, terwijl u toch ongelooflijke queryprestaties kunt bieden.

Hoewel een gedetailleerde bespreking ervan buiten het bestek van deze tutorial valt, laten we het bespreken enkele van de belangrijkste, zoals joins en lookups, multitenancy en querycaching.

Druid ondersteunt twee manieren om de gegevens samen te voegen. De eerste is de join-operators en de tweede is de zoekopdracht tijdens het zoeken. Voor betere queryprestaties is het echter raadzaam om query-time joins te vermijden.

Multitenancy verwijst naar de functie van het ondersteunen van meerdere tenants op dezelfde Druid-infrastructuur terwijl ze toch logische isolatie bieden. Het is mogelijk om dit in Druid te bereiken door middel van aparte databronnen per tenant of datapartitionering door de huurder.

En tot slot is het cachen van query's de sleutel tot prestaties in gegevensintensieve applicaties. Druid ondersteunt het cachen van queryresultaten op segment- en queryresultaatniveau. Verder kunnen de cachegegevens zich in het geheugen of in externe permanente opslag bevinden.

7. Taalbindingen

Hoewel Druid uitstekende ondersteuning heeft voor het maken van opname-specificaties en het definiëren van queries in JSON, is het kan soms vervelend zijn om deze query's in JSON te definiëren, vooral wanneer zoekopdrachten complex worden. Helaas biedt Druid geen klantenbibliotheek in een specifieke taal om ons hierbij te helpen. Maar daar zijn nogal wat taalbanden die zijn ontwikkeld door de gemeenschap. Een dergelijke clientbibliotheek is ook beschikbaar voor Java.

We zullen snel zien hoe we het TopN query die we eerder gebruikten met behulp van deze clientbibliotheek in Java.

Laten we beginnen met het definiëren van de vereiste afhankelijkheid in Maven:

 in.zapr.druïde druïdrie 2.14 

Hierna zouden we de clientbibliotheek moeten kunnen gebruiken en onze TopN vraag:

DateTime startTime = nieuwe DateTime (2015, 9, 12, 0, 0, 0, DateTimeZone.UTC); DateTime endTime = nieuwe DateTime (2015, 9, 13, 0, 0, 0, DateTimeZone.UTC); Interval interval = nieuw interval (startTime, endTime); Granulariteit granulariteit = nieuwe SimpleGranularity (PredefinedGranularity.ALL); DruidDimension-dimensie = nieuwe SimpleDimension ("pagina"); TopNMetric metric = nieuwe SimpleMetric ("count"); DruidTopNQuery query = DruidTopNQuery.builder () .dataSource ("wikipedia") .dimension (dimensie) .threshold (10) .topNMetric (metrisch) .granularity (granulariteit) .filter (filter) .aggregators (Arrays.asList (nieuwe LongSumAggregator ( "count", "count"))) .intervals (Collections.singletonList (interval)). build ();

Hierna kunnen we eenvoudig de vereiste JSON-structuur genereren, die we kunnen gebruiken in de HTTP POST-oproep:

ObjectMapper-mapper = nieuwe ObjectMapper (); String requiredJson = mapper.writeValueAsString (query);

8. Conclusie

In deze tutorial hebben we de basisprincipes van gebeurtenisgegevens en Apache Druid-architectuur doorgenomen.

Verder hebben we een primair Druid-cluster opgezet met Docker-containers op onze lokale computer. Vervolgens hebben we ook het proces doorlopen van het opnemen van een voorbeelddataset in Druid met behulp van de native batchtaak. Hierna zagen we de verschillende manieren waarop we onze gegevens in Druid moeten opvragen. Ten slotte hebben we een clientbibliotheek in Java doorlopen om Druid-query's te maken.

We hebben zojuist de oppervlakte van de functies die Druid te bieden heeft, bekrast. Er zijn verschillende mogelijkheden waarin Druid ons kan helpen bij het bouwen van onze datapijplijn en het maken van datatoepassingen. De geavanceerde opname- en queryfuncties zijn de voor de hand liggende volgende stappen om te leren, om effectief gebruik te maken van de kracht van Druid.

Bovendien zou het creëren van een geschikte druïde cluster die de individuele processen schaalt naar behoefte het doel moeten zijn om de voordelen te maximaliseren.