Gremlin: OLAP vs divisione della query

Oct 06 2020

Ho una query (collegamento sotto) che devo eseguire una volta al giorno o una volta alla settimana nella mia applicazione per trovare gruppi di utenti connessi. Nella query controllo tutti i possibili gruppi per ogni utente dell'applicazione (non tutti gli utenti vengono valutati ma potrebbero essere molti). Per il momento sto solo effettuando test delle prestazioni in localhost utilizzando Gremlin Server, poiché la mia applicazione non è ancora attiva.

Il problema è che quando si prova questa query simulando molti utenti, la query raggiunge il limite di tempo che una richiesta può richiedere configurato in Gremlin Server per impostazione predefinita, un altro problema è che la query non richiede l'utilizzo completo della CPU poiché sembra che sia stata progettata una singola query utilizzare in qualche modo un singolo thread o una quantità ridotta di elaborazione della CPU.

Quindi ho in mente 2 soluzioni, dividere la query in un blocco per utente o utilizzare OLAP:

Soluzione 1: inviare una query per ottenere prima gli utenti, quindi inviare una query per utente, quindi rimuovere i duplicati nel codice del server, questo dovrebbe funzionare nel mio caso e poiché posso inviare tutte le query contemporaneamente posso utilizzare tutte le risorse disponibile e aggirare i limiti di tempo.

Soluzione 2: utilizzare OLAP. Immagino che OLAP non abbia un limite di tempo. Il problema: la mia idea è di utilizzare Amazon Neptune e OLAP non è supportato lì per quanto ne so. In questa domanda a riguardo: query OLAP di Gremlin su AWS Neptune

David dice: Aggiornamento: da GA (giugno 2018), Neptune supporta più query in una singola richiesta / transazione

Cosa significa "più query in una singola richiesta"?

Qual è il confronto tra la mia soluzione 1 e OLAP?

Devo cercare un altro servizio di database che supporti OLAP invece di Nettuno? Quale potrebbe essere? Non voglio un'opzione che implichi imparare a configurare il mio server "simile a Nettuno", ho tempo limitato.

La mia domanda nel caso tu voglia dare un'occhiata: https://gremlify.com/69cb606uzaj

Risposte

1 stephenmallette Oct 07 2020 at 19:07

Questa è una domanda un po 'complicata.

Il problema è che quando si prova questa query simulando molti utenti, la query raggiunge il limite di tempo che una richiesta può richiedere che è configurato in Gremlin Server per impostazione predefinita,

Darò per scontato c'è una ragione per cui non è possibile modificare il valore predefinito, ma per coloro che potrebbero essere la lettura di questa risposta il timeout è configurabile sia a livello di server (con evaluationTimeoutin YAML del server ) e per richiesta sia per gli script e bytecode basandomi richieste.

un altro problema è che la query non richiede l'utilizzo completo della CPU poiché sembra che una singola query sia progettata per utilizzare un singolo thread o una quantità ridotta di elaborazione della CPU in qualche modo.

Se stai testando con TinkerGraph in Gremlin Server, sappi che TinkerGraph è davvero semplice. Non fa nulla internamente per eseguire alcun aspetto di un attraversamento in parallelo (senza TinkerGraphComputer che è correlato a OLAP).

Quindi ho in mente 2 soluzioni, dividere la query in un blocco per utente o utilizzare OLAP:

Entrambi gli approcci hanno il potenziale per funzionare. Nella prima soluzione suggerisci una forma di OLAP dei poveri in cui devi ideare i tuoi metodi per eseguire questa elaborazione parallela (ad esempio, gestire i pool di thread, sincronizzare lo stato, ecc.). Penso che questo approccio sia un primo passo comune che le persone intraprendono per affrontare questo tipo di problema. Mi chiedo se hai bisogno di una grana fine come un utente per richiesta. Penserei che l'invio di più messaggi alla volta sarebbe accettabile, ma solo il test nel tuo ambiente reale darebbe la risposta a questo. La cosa bella di questa soluzione è che normalmente funzionerà su qualsiasi sistema grafico, incluso Nettuno.

