Aplicativos WCF escaláveis ​​usando cache distribuído

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.

  • Os dados do aplicativo são, de longe, o uso de dados mais pesado em um serviço WCF, e seu armazenamento e acesso são um grande gargalo de escalabilidade devido à latência que vem como um subproduto do acesso a dados relacionais.
  • Ambientes com fontes de dados altamente distribuídas e díspares representam o maior desafio para atingir as metas de desempenho da SOA. Embora a camada de aplicativo possa ser dimensionada bem, uma das principais preocupações que permanecem em uma arquitetura orientada a serviços (SOA) é o desempenho dos serviços de dados participantes.
  • A camada de dados não pode ser dimensionada de forma linear em termos de capacidade de manipulação de transações, potencialmente causando atrasos consideráveis ​​no tempo de resposta geral.
  • Além disso, um serviço SOA depende de outros serviços, que podem não estar disponíveis localmente, de modo que uma chamada WAN para outro serviço pode se tornar outro gargalo.
  • Além disso, se a SOA estiver sendo usada na implementação de uma camada de virtualização de dados, o desempenho dos serviços de dados é de fundamental importância, caso em que o desempenho do aplicativo é diretamente proporcional ao tempo que leva para buscar os dados subjacentes. Os serviços de dados podem acessar dados relacionais e não relacionais, geralmente distribuídos em vários data centers distribuídos geograficamente, o que pode causar latência de resposta, prejudicando o desempenho geral do aplicativo.

Cache Distribuído (NCache) para escalabilidade do serviço

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.

Como funciona o dobrador de carta de canal NCache o cache distribuído pode reduzir a pressão sobre a fonte de dados
Figura 1: Como NCache o cache distribuído pode reduzir a pressão sobre a fonte de dados

Cache de dados do aplicativo

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:

  • O Cache Distribuído pode escalar horizontalmente como resultado da arquitetura que emprega.
  • Ele mantém as coisas distribuídas em vários servidores — e ainda oferece ao seu aplicativo SOA uma visão lógica para que você pense que é apenas um cache. Mas o cache realmente vive em vários servidores e é isso que permite que o cache realmente seja dimensionado.
  • Se você usa cache distribuído como NCache entre a camada de serviço e o banco de dados, você melhorará drasticamente o desempenho e a escalabilidade da camada de serviço, pois economizará um grande número de viagens demoradas ao banco de dados.

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;
    }
  }
}
Figura 2 - Uso do serviço WCF NCache - Cache Distribuído

Recursos importantes de cache

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.

Dados em cache expirando

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.

Sincronizando o Cache com um Banco de Dados

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.

Gerenciando relacionamentos de dados no cache

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.

Conclusão

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.

© Copyright Alachisoft 2002 - . Todos os direitos reservados. NCache é uma marca registrada da Diyatech Corp.