Programmering

Hvorfor du bør bruke en grafdatabase

Jeff Carpenter er teknisk evangelist i DataStax.

Det har nylig vært mye spreng om grafdatabaser. Mens grafdatabaser som DataStax Enterprise Graph (basert på Titan DB), Neo4 og IBM Graph har eksistert i flere år, indikerer nylige kunngjøringer om administrerte skytjenester som AWS Neptune og Microsofts tillegg av grafkapasitet til Azure Cosmos DB at grafdatabaser har kommet inn i mainstream. Med all denne interessen, hvordan kan du bestemme om en grafdatabase er riktig for søknaden din?

Hva er en grafdatabase?

La oss definere noen terminologi før vi går videre. Hva er en grafdatabase? Tenk på det når det gjelder datamodellen. En grafdatamodell består av hjørner som representerer enhetene i et domene, og kanter som representerer forholdet mellom disse enhetene. Fordi både hjørner og kanter kan ha flere navn-verdi-par kalt eiendommer, er denne datamodellen formelt kjent som en eiendomsgraf. Noen grafdatabaser krever at du definerer en skjema for grafen din - dvs. definere etiketter eller navn på hjørnene, kantene og egenskapene dine før du fyller ut data - mens andre databaser lar deg operere uten et fast skjema.

Som du kanskje har lagt merke til, er det ingen ny informasjon i grafdatamodellen som vi ikke kunne fange i en tradisjonell relasjonsdatamodell. Tross alt er det enkelt å beskrive forholdet mellom tabeller ved hjelp av fremmede nøkler, eller vi kan beskrive egenskapene til et forhold med en sammenføyningstabell. Hovedforskjellen mellom disse datamodellene er måten data er organisert og tilgang til. Anerkjennelsen av kanter som en "førsteklasses borger" ved siden av hjørner i grafdatamodellen gjør det mulig for den underliggende databasemotoren å iterere veldig raskt i alle retninger gjennom nettverk av hjørner og kanter for å tilfredsstille applikasjonsforespørsler, en prosess kjent som traversal.

Fleksibiliteten til grafdatamodellen er en nøkkelfaktor som driver den nylige økningen i populariteten til grafdatabaser. De samme kravene til tilgjengelighet og massiv skala som styrte utviklingen og adopsjonen av forskjellige NoSQL-tilbud de siste 10 årene, fortsetter å bære frukt i den nylige graftrenden.

Hvordan vite når du trenger en grafdatabase

Men som med all populær teknologi, kan det være en tendens til å bruke grafdatabaser på alle problemer. Det er viktig å sørge for at du har en brukstilfelle som passer godt. For eksempel brukes grafer ofte til problemdomener som:

  • Sosiale nettverk
  • Anbefaling og personalisering
  • Customer 360, inkludert enhetsoppløsning (korrelering av brukerdata fra flere kilder)
  • Svindeloppdagelse
  • Kapitalforvaltning

