View a markdown version of this page

Modello di pool per grafici di proprietà etichettati - AWS Guida prescrittiva

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

Modello di pool per grafici di proprietà etichettati

Esistono tre diversi approcci al modello di pool per LPGs Amazon Neptune:

  • Strategia immobiliare ‒ Scegli la strategia delle proprietà quando devi dare priorità all'uso di costrutti di libreria consolidati come il linguaggio Apache Gremlin rispetto alle prestazioni TinkerPop . PartitionStrategy

  • Strategia prefix-label ‒ Consigliamo la strategia prefix-label per la maggior parte degli scenari basati sulle prestazioni e sulla limitazione degli effetti rumorosi dei vicini.

  • Strategia a più etichette ‒ La strategia a più etichette offre prestazioni migliorate della strategia con etichetta con prefisso. Supporta anche l'esecuzione di query che riguardano tutti i tenant di un cluster (ad esempio, query ISV per il reporting o il monitoraggio su tutti i tenant).

Strategia immobiliare

Con LPGs, gli utenti possono aggiungere proprietà di coppia chiave-valore ai nodi, ai vertici e agli spigoli. Per ottenere la separazione logica, la maggior parte dei clienti la modella in modo intuitivo come una proprietà unica su ogni nodo e perimetro con una chiave di proprietà comune del tenant. La chiave di proprietà del tenant rappresenta tutti i tenant che possiedono il nodo. L'identificatore del tenant è un valore univoco che identifica un singolo tenant.

Il diagramma seguente mostra questo modello. I due sottografi disconnessi hanno diversi nodi e bordi etichettati, con la chiave di proprietà del tenant rappresentata da. TId Ogni nodo e spigolo di un sottografo ha un valore di. TId 1 Nell'altro sottografo, ogni nodo e spigolo ha un TId valore di. 2

I nodi e le loro relazioni.

All'interno dei grafici delle proprietà etichettati, ci sono due modi per gestirlo. Il linguaggio di interrogazione Gremlin offre la libreria PartitionStrategytrasversale per aiutare a gestire il partizionamento dei dati. Il codice dell'esempio seguente prevede che ogni nodo e ogni bordo abbiano una proprietà chiamata: TId

strategy1 = new PartitionStrategy(partitionKey: "TId", writePartition: "1", readPartitions: ["1"]) strategy2 = new PartitionStrategy(partitionKey: "TId", writePartition: "2", readPartitions: ["2"])

Quando vengono scritti nuovi nodi o bordi, la proprietà "TId" viene aggiunta con il valore "1" o"2", a seconda che sia strategy2 stato selezionato strategy1 o meno. Per il cliente con "TId" of"1", si utilizzastrategy1. L'esempio seguente mostra la scrittura di dati per quel cliente:

g.withStrategies(strategy1).addV("Label1").property("Value", "123456").property(id, "Item_1")

Per le query di lettura, "TId == '2'" viene aggiunto un filtro per "TId == '1'" o a ogni nodo o edge traversal utilizzando strategy1 ostrategy2, rispettivamente. Queste strategie di partizione semplificano il codice, ma non sono necessarie. Il vantaggio dell'utilizzo di questa strategia è che può essere iniettata a livello di autorizzazione e passata al codice di livello inferiore che forma la query. Ciò separa il codice che determina l'identificatore del cliente (TId) dalla logica della query.

Il codice di esempio seguente mostra una query Gremlin per leggere i dati:

g.withStrategies(strategy1).V().hasLabel("Label1")

Il codice precedente è equivalente al seguente esempio:

g.V().hasLabel("Label1").has("TId", "1")

Allo stesso modo, quando si scrivono dati utilizzando Gremlin, è possibile utilizzare la seguente query:

g.withStrategies(strategy1).addV("Label1").property("Value").property(id, "Item_1")

Il codice precedente è equivalente al seguente esempio, che non utilizza la strategia di partizione e richiede quindi che la "TId" proprietà sia scritta in modo esplicito:

g.addV("Label1").property("TId", "1").property("Value").property(id, "Item_1")

In OpenCypher, queste librerie non esistono. Sei responsabile della scrittura e della modifica delle tue query per aggiungere l'identificatore del tenant come proprietà su nodi e bordi. Esempio:

CREATE (n:Item {`~id`: 'Item_1', Value: '123456', TId: '1'}) CREATE (n:Item {`~id`: 'Item_2', Value: '123456', TId: '2'})

Notate la somiglianza tra il codice Gremlin senza la strategia di partizione. È quindi possibile leggere il nodo scritto dalla prima CREATE istruzione utilizzando il codice seguente:

MATCH (n:Item {TId: '1'}) RETURN n --or MATCH (n:Item) WHERE n.TId == '1' RETURN n

