Paginação com cache progressivo
O que é Cache? O armazenamento em cache é a técnica de armazenar cópias de dados de aplicativos usados com frequência em uma camada de memória menor e mais rápida para melhorar os tempos de recuperação de dados e o rendimento.
O que é Paginação? A paginação é o processo de separação de dados em conjuntos, assim como as páginas de um livro. Uma solicitação de API GET para solicitar informações de um servidor por meio de um terminal de API para grandes bancos de dados pode gerar milhões, senão bilhões, de resultados. A resposta da API que nos envia milhares de entradas de uma só vez é um desperdício de recursos. A paginação ajuda a dimensionar nosso aplicativo, atender mais usuários, fazer consultas eficientes e criar uma boa experiência do consumidor.
Vamos considerar um cenário: Você recebe uma tarefa para desenvolver um serviço. Isso terá pontos de extremidade servindo registros de diferentes tabelas de banco de dados. Por enquanto, vamos considerar que você começa com um endpoint que atende a partir da tabela de produtos do seu banco de dados. A API oferece suporte a alguns parâmetros de filtro. Digamos PriceRange, Manufacturer, etc. Considerando que existem mais de 5 milhões de produtos em seu banco de dados. E seus fornecedores continuam adicionando mais produtos ao banco de dados.
Pensamentos iniciais: Pode-se pensar em criar uma consulta de banco de dados no recurso da API e no parâmetro de filtro e executá-la em pushdown no banco de dados, ler todos os registros filtrados, armazená-los em algum cache e fornecer respostas paginadas do cache para solicitações subsequentes.
Imagine se o resultado da consulta retornasse 2 milhões de registros. Você armazenará em cache (2 milhões — pageSize) registros? Além disso, o tempo de resposta da primeira solicitação será enorme. Como você está carregando todos os 2 milhões de registros de uma só vez, independentemente do tamanho da página. E quando invalidar o cache. Já está armazenando uma grande quantidade de dados.
Minha abordagem usando cache progressivo
Bob vai comprar pão Naan no restaurante mais próximo. Ele observa que há duas pessoas perto de um forno. Um deles é moldar o chão em pão Naan. Outro sob demanda coloca aqueles pães de forma no Forno e serve o pedido. Ele observa que a pessoa no Forno espera alguns segundos em caso de qualquer outro pedido e se inclina para trás caso contrário.
Você entendeu certo? Trabalhe sob demanda, faça uma pausa por um tempo, descarte o contrário. Foi exatamente assim que resolvi esse problema. Agora vamos mapear isso em nosso cenário.
Cache Progressivo:
Nossa chave de cache é GUID. Isso será usado aqui como um parâmetro de cursor para nossa paginação. O valor é o leitor pausado. Podemos implementar um cache usando o cache LRU. Além disso, um cronômetro adicional que marca a cada 8 segundos (pode ser configurado pelo usuário) descarta o leitor usado menos recentemente. Portanto, não mantemos conexões de banco de dados abertas por muito tempo.
public interface ICache
{
void Add(Guid Key,IReader reader);
IReader Get(Guid Key);
void DisposeUnwanted();
}
Primeiro Pedido
Example request: https://localhost:9261/Products?Price=100&Manufacturer=HP
//Converted Query for our example request.
SELECT * FROM products WHERE Price = 100 AND Manufacturer Like 'HP'
Etapa 3: Pause o leitor, gere o GUID e armazene-o em cache.
Etapa 4: adicione o GUID gerado como cursor para a próxima página no corpo da resposta JSON.
Solicitações subsequentes
Example request: https://localhost:9261/Products?Price=100&Manufacturer=HP&Cursor=GUID
Etapa 2: retome o leitor e leia o registro até sua contagem limite.
Passos 3 e 4: Igual ao primeiro pedido.
Complexidade de tempo: O(limite), onde o limite é o tamanho da página de resposta.
Prós:
- Sem carregamento preguiçoso.
- Uso eficiente de recursos.
- Tempo de resposta constante.
- Sem consultas complexas. O que você precisa entender se fizer pushdown do parâmetro do cursor.
- Não é possível ler registros anteriores. Mas isso não é possível usando a paginação do cursor por definição.
Sim, a vida é fácil, se você pode codificá-la.
Esse modelo de cache progressivo pode se adequar a outras fontes de dados, como arquivos, documentos. (Precisamos de um processador de expressão separado para a cláusula where, pois não podemos fazer push down em arquivos). Ele também se encaixa eficientemente em seus diferentes esquemas de tabela de banco de dados sem se preocupar muito com sua estrutura.
O modelo funcionou perfeitamente para mim. Já vi pessoas presas em uma situação semelhante no Stack Overflow e usando carregamento lento ou alguma implementação de terceiros com sobrecarga extra em vez de uma solução simples. A abordagem compartilhada é minha. Portanto, pode se adequar ao seu caso de uso. Por favor, compartilhe suas abordagens nos comentários.
E se você gostou deste artigo, clique no botão de palmas abaixo . Significa muito para mim e ajuda outras pessoas a verem a história.
~Sooraj Kumar
Engenheiro de Software Sênior @ Astera Software





































![O que é uma lista vinculada, afinal? [Parte 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)