Cache + .NET: Cache de Objetos – // Rodolfo Fadino
rodolfo in ASP.NET | May 17, 2013 Cache + .NET: Cache de Objetos
Existem diversas técnicas e abordagem para melhorarmos a performance de nossas aplicações e sites. O Cache é uma excelente maneira de economizarmos recursos e melhorar a performance de nossas aplicações, basicamente técnicas de Cache consistem em manter uma versão daquele recurso em uma área de acesso rápido e otimizado (ex: memória).
Existe uma frase, que conheci através do Alexandre Tarifa e do Cleber Dantas:
"O código mais rápido é aquele que não é executado" (adaptação)
Pensando nisto decidi escrever uma série com 4 posts abordando as diversas camadas e técnicas para utilizar Cache com .NET e aplicações Web, vou abordar temas como: Cache de Objetos, OutputCache, Sistemas de Cache Distribuídos e Cache Http.
Neste primeiro post vou abordar o Cache de Objetos, que no caso do .NET consiste em manter objetos na memória do servidor, com um sistema de controle de validade, inserção, atualização, remoção e retorno dos objetos.
O Cache de objetos não contém nenhuma informação sobre o conteúdo dos itens que contem, ele funciona mantendo uma referencia para esses objetos, e fornece métodos para manipular, controlar suas dependências e definir politicas de expiração.
Nas versões anteriores ao .NET 4.0, o ASP.NET era quem provia a implementação do cache em memória, na namespace System.Web.Caching ou seja, antes do .NET 4.0 as aplicações eram dependentes do System.Web. A partir do .NET 4.0 temos uma namespace System.Runtime.Caching que contém a API para cache em aplicações web e não web.
Para este post, vamos utilizar o cache da classe System.Web.Caching.Cache. Uma instancia desta classe é criada por aplicação, e permanece valida enquanto aquela aplicação web permanece ativa. Esta instancia é uma propriedade do objeto
Adicionando objetos ao Cache
Existe diversas maneiras para adicionar um objeto no cache, para este exemplo vou adicionar uma string de diversas maneiras no Cache.
Adicionando um item diretamente utilizando chave e valor:
HttpContext.Cache["chave1"]= "valor do objeto";
Adicionando um item utilizando o método Insert:
HttpContext.Cache.Insert("chave1","valor do objeto");
Adicionando um item com uma coleções de chaves de objetos no cache, o qual o objeto "chAve3" depende:
string[] dependencias = {"chave1", "chave2"};
HttpContext.Cache.Insert("chave3","valor do objeto",
new CacheDependency(null,dependencias));
Além da dependência de outros objetos no cache, é possível ter várias outras dependência, que em caso de alteração, o objeto do cache é invalidado.
No exemplo abaixo, qualquer alteração no teste.xml faria o objeto com a chave "chave1" ser invalidado:
HttpContext.Cache.Insert("chave1", "valor do objeto 1",
Server.MapPath("teste.xml")));
Outra configuração importante no Cache é a politica de expiração com prazos definidos.Existem duas maneiras de configurar o tempo de expiração: sliding expiration e absolute expiration (detalhes).O tempo de expiração do Cache tem duas maneiras de ser configurado:
Absolute Expiration: O objeto em Cache irá expirar em uma determinada data, a partir do momento de inserção do objeto no Cache, independente do seu uso ou não.
Sliding Expiration: O objeto em Cache irá expirar após o tempo configurado, a partir da ultima requisição do objeto em Cache.
No exemplo abaixo eu uso Absolute Expiration, o objeto ficará no Cache por 2 minutos:
var objetoCacheado = "Objeto no Cache";
Cache.Insert("chave1", objetoCacheado, null, DateTime.Now.AddMinutes(2),
Neste segundo exemplo, com Sliding Expiration o objeto ficará no Cache por 2 minutos após o ultimo acesso a ele:
Cache.Insert("chave2", objetoCacheado, null, System.Web.Caching.Cache.NoAbsoluteExpiration,
Outra maneira de adicionar um objeto no cache é utilizar o método Add, o que retorna o objeto que representa o item no cache
var objetoQueRepresentaoItem = (string)HttpContext.Cache.Add(
"chave1",
objetoCacheado,
Uma opção de configuração durante a inserção de um objeto no Cache é a prioridade de manutenção daquele objeto na memória, que é um Enum
Retornando objetos do Cache
Para retornar um objeto que esteja no Cache é só acessar o objeto através da chave que foi utilizada para armazenar o objeto, caso o objeto não esteja no cache, o valor NULL será retornado.
Como o Cache é volátil, o exemplo abaixo utiliza uma abordagem de desenvolvimento que verifica se o objeto com a chave "chave1" está no Cache, caso ele não esteja, o valor é armazenado no Cache e retornado, caso ele esteja no cache, o valor é retornado:
cachedString = (string)HttpContext.Cache["chave1"];
cachedString = "valor da chave no cache";
HttpContext.Cache.Insert("chave1", cachedString);
Removendo objetos ao Cache
O Cache do ASP.NET é volátil, um objeto pode ser removido por diversos motivos como:Cache cheio, o objeto expirou ou alguma dependência do objeto foi alterada. Além desses meios, um item do Cache pode ser removido da seguinte maneira:
HttpContext.Cache.Remove("chave1");
Como exemplo, vou criar um estrutura para manter as informações de diversos menus (dinâmicos) de um site no cache, no exemplo utilizei um cache de 15 minutos, é impressionante como cenários de alta escala, algum segundos de Cache é a diferença entre 5000 requisições ao banco de dados, contra somente 1 requisição.
public class MenuRepository
public Menu Load(int menuId)
//TODO:Carregar do banco
MenuService (responsável por orquestrar se o objeto será retornado no cache ou diretamente do banco de dados e armazenado no cache antes de retornar):
var cacheKey = string.Format("menu_{0}", menuId);
var menuNoCache = (Menu)System.Web.HttpContext.Current.Cache[cacheKey];
if(menuNoCache==null)
var menuRepository = new MenuRepository();
menuNoCache = menuRepository.Load(menuId);
menuNoCache,
return menuNoCache;
Evitar transferência de redes, idas ao banco de dados e execução de algumas queries podem ser fundamentais no ganho de performance.
Espero que este post seja útil, no próximo post falarei um pouco sobre OutputCache.
Estou a disposição para duvida, criticas e sugestões
Esperando pelos próximos posts 😉
Muito bom o artigo, bem didatico, gostei da parte do Sliding
Expliration, a idéia seria pra usar em processos que demorem para gerar
cache? tipo: enquanto recebe acesso mantenha o cache, se passar X tempo,
faça um novo cache.
Fiz uns tentes equi e funciona muito bem, já
tinha brincado com cache HTTP, mais o de objeto ainda não tinha
brincado, muito bom mesmo o artigo parabens!
Muito bom cara, tenho uma sugestão, que tal colocar alguma coisa sobre CDN's?
[…] eu disse em um post anterior (Cache + .NET: Cache de Objetos), existem diversas técnicas para conseguirmos melhorar a performance de nossas aplicações web. […]
Rodolfo, eu tenho algumas entidades, eu posso colocá-las no Cache? qual seria a boa prática? colocar no repositório ou apenas colocá-las no tratamento da camada de apresentação?