Autor: Iqbal Khan
Após a explosão de aplicativos da Web para acomodar o uso de alto tráfego, a próxima grande onda tornou-se a arquitetura orientada a serviços (SOA). A SOA mudou o cenário de desenvolvimento e integração de aplicativos. Ele está destinado a se tornar uma maneira padrão de desenvolver aplicativos extremamente escaláveis, e plataformas de computação em nuvem como o Windows Azure e o Windows Communication Foundation (WCF) representam um salto gigantesco na movimentação da SOA para atingir esse objetivo. A SOA destina-se principalmente a alcançar escalabilidade e sustentar a carga que é lançada para obter agilidade e produtividade aprimoradas.
No entanto, um verdadeiro aplicativo SOA deve ser dimensionado facilmente no que diz respeito à arquitetura do aplicativo. No entanto, existem muitos gargalos de desempenho que precisam ser resolvidos para alcançar a verdadeira escalabilidade.
Para reduzir a latência de resposta de toda a solução, uma abordagem abrangente é utilizar um sistema de cache de alto desempenho para uso em conjunto com os serviços de dados ou na camada de virtualização de dados. Os serviços SOA lidam com dois tipos de dados. Um são dados de estado de serviço e o outro são dados de resultado de serviço que residem no banco de dados. Ambos causam gargalos de escalabilidade.
O armazenamento em cache pode desempenhar um papel muito importante na melhoria da velocidade de acesso ao estado do serviço e aos dados do aplicativo, ao mesmo tempo em que permite dimensionar os serviços ao mesmo tempo. O cache consegue isso minimizando a quantidade de tráfego e a latência entre os serviços que usam o cache e os provedores de dados subjacentes. A Figura 1 mostra o uso de NCache cache distribuído para conseguir isso.
Um cache distribuído como NCache é usado para armazenar em cache apenas um subconjunto dos dados que estão no banco de dados com base no que o serviço WCF precisa em uma pequena janela de algumas horas. Um cache distribuído pode dar a um aplicativo SOA um aumento significativo de escalabilidade porque:
A lógica básica a ser implementada é que, antes de ir para o banco de dados, verifique se o cache já possui os dados. Se isso acontecer, tire-o do cache. Caso contrário, vá para o banco de dados para buscar os dados e coloque-os no cache para a próxima vez. A Figura 2 mostra um exemplo.
using System.ServiceModel;
using Alachisoft.NCache.Web.Caching;
namespace MyWcfServiceLibrary {
[ServiceBehavior]
public class EmployeeService : IEmployeeService {
static string _sCacheName = "myServiceCache";
static Cache _sCache =
NCache.InitializeCache(_sCacheName);
public Employee Load(string employeeId) {
// Create a key to lookup in the cache.
// The key for will be like "Employees:PK:1000".
string key = "Employee:EmployeeId:" + employeeId;
Employee employee = (Employee)_sCache[key];
if (employee == null) {// item not found in the cache.
// Therefore, load from database.
LoadEmployeeFromDb(employee);
// Now, add to cache for future reference.
_sCache.Insert(key, employee, null,
Cache.NoAbsoluteExpiration,
Cache.NoSlidingExpiration,
CacheItemPriority.Default);
}
// Return a copy of the object since ASP.NET Cache is InProc.
return employee;
}
}
}
Um design de cache para um serviço deve considerar questões como: com que frequência os dados subjacentes são alterados, com que frequência os dados em cache precisam ser atualizados, se os dados são específicos do usuário ou de todo o aplicativo, qual mecanismo usar para indicar que o cache precisa de atualização, nível de tolerância de aplicação para dados sujos etc. Assim, uma solução de cache deve ter os recursos necessários para classificar todos esses requisitos.
Alguns dos principais recursos no gerenciamento escalável de dados por meio de serviços de dados usando cache distribuído são apresentados a seguir.
As expirações permitem especificar por quanto tempo os dados devem permanecer no cache antes que o cache os remova automaticamente. Existem dois tipos de expirações que você pode especificar em NCache: expiração em tempo absoluto e expiração em tempo deslizante ou ocioso.
Se os dados em seu cache também existirem no banco de dados, você sabe que esses dados podem ser alterados no banco de dados por outros usuários ou aplicativos que podem não ter acesso ao seu cache. Quando isso acontece, os dados em seu cache ficam obsoletos, o que você não deseja. Se você puder adivinhar por quanto tempo acha seguro que esses dados sejam mantidos no cache, poderá especificar a expiração em tempo absoluto. Além disso, a expiração deslizante pode ser muito útil para aplicativos baseados em sessão, nos quais você armazena sessões em cache distribuído.
A necessidade de sincronização de banco de dados surge porque o banco de dados está realmente sendo compartilhado entre vários aplicativos e nem todos esses aplicativos têm acesso ao seu cache. Se o seu aplicativo de serviço WCF for o único a atualizar o banco de dados e também puder atualizar facilmente o cache, você provavelmente não precisará do recurso de sincronização de banco de dados.
Mas, em um ambiente da vida real, isso nem sempre é o caso. Aplicativos de terceiros atualizam dados no banco de dados e seu cache fica inconsistente com o banco de dados. Sincronizar seu cache com o banco de dados garante que o cache esteja sempre ciente dessas alterações no banco de dados e possa se atualizar de acordo.
Sincronizar com o banco de dados geralmente significa invalidar o item em cache relacionado do cache para que, na próxima vez que seu aplicativo precisar dele, ele tenha que buscá-lo no banco de dados porque o cache não o possui.
A maioria dos dados vem de um banco de dados relacional e, mesmo que não venha de um banco de dados relacional, é de natureza relacional. Por exemplo, você está tentando armazenar em cache um objeto de cliente e um objeto de pedido e ambos os objetos estão relacionados. Um cliente pode ter vários pedidos.
Quando você tem esses relacionamentos, precisa ser capaz de manipulá-los em um cache. Isso significa que o cache deve saber sobre o relacionamento entre um cliente e um pedido. Se você atualizar ou remover o cliente do cache, talvez queira que o cache remova automaticamente o objeto de pedido do cache. Isso ajuda a manter a integridade dos dados em muitas situações.
Se um cache não puder acompanhar esses relacionamentos, você terá que fazer isso sozinho — e isso torna seu aplicativo mais complicado e complexo.
Assim, um aplicativo SOA não pode ser dimensionado com eficiência quando os dados que ele usa são mantidos em um armazenamento que não é dimensionável para transações frequentes. É aqui que o cache distribuído como NCache realmente ajuda. Em um ambiente corporativo, o ambiente de aplicativo baseado em SOA não pode realmente ser dimensionado sem empregar uma verdadeira infraestrutura de cache distribuído. Os servidores de banco de dados tradicionais também estão melhorando, mas sem o armazenamento em cache distribuído, os aplicativos de serviço não podem atender à demanda explosiva por escalabilidade no ambiente de aplicativos complexos de hoje.
Autor:Iqbal Khan trabalha para Alachisoft , uma empresa de software líder que fornece soluções de cache distribuído .NET e Java, mapeamento O/R e otimização de armazenamento do SharePoint. Você pode alcançá-lo em iqbal@alachisoft.com.