Quais são as práticas recomendadas para armazenar em cache os resultados paginados cuja ordem / propriedades podem ser alteradas?

11

Qual é a melhor prática para armazenar em cache os resultados da pesquisa paginada cujas ordens / propriedades podem ser alteradas?

Digamos que, no meu aplicativo, alguém queira ver os últimos 20 tópicos de discussão (de 10.000). Uma solicitação seria enviada ao banco de dados, via servlet, para buscar os 20 primeiros registros da tabela de threads de discussão como XML / JSON. Se eles querem ver os próximos 20, vão para a próxima página de resultados e isso dispara outra solicitação para obter o próximo lote (limite e deslocamento = 20, etc.).

Para reduzir a carga do servidor e a espera do cliente, gostaria de armazenar em cache as páginas anteriores dos resultados. No entanto, tenho duas perguntas:

  1. A tabela na qual os resultados são mostrados pode ser ordenada por mais de um atributo (por exemplo, data de criação do encadeamento, autor do encadeamento, data do último post). Isso significa que uma declaração como 'primeiros 20 resultados' não faz sentido sem contexto (ou seja, pelo que estamos ordenando). Como o front-end, então, comunica ao back-end o que ele já carregou? Meu primeiro pensamento foi usar IDs para cada resultado, mas enviá-los de volta ao servidor em solicitações subsequentes (e filtrar os resultados com base neles) consumiria tanto tempo quanto enviar tudo de volta às cegas. Como posso fazer isso?
  2. E se um atributo de um resultado retornado anteriormente (ou seja, a data posterior mais recente) for alterado? Precisamos então de uma maneira de verificar cada resultado para ver se ele foi modificado no lado do servidor desde que foi paginado. Como posso fazer isso?
goodsquishy
fonte
Seu exemplo é um pouco difícil. Se tiver apenas 100 threads, é melhor baixar todos os 100 de uma só vez. Se você está obtendo 20 de 10.000, é uma história diferente.
22613 Dan Pichelman
@ DanPichelman Desculpe, eu estava um pouco confuso. Seria mais do que 10.000.
goodsquishy
Número editado para maior clareza.
goodsquishy
É este http? Se for, por que não apenas armazenar em cache com base no URL? Tem todos os parâmetros no URL. Se for um navegador, tente utilizar o cache do navegador. Se for um aplicativo, defina uma expiração de cache. O Volley do Android funciona muito bem.
Frostymarvelous 19/03

Respostas:

7

Parece que você precisa é um wrapper para todos os parâmetros que definem uma página (por exemplo, pageNumber, pageSize, sortType, totalCount, etc.) e usam esse DataRequestobjeto como a chave para o seu mecanismo de cache. A partir deste ponto, você tem várias opções para lidar com o cache:

  • Implemente algum tipo de mecanismo de tempo limite para atualizar o cache (com base na frequência com que os dados são alterados).
  • Tenha um ouvinte que verifique as alterações no banco de dados e atualize o cache com base nos parâmetros acima.
  • Se as alterações forem feitas pelo mesmo processo, você sempre poderá marcar o cache como desatualizado a cada alteração e marcar esse sinalizador quando uma página for solicitada.

Os dois primeiros podem envolver um mecanismo do planejador para disparar em algum intervalo ou com base em um evento. O último pode ser o mais simples se você tiver um único ponto de acesso a dados.

Por fim, como o @DanPichelman mencionou, ele pode rapidamente se tornar um algoritmo muito complicado que supera os benefícios, portanto, verifique se o ganho no desempenho justifica a complexidade do algoritmo.

rae1
fonte
3

Eu provavelmente lidaria com isso assim:

  1. Trate pedidos diferentes como seqüências diferentes todos juntos. Não valerá a pena a contabilidade extra para rastrear o que cada cliente possui (ou enviá-lo repetidamente).
  2. Sempre que as páginas do usuário, exibem imediatamente do cache e, ao mesmo tempo, enviam um GET ao servidor que inclui um hash ou um último horário de acesso. O servidor envia de volta uma página inteira apenas se algo mudou.
  3. Recupere do servidor mais de uma página da interface do usuário por vez. Por exemplo, se sua interface do usuário exibir 20 entradas, consulta 60. Preciso testar essa, mas minha expectativa é que o tamanho de retorno mais eficiente seja geralmente maior que a quantidade média de dados mostrados em uma página. Isso também torna a interface do usuário muito responsiva para algumas viradas de página.
  4. Pré-buscar reslts quando você estiver próximo de um limite. Isso ajuda a preservar esses tempos de carregamento rápidos do cache.
Chris Pitman
fonte
2

Apenas um pensamento - na chamada do servidor, transmita os parâmetros usuais mais uma matriz de hashes MD5 que representam páginas de dados visualizadas anteriormente em cache no momento.

A chamada de retorno conteria todos os dados habituais para a nova página atual, além de atualizações para quaisquer páginas desatualizadas visualizadas anteriormente. Você pode usar o hash antigo como chave.

Eu recomendaria muitos testes de desempenho e tempo primeiro - o código do lado do cliente será muito mais complicado do que seria se você simplesmente acessasse o servidor para cada página de dados. Verifique se a complexidade extra resulta em uma melhoria significativa.

Dan Pichelman
fonte
Obrigado pela sua resposta. Eu estava pensando em hash, mas não tenho certeza se isso ajudará no cenário de reordenamento (ou seja, não é granular o suficiente e funciona apenas por página, não por resultado). Acho que seu último parágrafo é um bom argumento e estou começando a pensar que a complexidade de qualquer solução possível superaria os benefícios de desempenho.
goodsquishy