Grafico BiPartite distribuito [chiuso]

1

Ho un caso d'uso in cui ho un grafico Bi-Partite. Chiama un tipo di nodo "Tipo A" e l'altro "Tipo B." Ora quando viene aggiunto un nodo di tipo A, forma alcuni bordi in base a un criterio con nodi di tipo B (di solito quanti bordi esistenti ha il nodo di tipo B?). I nodi di tipo A vengono aggiunti in modo coerente (ad esempio con ogni richiesta HTTP). Il criterio utilizzato è molto semplicistico in quanto la latenza della richiesta HTTP non può essere grande.

Dopo un intervallo di tempo X, un processo viene eseguito in background che acquisisce un'istantanea del grafico e "rimescola" i bordi in base a criteri più ottimali, il che richiede molto più tempo per essere eseguito. Ora, dopo averlo rimodellato, è necessario aggiornare i processi che servono le richieste HTTP al nuovo stato del grafico.

Ora succede in un ambiente distribuito. Diverse caselle stanno offrendo richieste HTTP.

  1. Come posso archiviare il grafico distribuito?

Un'opzione è quella di memorizzare i bordi e i nodi in Redis. Quindi, quando arriva una richiesta con un nodo di tipo A, devi prima recuperare tutti i nodi di tipo B (non saranno troppi), formare tutti i bordi e salvare nuovamente i bordi nei Redis. Il problema è che il vincolo è il numero di fronti che possono avere i nodi di tipo B. Quindi, se un nodo di tipo B aveva 4 spigoli e il limite è 5 e due richieste simultanee cercano di aggiungere un margine si deve fallire. L'unico modo in cui posso vederlo è

(1) Blocca i blocchi in Redis o

(2) Sharding del grafico in modo che un sottoinsieme di nodi di tipo B venga sempre recuperato da una casella (che non è ottimale).

  1. Come aggiorno il grafico distribuito dopo il ciclo ottimale?

Il ciclo ottimale acquisisce un'istantanea del grafico e ottimizza i bordi (rimpolpili). Ora questo richiede un po 'di tempo. Quindi durante questo periodo le richieste HTTP aggiungono anche nodi alla loro istantanea in Redis. Qual è il modo migliore per "unire" questi due grafici.

Un'opzione è successiva all'esecuzione del ciclo ottimale,

(1) imposta un flag per dire interrompere temporaneamente l'aggiunta di nuovi nodi nelle richieste HTTP (le richieste molto probabilmente bloccheranno o invieranno messaggi asincroni al chiamante in un secondo momento tramite Kafka / RabbitMQ)

(2) aggiunge tutti i nuovi nodi che erano stati aggiunti mentre era in esecuzione (se ci sono voluti 30 secondi per eseguire e c'era un nuovo nodo aggiunto ogni secondo, allora ha bisogno di contare per altri 30 nodi che non erano nella sua snapshot).

(3) Sostituisce i bordi del grafico in Redis.

(4) Annulla il flag per avviare nuovamente l'elaborazione delle richieste HTTP.

Tuttavia, questo processo causa un aumento della latenza delle richieste HTTP quando vengono bloccate dall'elaborazione, il che non è positivo.

    
posta dg428 24.11.2017 - 20:38
fonte

1 risposta

0

Non afferrare le serrature. Il tuo grafico deve essere sempre disponibile, per la lettura e per gli aggiornamenti.

Per eseguire il rimescolamento offline (30 secondi) è necessario un modo per dividere immediatamente il grafico in due copie. Cioè, arriva un web GET, poi lo dividi, poi arriva un secondo GET e non si noterà un insolito ritardo. Una tecnica tipica per farlo è COW, copia-su-scrittura .

Ora hai due grafici che divergono, uno è mutato dalle richieste web online e uno viene rimescolato. Le richieste Web vengono inoltre registrate sul lato.

Una volta completata la rimescolazione, riproduci tutte le richieste web registrate sul grafico rimescolato. Più richieste arriveranno durante questo, quindi tienilo fino alla fine della coda.

A questo punto puoi eliminare in sicurezza il grafico online e utilizzare il grafico di rimescolamento offline per le richieste online.

Per quanto riguarda il limite dei K edge per nodo, basta rilassarlo in K + 3 o 2K o qualcosa durante il rimpasto e sfoltire i bordi oltre K come passaggio finale prima di premere il grafico nel servizio online.

    
risposta data 25.11.2017 - 06:53
fonte