È possibile scegliere la strategia delle proprietà quando si desidera utilizzare costrutti TinkerPop Gremlin nativi come. PartitionStrategy Tuttavia, questo modello presenta degli svantaggi in termini di prestazioni su Amazon Neptune rispetto alla strategia prefix-label. Per una discussione su questi svantaggi prestazionali, consulta la sezione Implicazioni prestazionali per i modelli GPL.

Se si applicano le seguenti condizioni, prendete in considerazione la possibilità di modellare la strategia delle proprietà solo sui nodi, non sugli spigoli:

  • Il grafico presenta un numero significativamente maggiore di bordi rispetto alle etichette.

  • Ogni inquilino è un grafico disconnesso.

  • È possibile accedere al grafico solo utilizzando i nodi come punto di partenza, non le etichette.

Strategia basata sull'etichetta con prefisso

Se le prestazioni sono una delle principali preoccupazioni, consigliamo vivamente di prendere in considerazione la strategia basata sull'etichetta con prefisso rispetto alla strategia immobiliare.

Nella strategia prefix-label, si etichetta ogni nodo con una combinazione di identificatore del tenant e etichetta del nodo. Ad esempio, se il tenant ha un identificatore di "1" e l'etichetta del nodo è"Label1", si specifica l'etichetta del nodo come. "1-Label1" Il diagramma seguente mostra due sottografi disconnessi che utilizzano questo modello.

Nodi con etichette che includono prefissi e relazioni tra nodi.

Quando scrivi dati in Gremlin, puoi aggiungere un numero identificativo all'etichetta di qualsiasi nodo:

g.addV("1-Label1") g.addV("2-Label6")

Quando interrogate questo grafico, potete verificare l'esistenza di questo prefisso su un nodo:

g.V().hasLabel("1-Label1")

In OpenCypher puoi scrivere dati usando un'istruzione: CREATE

CREATE (n:`1-Label1` {`~id`: 'Item_1', Value: 'XYZ123456'})

Per interrogare i dati che hai scritto in OpenCypher, usa il seguente codice:

MATCH n= (:`1-Label1`) RETURN n

La strategia prefix-label presuppone che tutti i nodi siano assegnati a uno o più tenant e che le autorizzazioni non vengano assegnate nell'ambito edge. Evita di utilizzare questa strategia sulle etichette perimetrali, poiché ciò causerà un gran numero di predicati e avrà un impatto negativo sulle prestazioni di Neptune.

L'approccio basato sull'etichetta con prefisso presenta due svantaggi principali. Innanzitutto, è difficile eseguire domande che si estendano a tutti gli inquilini. Un esempio è una query che conta tutti i nodi di una determinata etichetta per il reporting o il monitoraggio. Se questo è il tuo caso d'uso, valuta la possibilità di combinare questa strategia con la strategia a più etichette. Per ulteriori informazioni sulla combinazione di strategie, consulta la sezione Modello ibrido.

In secondo luogo, la strategia prefix-label richiede controlli che impongano la corretta applicazione del prefisso appropriato a ogni query per prevenire la perdita di dati. Tuttavia, questa strategia è l'opzione più efficiente per i carichi di lavoro che richiedono query a bassa latenza e la consigliamo vivamente. La sezione Implicazioni prestazionali per i modelli GPL fornisce esempi del motivo per cui questa è la strategia più efficiente.

Strategia a etichetta multipla

La terza opzione consiste nell'utilizzare una strategia a più etichette. Per questo approccio, aggiungi etichette aggiuntive a ogni nodo del grafico. Ad esempio, se devi filtrare tutti i dati di un determinato inquilino, aggiungi l'etichetta ID del tenant. Se devi filtrare tutti i dati per una determinata etichetta indipendentemente dal tenant, aggiungi quell'etichetta. Il diagramma seguente mostra la strategia a più etichette applicata utilizzando tre etichette per ogni nodo.

È ora possibile accedere al grafico utilizzando tre diversi modelli:

Nodi e relative relazioni, in cui ogni nodo ha labelX, X, X-labelX.
  • Attiva il filtro Label1 per restituire tutti i nodi con tutti i tenant. Label1

  • Filtra 1 per restituire tutti i nodi per il tenant 1.

  • Filtra 1-Label1 per restituire tutti i nodi solo per il tenant 1 con etichetta. Label1

Infatti LPGs, ci sono due modi per implementarlo.

In Gremlin, è possibile utilizzare la strategia di attraversamento chiamata SubgraphStrategya limitare l'ambito di tutte le query ai soli vertici con un'etichetta specifica, ad esempio: "Label1"

g.withStrategies( new SubgraphStrategy( vertices=hasLabel("Label1") ) )

Al contrario PartitionStrategy, SubgraphStrategy influisce solo sulla lettura dei dati, non sulla scrittura dei dati. Per scrivere i dati, assegna manualmente le etichette in ogni query:

g.addV("Label1").property("Value","XYZ123456") .addV("Label2").property("Value","XYZ123456")

