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.
- 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).
- 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.