Enten brukssaken din passer inn i et av disse domenene eller ikke, er det noen andre faktorer du bør vurdere som kan bidra til å avgjøre om en grafdatabase passer for deg:

  • Mange-til-mange-forhold. I sin bok "Designing Data Intensive Applications" (O'Reilly) antyder Martin Kleppmann at hyppige mange-til-mange-forhold i ditt problemdomene er en god indikator for grafbruk, siden relasjonsdatabaser har en tendens til å slite med å navigere effektivt i disse forholdene.
  • Høy verdi av relasjoner. En annen heuristikk jeg ofte har hørt: Hvis forholdet mellom dataelementene dine er like viktige eller viktigere enn selve elementene, bør du vurdere å bruke graf.
  • Lav ventetid i stor skala. Når du legger til en annen database i applikasjonen, blir applikasjonen også komplisert. Evnen til grafdatabaser til å navigere gjennom forholdene som er representert i store datasett raskere enn andre typer databaser, er det som rettferdiggjør denne ekstra kompleksiteten. Dette gjelder spesielt i tilfeller der et komplekst relasjonelt tilknytningsforespørsel ikke lenger utfører, og det ikke er noen ekstra optimaliseringsgevinster å oppnå i spørringen eller relasjonsstrukturen.

Definere grafskjema og spørsmål med Gremlin

La oss ta en titt på hvordan du kommer i gang med en grafdatabase ved hjelp av et reelt eksempel, det anbefalingssystemet vi nylig la til i KillrVideo. KillrVideo er et referanseprogram for å dele og se på videoer som vi har bygd for å hjelpe utviklere å lære hvordan man bruker DataStax Enterprise, inkludert DataStax Enterprise Graph, en grafdatabase bygget på toppen av svært skalerbare datateknologier, inkludert Apache Cassandra og Apache Spark.

Språket som brukes til å beskrive og samhandle med grafer i DataStax Enterprise Graph er Gremlin, som er en del av Apache TinkerPop-prosjektet. Gremlin er kjent som språket for å beskrive grafgjennomganger på grunn av dets fleksibilitet, utvidbarhet og støtte for både deklarative og tvingende spørsmål. Gremlin er basert på Groovy-språket, og drivere er tilgjengelige på flere språk. Det viktigste er at Gremlin støttes av de mest populære grafdatabasene, inkludert DataStax Enterprise Graph, Neo4j, AWS Neptune og Azure Cosmos DB.

Vi utformet en anbefalingsalgoritme for å identifisere dataene vi trenger som input. Tilnærmingen var å generere anbefalinger for en gitt bruker basert på videoer som var likt av lignende brukere. Målet vårt var å generere anbefalinger i sanntid når brukere interagerer med KillrVideo-applikasjonen, dvs. som en OLTP-interaksjon.

For å definere skjemaet identifiserte vi et delsett av dataene som administreres av KillrVideo som vi trengte for grafen vår. Dette inkluderte brukere, videoer, rangeringer og koder, samt egenskaper til disse elementene som vi kan referere til i algoritmen eller presentere i anbefalingsresultater. Vi opprettet et grafskjema i Gremlin som så slik ut:

// lage toppunktetiketter

schema.vertexLabel (“bruker”). partitionKey (‘userId’).

egenskaper (“userId”, “email”, “added_date”). ifNotExists (). create ();

schema.vertexLabel (“video”). partitionKey (‘videoId’).

egenskaper (“videoId”, “name”, “description”, “added_date”,

preview_image_location ”). ifNotExists (). create ();

schema.vertexLabel (“tag”). partitionKey (‘name’).

egenskaper (“navn”, “merket_dato”). ifNotExists (). create ();

// lage kantetiketter

schema.edgeLabel ("vurdert"). multiple (). egenskaper ("vurdering").

tilkobling ("bruker", "video"). ifNotExists (). create ();

schema.edgeLabel ("lastet opp"). single (). egenskaper ("added_date").

tilkobling ("bruker", "video"). ifNotExists (). create ();

schema.edgeLabel (“taggedWith”). singel ().

tilkobling ("video", "tag"). ifNotExists (). create ();

Vi valgte å modellere brukere, videoer og koder som hjørner, og brukte kanter for å identifisere hvilke brukere som lastet opp hvilke videoer, brukerrangeringer av videoer og kodene som er tilknyttet hver video. Vi tildelte egenskaper til hjørner og kanter som det henvises til i spørsmål eller er inkludert i resultatene. Det resulterende skjemaet ser slik ut i DataStax Studio, et utviklingsverktøy for bærbar PC-stil for utvikling og utføring av spørsmål i CQL og Gremlin.

Basert på dette skjemaet definerte vi spørringer som fyller ut data i grafen og spørsmål som henter data fra grafen. La oss se på et grafspørsmål som genererer anbefalinger. Her er den grunnleggende strømmen: For en gitt bruker, identifiser lignende brukere som likte videoer den gitte brukeren likte, velg videoer som lignende brukere også likte, ekskluder videoer den gitte brukeren allerede har sett på, ordne videoene etter popularitet og gi resultatene.

def numRatingsToSample = 1000

def localUserRatingsToSample = 10

def minPositiveRating = 4

def userID = ...

g.V (). har (“user”, “userId”, userID) .as (“^ currentUser”)

// få alle videoene brukeren så på og lagre dem

.map (out (‘rated '). dedup (). fold ()). as (“ ^ WatchVideos ”)

// gå tilbake til den nåværende brukeren

.select (“^ currentUser”)

// identifisere videoene brukeren vurderte høyt

.outE ('vurdert'). har ('vurdering', gte (minPositiveRating)). inV ()

// hvilke andre brukere vurderte disse videoene høyt?

.inE ('vurdert'). har ('vurdering', gte (minPositiveRating))

// begrense antall resultater slik at dette fungerer som et OLTP-spørsmål

.sample (numRatingsToSample)

// sorter etter rangering for å favorisere brukere som rangerte videoene høyest

.by (‘rating’). outV ()

// eliminere den nåværende brukeren

.where (neq (“^ currentUser”))

La oss ta en pause for å få pusten. Så langt i denne gjennomgangen har vi identifisert lignende brukere. Den andre delen av traversalen tar de lignende brukerne, tar et begrenset antall videoer de lignende brukerne likte, fjerner videoer brukeren allerede har sett på, og genererer et resultatsett sortert etter popularitet.

  // velg et begrenset antall høyt rangerte videoer fra hver lignende bruker

.local (outE ('rated'). har ('rating', gte (minPositiveRating)). limit (localUserRatingsToSample)). sack (assign) .by ('rating'). inV ()

// ekskluder videoer brukeren allerede har sett på

.not (hvor (innenfor (“^ WatchVideos”)))

// identifiser de mest populære videoene etter summen av alle rangeringer

.gruppe (). av (). av (sekk (). sum ())

// nå som vi har et stort kart over [video: score], bestill det

.ordre (lokal) .by (verdier, dekr) .begrens (lokal, 100) .velg (nøkler) .utfold ()

// send ut anbefalte videoer inkludert brukeren som lastet opp hver video

.project (‘video’, ‘user’)

.av()

.by (__. in (‘uploaded’))

Mens denne gjennomgangen ser komplisert ut, må du huske at det er hele forretningslogikken til en anbefalingsalgoritme. Vi vil ikke gå nærmere inn på hvert trinn i denne gjennomgangen her, men språkreferansen er en stor ressurs, og opplæringskurs av høy kvalitet er tilgjengelig.

Jeg anbefaler å utvikle traversaler interaktivt over et representativt datasett ved hjelp av et verktøy som DataStax Studio eller Gremlin-konsollen fra Apache TinkerPop. Dette lar deg raskt itere og finjustere dine traversaler. DataStax Studio er et nettbasert miljø som gir flere måter å visualisere traversale resultater som nettverk av noder og kanter, som vist på bildet nedenfor. Andre støttede visninger inkluderer tabeller, diagrammer og grafer, samt sporing av ytelse.

DataStax

Innlemme en grafdatabase i arkitekturen din

Når du har designet grafskjemaet og spørringene dine, er det på tide å integrere grafen i applikasjonen din. Slik integrerte vi DataStax Enterprise Graph i KillrVideo. KillrVidos flerlagsarkitektur består av et webapplikasjon som sitter på toppen av et sett med mikrotjenester som administrerer brukere, videoer (inkludert koder) og rangeringer. Disse tjenestene utnytter DataStax Enterprise Graph-databasen (bygget på Apache Cassandra) for datalagring og tilgang til dataene ved hjelp av CQL.

Vi implementerte anbefalingsmotoren vår som en del av tjenesten Foreslåtte videoer, som vist nedenfor. Denne tjenesten genererer en liste over anbefalinger gitt en bruker-ID. For å implementere anbefalingsmotoren oversatte vi Gremlin-traversalen beskrevet ovenfor til Java-kode.

DataStax

Denne arkitekturen fremhever en hyppig utfordring i mikrotjenestearkitekturer - behovet for å samhandle med data som eies av flere tjenester. Som vist ovenfor, er grafen som brukes til å generere anbefalinger, avhengig av data fra tjenestene User Management, Video Catalog og Ratings.

Vi bevarte dataeierskapet til våre eksisterende tjenester ved å bruke asynkrone meldinger. Tjenestene User Management, Video Catalog og Ratings publiserer hendelser på dataendringer. Den foreslåtte videotjenesten abonnerer på disse hendelsene og gjør tilsvarende oppdateringer til grafen. Avvikene vi har gjort her er typiske for applikasjoner som bruker en multimodelltilnærming, et emne jeg utforsket i min forrige artikkel.

Implementering av Gremlin-traversaler i Java

DataStax Java Driver gir et vennlig, flytende API for implementering av Gremlin-traversaler med DataStax Enterprise Graph. API-et gjorde det trivielt å migrere Groovy-baserte spørsmål vi opprettet i DataStax Studio til Java-kode.

Vi klarte da å gjøre Java-koden vår enda mer lesbar og vedlikeholdbar ved å bruke en Gremlin-funksjon kjent som DSL-er, domenespesifikke språk. En DSL er en utvidelse av Gremlin til et bestemt domene. For KillrVideo opprettet vi en DSL for å utvide Gremlin traversal implementering med vilkår som er relevante for videodomenet. De KillrVideoTraversalDsl klasse definerer spørringsoperasjoner som user (), som lokaliserer toppunktet i grafen med et gitt UUID, og recommendByUserRating (), som genererer anbefalinger for en gitt bruker basert på parametere som en minimumsvurdering og et ønsket antall anbefalinger.

Ved å bruke en DSL forenklet implementeringen av tjenesten Suggested Videos til noe som eksemplet nedenfor, som skaper en GraphStatement som vi deretter utfører ved hjelp av DataStax Java Driver:

GraphStatement gStatement = DseGraph.statementFromTraversal (killr.users (userIdString)

.recommendByUserRating (100, 4, 500, 10)

);

Ved å bruke en DSL fikk vi skjule noe av kompleksiteten til grafinteraksjonene våre i gjenbrukbare funksjoner, som deretter kan kombineres etter behov for å danne mer komplekse traversaler. Dette vil tillate oss å implementere flere anbefalingsmotorer som starter fra et valgt brukerpunkt som leveres av bruker() metode og la applikasjonen bytte mellom de forskjellige implementeringene.

Et fungerende grafeksempel

Du kan se resultatene av integrasjonen av DataStax Enterprise Graph i KillrVideo i delen "Anbefalt for deg" i webapplikasjonen vist nedenfor. Prøv det selv på //www.killrvideo.com ved å opprette en konto og rangere noen få videoer.

DataStax

Jeg håper at denne artikkelen gir deg noen gode ideer om hvordan en grafdatabase kan være fornuftig for søknaden din, og hvordan du kommer i gang med Gremlin og DataStax Enterprise Graph.

Jeff Carpenter er en teknisk evangelist i DataStax, hvor han utnytter sin bakgrunn innen systemarkitektur, mikrotjenester og Apache Cassandra for å hjelpe utviklere og driftsingeniører med å bygge distribuerte systemer som er skalerbare, pålitelige og sikre. Jeff er forfatteren av Cassandra: The Definitive Guide, 2. utgave.

New Tech Forum er et sted for å utforske og diskutere ny teknologi i enestående dybde og bredde. Valget er subjektivt, basert på vårt valg av teknologiene vi mener er viktige og av størst interesse for leserne. godtar ikke markedsføringssikkerhet for publisering og forbeholder seg retten til å redigere alt bidratt innhold. Send alle henvendelser til[email protected].

$config[zx-auto] not found$config[zx-overlay] not found