caching su più server

4

Poiché abbiamo bisogno di mantenere bassi i tempi di risposta, riceviamo tonnellate di richieste e dobbiamo essenzialmente elaborare ALMOST gli stessi dati (che chiamerò X) ogni richiesta (gli input sono diversi però, quindi possiamo t cache responses), stiamo usando una tecnica in cui prendiamo una nuova copia di X ogni 90 secondi dal database e la memorizziamo localmente in memoria come un elenco python di dizionari, sui nostri server delle applicazioni (stiamo usando uwsgi).

Il nodo nella macchina: ci sono analisi temporanee di cui dobbiamo tenere traccia in questi 90 secondi per regolare i nostri dati ogni iterazione, e ogni iterazione dipende da ciò che calcoliamo dall'ultima iterazione.

Il problema è che abbiamo più server di applicazioni che memorizzano gli stessi dati, X, in memoria e ognuno di questi server ha bisogno di aggiornare X allo stesso tempo per mantenere i calcoli coerenti per l'intervallo successivo. Ho provato alcune tecniche, come trasmettere un messaggio dopo ogni calcolo per ricaricare la X di ogni server, ma non è stato così efficace come spero, e rende le cose più complicate.

Dovrei dire, il motivo per cui non abbiamo usato memcached o qualcosa di simile è perché non vogliamo sacrificare alcuna velocità se possiamo. Forse sono ignorante su quanto velocemente possiamo recuperare e caricare la lista in oggetti python da memcached.

Capisco che la mia spiegazione non sia la più grande e risponderò a qualsiasi domanda per dare un quadro migliore della situazione.

Modifica: siamo a circa 5000 richieste al secondo, la dimensione dei dati che elaboriamo è di circa 2 MB al momento, ma continuerà a crescere, quindi vorremmo evitare di inviarlo via cavo per ogni richiesta.

    
posta tonyl7126 16.04.2013 - 19:47
fonte

2 risposte

2

La tua domanda è interessante, pensata per dare una risposta rapida ma è più complicata.

Hai una serie di dati (per favore fornisci le dimensioni e l'indicazione delle richieste!). Dovrebbe essere uguale a tutte le macchine in un dato momento. Questo è interessante perché rende i sistemi distribuiti meno completi. Si arriva a un sistema basato su più transazioni in cui ci si può davvero fidare dei dati.

dichiari che è un requisito (e così importante).

La prima cosa che ti garantisco è: ho davvero bisogno di distribuire questi dati? Se si utilizza una memoria centrale, non si hanno affatto tutti i problemi di sincronizzazione e di replica. Quindi se non ci sono problemi non devi risolverlo. (In questo caso l'hardware potrebbe essere una soluzione molto più economica).

E presumo in base alla tua storia che non ci sia alcun motivo. Perché? Perché è possibile ottenere ogni "secondo" dati ogni 90 secondi. Potresti farlo anche su una trasmissione. Quindi la tua memoria centrale sembra essere in grado di fornire quell'istante.

Anche se hai più server così sembra necessario. Ora memorizzano i dati, eseguono i calcoli, si reimpostano sui nuovi dati e ricominciano a funzionare. Ciò significa che l'aspettativa è che il ritardo di risposta aumenterà significativamente quando chiedi i dati dalla tua memoria centrale invece del tuo dizionario Python locale.

Sembra ragionevole. Hai misurato questo? Sei proprio sicuro che non sia possibile? Veramente sicuro?

Ok, diciamo che è impossibile: devi avere un sistema distribuito che garantisca che i dati saranno sempre lì quando inizierai con una nuova sessione. Personalmente penso che dovresti dimenticarti di quel 90 sec. periodo comunque. Quindi, in tal caso, si ottengono soluzioni in tempo reale, quasi in tempo reale. Questo è possibile, ma penso che tu lo faccia diventare molto duro.

Generalmente tutte le soluzioni non-sql distribuite indeboliscono le garanzie per la sincronizzazione dei dati. Quindi trova una via d'uscita più semplice o crea il cluster quasi in tempo reale. Quelle sono le tue migliori scommesse.

    
risposta data 16.04.2013 - 20:04
fonte
-1

Penso che un buon approccio sarebbe quello di dividere il controllo dei dati e in effetti ottenerli. Perché? Memcache è davvero veloce ... Ma come hai spiegato, c'è una certa latenza a causa della grande quantità di dati che devi recuperare. Quindi adattiamo il tuo design a questo argomento.

Cioè, prova a imitare i metodi HEAD + GET di HTTP ...

Ogni server riceve un piccolo valore da memcache. Questo piccolo valore funge da HEAD, restituendo solo la data + ora in cui sono stati calcolati gli ultimi dati di 2 MB.

Se il server vede che è uguale alla propria copia, continua con la versione cache locale del blob 2 MB.

Quando i dati vengono ricalcolati, entrambi i dati da 2 MB e il minuscolo semaforo vengono aggiornati su memcache. Quindi, la prossima volta che un server riceve la piccola data, sa che i dati devono essere ricaricati nella sua cache locale.

    
risposta data 20.05.2013 - 23:09
fonte