Qual è il modo migliore per memorizzare nella cache una tabella di database in crescita per la generazione html?

4

Ho una tabella di database che aumenterà di dimensioni di circa 5000 righe all'ora. Per una chiave che vorrei interrogare, la query aumenterà di dimensioni di circa 1 riga ogni ora. Vorrei una pagina web per mostrare le ultime righe per una chiave, 50 alla volta (questo è configurabile). Vorrei provare e implementare memcache per mantenere l'attività del database bassa per le letture.

Se eseguo una query e creo un risultato cache per ogni pagina di 50 risultati, ciò funzionerebbe finché non verrà aggiunta una nuova voce. A quel tempo, la pagina dei risultati più recenti ottiene un nuovo risultato e i risultati più vecchi si riducono. Questo scende verso il basso l'elenco delle pagine memorizzate nella cache che mi inducono ad aggiornare ogni risultato della cache. Sembra un design scadente.

Potrei creare le pagine della cache all'indietro, quindi per ogni pagina richiesta dovrei ottenere le ultime 2 pagine e troncare alla lunghezza corretta di 50. Non sono sicuro che sia buono o cattivo?

Idealmente, il meccanismo che uso per inserire una nuova riga saprebbe anche come invalidare i risultati della cache corretti.

Qualcuno ha già risolto questo problema in modo ampiamente accettabile? Qual è il miglior metodo per farlo?

EDIT:

Se la mia comprensione della cache di query di MYSQL è corretta, ha granularità a livello di tabella in invalidazione . Dato che ho circa 5000 aggiornamenti prima che una query su una chiave debba essere invalidata, sembra che la cache delle query del database non venga utilizzata. MS SQL memorizza nella cache i piani di esecuzione e le pagine di dati a cui si accede frequentemente, quindi potrebbe fare meglio in questo scenario.

La mia query non è contro una singola tabella con TOP N. Una versione ha join a diverse tabelle e un'altra ha sottoseleziona.

Inoltre, poiché voglio memorizzare nella cache la tabella generata in html, mi chiedo se una cache a livello di server Web sia appropriata? Non c'è davvero alcun beneficio per nessun tipo di memorizzazione nella cache? Il miglior consiglio è proprio quello di consentire a una query del sito Web di passare attraverso tutti i livelli e di colpire il database ogni richiesta?

    
posta McLeopold 24.05.2011 - 00:10
fonte

4 risposte

9

A meno che non abbia frainteso la domanda, non penso che questo sia uno scenario appropriato per il caching.

I dati memorizzati nella cache normalmente hanno almeno uno dei seguenti attributi (in genere tutti):

  • Costoso da recuperare o calcolare;
  • Molto statico - può cambiare occasionalmente ma molto raramente;
  • Non critico - OK se il richiedente vede dati non aggiornati.

Non sembra che qualsiasi di questi si applichi alla tua situazione.

  • La query è un semplice SELECT , probabilmente TOP N , solo un indice di ricerca;
  • Cambia molto frequentemente;
  • I tuoi requisiti indicano che sono richiesti aggiornamenti immediati.

Quindi perché stai memorizzando nella cache? Il caching non è una panacea; spesso può peggiorare le prestazioni, se la memoria cache può essere utilizzata meglio per altri scopi.

I database fanno il loro caching. Finché il server DB ha un sacco di memoria, può memorizzare l'intera tabella in memoria se viene frequentemente interrogata; le prestazioni di questo saranno altrettanto buone quanto la cache se non migliori.

Altre idee / suggerimenti:

  • Se i dati obsoleti sono OK, la soluzione più semplice sarebbe quella di utilizzare un intervallo fisso (ad esempio la scadenza). Questo metodo è usato molto efficacemente in centinaia di migliaia di siti e sistemi. Puoi forzare un aggiornamento alla scadenza o aspettare fino a quando non viene richiesto nuovamente.

  • Se sei preoccupato dei conflitti tra letture e scritture, allora (a) non lo fare, finché non lo hai profilato e (b) se è davvero un problema, allora invece di provare a nasconderlo utilizza solo una tabella ridondante o un suggerimento NOLOCK .

Se hai bisogno di invalidare la cache ogni volta che una riga viene aggiunta / modificata, hai completamente annullato lo scopo di una cache dell'applicazione e ora stai cercando di implementare un database in memoria. Per favore, non farlo a meno che tu non abbia una buona ragione per farlo.

    
risposta data 24.05.2011 - 01:06
fonte
3

Il volume delle righe con cui hai a che fare è molto basso, meno di 10.000 all'anno.

L'implementazione di un meccanismo di memorizzazione nella cache per questo complicherebbe eccessivamente qualcosa che il database può fare molto rapidamente e facilmente, specialmente con gli indici corretti.

C'è una ragione specifica per cui stai cercando di implementare memcache per questo scenario?

La cache di query incorporata di MySQL funzionerà correttamente qui. Poiché la tua tabella non cambia molto spesso memorizzerà i tuoi risultati in cache in modo appropriato e ridurrà comunque l'attività di lettura del database.

Nota: ho assunto MySQL poiché è lì che di solito vedo implementato memcache:)

Modifica Sulla base dei dettagli aggiornati, suggerirei comunque di andare con una soluzione di database diritta. Il carico sul database per la sola lettura diventa davvero un problema in ambienti con volumi elevati. Una buona indicizzazione e l'ottimizzazione delle query di solito forniscono buone prestazioni in molti ambienti.

Se hai bisogno di prendere il percorso memcache, ti suggerirei di non provare a gestire le pagine nella cache in modo microscopico.

Ogni inserto può controllare memcache - se l'inserto introduce la nuova voce per la chiave (che hai detto succedere una volta ogni ora) allora dovrebbe invalidare l'intera cache relativa a quella tabella.

Quando qualcuno richiede una pagina dei risultati, controlla memcache. Se i risultati per quella pagina sono già lì, usali. In caso contrario, eseguire una query specifica per ottenere solo quella pagina, memorizzare nella cache i dettagli della pagina in memcache e restituire i risultati.

Con questo approccio, la gestione della cache è semplice e si rigenera la pagina della cache solo la prima volta che viene richiesta dopo una invalidazione. Le seguenti richieste useranno la cache fino alla successiva invalidazione. Questo approccio significherà anche solo i dati di memorizzazione nella cache per le pagine effettivamente richieste.

    
risposta data 24.05.2011 - 00:19
fonte
2

Utilizza la cache del database

Gestirà questo volume basso con facilità. Basta usare la seguente query:

select top 50 from your_view
    
risposta data 24.05.2011 - 00:21
fonte
1

Un altro trucco che funziona in molti database è un indice composito. Di solito gli indici compositi funzionano bene se la query viene eseguita nello stesso ordine dell'ordine delle colonne nell'indice. Nel tuo caso, l'indice sarebbe acceso.

In questo modo, l'indice è costruito come (key1, row1) (key1, row2) (key2, row3) (key2, row5) (key3, row6) e così via. L'indice lo troverà molto facile da interrogare in base alla chiave del prefisso qui - e l'ultimo / ultimo elemento di recupero sarebbe rapido come un lampo. Se segui questa strada, assicurati che il tuo db stia effettivamente scegliendo questo indice composito per questa query top.

    
risposta data 24.05.2011 - 01:25
fonte

Leggi altre domande sui tag