EntLib (parte 2) – Melhore a performance de suas consultas
Todo mundo sabe que na maioria das vezes o maior custo para recuperarmos informações numa aplicação está na consulta ao banco de dados. Entenda por “custo” a demanda de infra necessária para obter ou até mesmo persistir dados no contexto da aplicação bem como o tempo de resposta para executar tais operações, o que impacta diretamente na performance geral da aplicação. Uma das técnicas utilizadas para evitarmos consultas desnecessárias ao servidor de banco de dados é o armazenamento temporário em cache, onde os dados são disponibilizados em uma área da memória do servidor de aplicação.
A Enterprise Library oferece uma biblioteca para utilização de mecanismos de cache de maneira simples chamada Caching Application Block. Para usarmos o bloco numa aplicação basta adicionarmos uma referência no projeto da seguinte DLL:
Microsoft.Practices.EnterpriseLibrary.Caching.dll
A partir daí adicionamos o namespace indicado abaixo na classe que utilizará o Caching:
...
using Microsoft.Practices.EnterpriseLibrary.Caching;
...
Se quiséssemos, por exemplo, recuperar imagens de produtos gravadas no banco de dados, utilizaríamos o seguinte código:
...
byte[] fotoProduto = null;
ICacheManager cache = CacheFactory.GetCacheManager();
fotoProduto = (byte[])cache[id.ToString()];
if (fotoProduto == null)
{
ServicoProduto servico = new ServicoProduto();
fotoProduto = servico.ObterFotoProduto(id);
cache.Add(id.ToString(), fotoProduto);
}
...
Repare que nas linhas 4 e 5 o cache é criado e a variável fotoProduto recebe o valor armazenado no gerenciador de cache do Caching Application Block. Nas linhas 7 a 13 a consulta ao banco é realizada caso o cache ainda não tenha sido preenchido ou o seu tempo de vida tenha expirado. Nas solicitações seguintes a consulta ao banco será descartada, já que o cache já terá recebido a carga da imagem. Para garantirmos a unicidade das imagens fornecemos junto a chave do produto através do valor contido na variável id.
O arquivo de configuração da aplicação deve ser alterado adicionando-se as tags a seguir:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
...
<section name="cachingConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Caching.Configuration.CacheManagerSettings, Microsoft.Practices.EnterpriseLibrary.Caching, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</configSections>
...
<cachingConfiguration defaultCacheManager="Cache Manager">
<cacheManagers>
<add expirationPollFrequencyInSeconds="60" maximumElementsInCacheBeforeScavenging="1000"
numberToRemoveWhenScavenging="10" backingStoreName="Null Storage"
type="Microsoft.Practices.EnterpriseLibrary.Caching.CacheManager, Microsoft.Practices.EnterpriseLibrary.Caching, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
name="Cache Manager" />
</cacheManagers>
<backingStores>
<add encryptionProviderName="" type="Microsoft.Practices.EnterpriseLibrary.Caching.BackingStoreImplementations.NullBackingStore, Microsoft.Practices.EnterpriseLibrary.Caching, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
name="Null Storage" />
</backingStores>
</cachingConfiguration>
...
</configuration>
O tempo de duração do cache está definido na linha 14, através da propriedade expirationPollFrequencyInSeconds.
Obviamente devemos planejar o uso deste mecanismo, entendendo onde teremos um real ganho de performance ao aplicarmos essa técnica, caso contrário estaremos só adicionando mais código na aplicação.
A título de informação, a Microsoft tem um projeto com o codinome Velocity que oferecerá uma plataforma de cache distribuído para aplicações armazenando qualquer tipo de dado com alta-performance. Atualmente o projeto está com a versão CTP 3 disponível para download, caso você tenha alguma experiência com o Velocity e deseje compartilhar comentando aqui, fique a vontade. Até o próximo post da série.