Quali sono le migliori pratiche per la memorizzazione nella cache dei risultati impaginati i cui ordini / proprietà possono cambiare?


11

Qual è la migliore pratica per la memorizzazione nella cache dei risultati di ricerca impaginati i cui ordini / proprietà possono essere modificati?

Supponiamo che nella mia domanda qualcuno voglia vedere gli ultimi 20 thread di discussione (su 10.000). Una richiesta verrebbe inviata al database, tramite servlet, per recuperare i primi 20 record dalla tabella dei thread di discussione come XML / JSON. Se poi vogliono vedere i prossimi 20, passano alla pagina successiva dei risultati e questo fa scattare un'altra richiesta per ottenere il lotto successivo (limite e offset = 20, ecc.).

Al fine di ridurre il carico del server e l'attesa del client, vorrei memorizzare nella cache le pagine precedenti dei risultati. Tuttavia, ho due domande:

  1. La tabella in cui sono mostrati i risultati può essere ordinata da più di un attributo (ad esempio, data-creazione-thread, autore-thread, last-post-date). Ciò significa che un'affermazione come "primi 20 risultati" non ha senso senza contesto (cioè, da cosa stiamo ordinando). In che modo il front-end, quindi, comunica al back-end ciò che ha già caricato? Il mio primo pensiero è stato quello di utilizzare gli ID per ogni risultato, ma rispedirli al server su richieste successive (e filtrare i risultati in base a essi) richiederebbe tanto tempo quanto restituire alla cieca tutto. Come posso fare questo?
  2. Cosa succede se un attributo di un risultato restituito in precedenza (ovvero la data più recente post-data) è cambiato? Abbiamo quindi bisogno di un modo per controllare ogni risultato per vedere se è stato modificato sul lato server da quando è stato effettuato il paging. Come posso farlo?

Il tuo esempio è un po 'approssimativo. Se sono solo 100 thread, è meglio scaricare tutti i 100 in una volta sola. Se ne stai prendendo 20 su 10.000, questa è una storia diversa.
Dan Pichelman,

@DanPichelman Mi dispiace, ero un po 'poco chiaro. Sarebbe più simile a 10.000.
goodsquishy,

Numero modificato per chiarezza.
goodsquishy,

Questo http è? In tal caso, perché non limitarsi a memorizzare nella cache in base all'URL? Avere tutti i parametri nell'URL. Se è un browser, prova a utilizzare la cache del browser. Se è un'app, imposta una scadenza cache. Volley di Android funziona abbastanza bene.
frostymarvelous

Risposte:


7

Sembra che quello che vi serve è un wrapper per tutti i parametri che definiscono una pagina (per esempio, pageNumber, pageSize, sortType, totalCount, ecc) e utilizzare questo DataRequestoggetto come la chiave per il meccanismo di caching. Da questo punto hai una serie di opzioni per gestire la cache:

  • Implementare una sorta di meccanismo di timeout per aggiornare la cache (in base alla frequenza con cui i dati cambiano).
  • Avere un listener che controlla le modifiche al database e aggiorna la cache in base ai parametri precedenti.
  • Se le modifiche vengono eseguite con lo stesso processo, puoi sempre contrassegnare la cache come obsoleta ad ogni modifica e controllare questo flag quando viene richiesta una pagina.

I primi due potrebbero comportare un meccanismo di pianificazione per attivarsi su un intervallo o sulla base di un evento. L'ultimo potrebbe essere il più semplice se si dispone di un singolo punto di accesso ai dati.

Infine, come menzionato da @DanPichelman, può rapidamente diventare un algoritmo troppo complicato che supera i vantaggi, quindi assicurati che il guadagno in termini di prestazioni giustifichi la complessità dell'algoritmo.


3

Probabilmente lo gestirò così:

  1. Tratta ordinamenti diversi come sequenze diverse tutti insieme. Non varrà la pena tenere la contabilità extra per tenere traccia di ciò che ogni cliente ha (o rispedirlo più e più volte).
  2. Ogni volta che le pagine utente vengono visualizzate immediatamente dalla cache, inviando contemporaneamente un GET al server che include un hash o un ultimo accesso. Il server restituisce una pagina intera solo se qualcosa è cambiato.
  3. Recupera dal server più di una pagina UI alla volta. Ad esempio, se l'interfaccia utente visualizza 20 voci, esegui una query 60. Devo testare questo, ma la mia aspettativa è che la dimensione di ritorno più efficiente sarà in genere maggiore della quantità media di dati mostrati su una pagina. Ciò rende l'interfaccia utente molto reattiva per alcune svolte di pagina.
  4. Il prefetch restituisce quando ci si avvicina a un limite. Questo aiuta a preservare i tempi di caricamento rapidi dalla cache.

2

Solo un pensiero: nella tua chiamata al server, passa i soliti parametri più una matrice di hash MD5 che rappresentano le pagine di dati precedentemente memorizzate nella cache.

La chiamata di ritorno conterrebbe tutti i soliti dati per la nuova pagina corrente, oltre agli aggiornamenti per eventuali pagine obsolete visualizzate in precedenza. Puoi usare il vecchio hash come chiave.

Consiglierei prima molti test prestazionali e di tempismo: il tuo codice lato client sarà molto più complicato di quanto sarebbe se colpissi semplicemente il server per ogni pagina di dati. Assicurati che la complessità extra si traduca in un miglioramento significativo.


Grazie per la tua risposta. Stavo pensando di eseguire l'hashing, ma non ero sicuro che potesse essere utile per lo scenario di riordino (ovvero, non è abbastanza granulare e funziona solo per pagina, non per risultato). Penso che il tuo ultimo paragrafo sia un buon punto e sto iniziando a pensare che la complessità di ogni possibile soluzione superi i vantaggi in termini di prestazioni.
goodsquishy,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.