Durante la lettura dei dati, puoi utilizzarli SubgraphStrategy per interrogare tutti i nodi con"Label1":

g.withStrategies( new SubgraphStrategy(vertices=.hasLabel("Label1")) ). V().has("Value","XYZ123456")

Neptune restituisce solo il primo record, che "Label1" ha un valore di. "XYZ123456" È equivalente alla seguente query, che non utilizza: SubgraphStrategy

g.V().hasLabel("Label1").hasValue("XYZ123456")

In questa query di base, sembra che SubgraphStrategy sia più complessa da usare. Tieni presente che le tue librerie possono fornire un'gistanza della strategia già definita. Gli sviluppatori non devono assicurarsi che vengano applicati i filtri corretti:

def getGraphTraversal(): return g.withStrategies(new SubgraphStrategy(vertices=.hasLabel("Label1")) getGraphTraversal().has("Value","XYZ123456")

Le librerie OpenCypher non hanno questi costrutti, quindi è necessario creare più etichette per ogni nodo:

CREATE (n:`1`:`Label1`:`1-Label1` {`~id`: 'Item_1', Value: '12345'})

Quando usi queste etichette per filtrare un sottografo, puoi restituire nodi che hanno l'etichetta cliente che stai cercando o che condividono una relazione con un altro nodo che ha quell'etichetta:

MATCH n=(:Label1:`1`) // or MATCH n=(:`1-Label1`)

La strategia a etichette multiple offre la massima flessibilità per interrogare i nodi per tipo (Label1) o tenant (1) o per utilizzare la strategia più efficiente di etichetta con prefisso quando le prestazioni sono della massima importanza (). 1-Label1

Lo svantaggio principale di questa strategia è che ogni etichetta è un oggetto aggiuntivo memorizzato nel grafico. Un oggetto è un nodo, un bordo o una proprietà su un nodo o un bordo interno LPGs. La velocità di inserimento viene misurata e limitata in base agli oggetti al secondo e i costi di archiviazione dipendono dal numero di gigabyte consumati. Ciò significa che oggetti aggiuntivi potrebbero avere un impatto misurabile su larga scala.

Implicazioni prestazionali per i modelli GPL

Il corso AWS Skill Builder Data Modeling for Amazon Neptune descrive in modo approfondito gli interni del modello di dati Neptune e le implicazioni della modellazione, ma riassumeremo le considerazioni importanti per questi progetti qui. Prendi in considerazione l'idea di avere tre inquilini (T1, T2, T3) su un singolo cluster Neptune. Questi inquilini hanno le seguenti caratteristiche:

  • Il tenant 1 (T1) ha un totale di 100 milioni di nodi e 10 milioni sono di tipo Item.

  • Il tenant 2 (T2) ha un totale di 10 milioni di nodi e 1 milione sono di tipo Item.

  • Il Tenant 3 (T3) ha un totale di 100 milioni di nodi e 1 milione sono di tipo Item.

Esegui una query che recupererà gli elementi per Tenant 3 utilizzando la strategia di proprietà. Neptune esamina le statistiche relative a due chiamate di indice:

  • Dove tenant property key=T3 ha 100 milioni di risultati

  • Dove label = Item ha 12 milioni di risultati (10 milioni da T1 + 1 milione da T2 + 1 milione da T3)

L'ottimizzatore di query Neptune determina che è meglio applicare prima quest'ultima query (12 milioni di risultati) e quindi ispeziona ogni elemento. tenant property key=T3 Recuperate 12 milioni di elementi per trovare 1 milione di risultati.

Notate l'impatto di questa interrogazione sui rumorosi vicini. Se si disponesse di 100 milioni di nodi Item per tenant, la prima query genererebbe 300 milioni di risultati anziché 12 milioni (questa impostazione è eccessivamente semplificata a scopo illustrativo. L'ottimizzatore Neptune potrebbe aver applicato un ordine di operazioni diverso).

Consideriamo quindi la strategia prefix-label. Effettua una singola chiamata di indice wherelabel=T3-Item, che restituisce 1 milione di risultati. Ciò consente di ottenere lo stesso risultato della strategia immobiliare, ma recupera 11 milioni di record in meno. Inoltre, non dovrete più preoccuparvi dei rumorosi vicini, perché l'etichetta non si sovrappone all'indice.

La strategia a più etichette non migliora direttamente le prestazioni delle query rispetto alla strategia basata sulle proprietà. Il filtraggio in base al valore della proprietà è paragonabile al filtraggio in base al valore dell'etichetta quando anche lo spazio di ricerca è comparabile. Invece, la strategia a più etichette supporta una maggiore flessibilità.  La strategia a più etichette offre prestazioni equivalenti alla strategia di etichetta con prefisso per o per l'etichetta. label=T3 T3-Item La strategia a più etichette offre prestazioni equivalenti alla strategia di proprietà per. label=Item Il vantaggio consiste nel supportare una varietà di modelli di accesso.