Usare la seconda soluzione con OLAP è più complicato. Hai l'ovvio problema che Neptune non lo supporta direttamente, ma rivolgersi a un fornitore diverso che lo fa non risolverà immediatamente il tuo problema. Mentre OLAP ti libera dal doverti preoccupare di come parallelizzare in modo ottimale il tuo carico di lavoro, ciò non significa che puoi prendere immediatamente quella query di Gremlin che desideri eseguire, lanciarla in Spark e ottenere una vittoria immediata. Ad esempio, e prendo questo dalla documentazione di riferimento di TinkerPop:

In OLAP, where the atomic unit of computing is the vertex and its local 
"star graph," it is important that the anonymous traversal does not leave the 
confines of the vertex’s star graph. In other words, it can not traverse to an 
adjacent vertex’s properties or edges.

Nella tua query, ci sono già punti in cui "lasci il grafico a stella" in modo da trovare immediatamente problemi da risolvere. Di solito questa limitazione può essere aggirata per scopi OLAP, ma non è così semplice come aggiungere withComputer()al tuo attraversamento e ottenere una vittoria in questo caso.

Scendendo ulteriormente lungo questo percorso di utilizzo di OLAP con un grafico diverso da Nettuno, probabilmente vorrai almeno considerare se questo attraversamento complesso potrebbe essere meglio scritto come un'abitudineVertexProgram che potrebbe legare meglio il tuo caso d'uso alle capacità di BSP rispetto a quello che il più generico TraversalVertexProgramquando si elabora Gremlin arbitrario. Del resto, un mix di Gremlin OLAP, VertexProgramun'elaborazione di stile mappa / riduzione personalizzata e alcuni standard potrebbe portare alla risposta più elegante ed efficiente.

Un'idea che ho preso in considerazione per i grafici che non supportano OLAP è stata quella di subgraph()(con Java) la parte del grafico che è rilevante per il tuo algoritmo e quindi eseguirlo localmente in TinkerGraph! Penso che potrebbe avere senso in alcuni casi d'uso in cui l'algoritmo ha alcuni limiti che possono essere definiti in anticipo per formare il sottografo, dove quei limiti possono essere facilmente filtrati e dove il sottografo risultante non è così grande da richiedere una quantità oscena di tempo per costruire. Sarebbe anche meglio se il sottografo avesse qualche utilità oltre un singolo algoritmo, comportandosi quasi come un grafico della cache. Non ho idea se ti sia utile ma è un pensiero. Ecco un recente post sul blog che ho scritto che parla della scrittura di VertexPrograms . Forse lo troverai interessante.

Tutto ciò che è stato detto su OLAP, penso che la tua prima soluzione sembri a posto. Non hai ancora un edge graph multimiliardario e probabilmente puoi permetterti di adottare questo approccio per ora.

Cosa significa "più query in una singola richiesta"?

Credo che questo significhi solo che puoi inviare uno script come:

g.addV().iterate()
g.addV().iterate()
g.V()

dove più comandi Gremlin possono essere eseguiti nell'ambito di una singola transazione in cui ogni comando deve essere "separato da una nuova riga ('\ n'), spazi (''), punto e virgola (';') o niente (ad esempio: g .addV ('person'). next () gV () is valid) ". Penso che solo l'ultimo comando restituisca un valore. Non sembra che quella particolare funzionalità sarebbe utile nel tuo caso. Vorrei guardare di più agli utenti batch all'interno di una particolare richiesta, ove possibile.

SeanMartin Oct 22 2020 at 01:57

Se stai cercando un motore grafico OLAP nativo, forse dai un'occhiata ad AnzoGraphDB che si ridimensiona e si comporta molto meglio per quello stile di query più complesso di qualsiasi altra cosa sappiamo. È un motore MPP, quindi ogni core lavora sulla query in parallelo. A seconda di quanti dati hai bisogno per agire, la versione gratuita (solo nodo singolo, RAM limitata) potrebbe essere tutto ciò di cui hai bisogno e può essere utilizzata commercialmente. Puoi trovarlo nel Marketplace AWS o su Docker Hub.

Dichiarazione di non responsabilità: lavoro per Cambridge Semantics Inc.