Este artigo foi traduzido por máquina.

Microsoft Azure

Usar cache distribuído no Microsoft Azure

Iqbal Khan
Jeremiah Talkar

Microsoft Azure está rapidamente se tornando a escolha de nuvem para aplicativos .NET. Além de seu rico conjunto de recursos de nuvem, Azure fornece total integração com o Microsoft .NET Framework. Também é uma boa escolha para aplicações Java, PHP, Ruby e Python. Muitos dos aplicativos movendo-se para Azure são elevado-tráfego, então você pode esperar o suporte completo para alta escalabilidade. Na memória cache distribuído pode ser um componente importante de um ambiente escalável.

Este artigo cobrirá cache distribuído em geral e o que ele pode fornecer.

Os recursos descritos aqui relacionam polivalente na memória cache distribuído e não especificamente Azure Cache ou NCache para Azure. Para aplicativos .NET implantados no Azure, na memória cache distribuído tem três vantagens principais:

  1. Escalabilidade e desempenho do aplicativo
  2. Cache de estado de sessão do ASP.NET , estado de exibição e página de saída
  3. Compartilhamento de dados de tempo de execução com eventos

Escalabilidade e desempenho do aplicativo

Azure facilita a escala de uma infra-estrutura de aplicativo. Por exemplo, você pode facilmente adicionar mais Web de funções, funções de trabalho ou máquinas virtuais (VMs) quando você antecipa a maior carga de transação. Apesar dessa flexibilidade, armazenamento de dados pode ser um gargalo que poderia mantê-lo de ser capaz de escalar seu app.

Isto é onde um cache distribuído na memória pode ser útil. Ele permite que você armazenar em cache o máximo de dados que você quiser. Leituras caro banco de dados pode reduzir em mais de 90 por cento. Isso também reduz a pressão transacional do banco de dados. Será capaz de executar mais rápido e assumir uma maior carga de transação.

Ao contrário de um banco de dados relacional, um cache distribuído na memória pode ser dimensionado de maneira linear. Geralmente não se tornará um gargalo de escalabilidade, apesar de 90% do tráfego leitura pode ir para o cache em vez de banco de dados. Todos os dados no cache é distribuída para vários servidores de cache. Você pode facilmente adicionar mais servidores de cache, como aumenta a sua carga de transação. Figura 1 mostra como direcionar apps para o cache.

Figura 1 usando na memória Cache em aplicativos .NET distribuído

// Check the cache before going to the database
  Customer Load(string customerId)
{
// The key for will be like Customer:PK:1000
  string key = "Customers:CustomerID:" + customerId;
  Customer cust = (Customer)Cache[key];
  if (cust == null)
{
// Item not found in the cache; therefore, load from database
  LoadCustomerFromDb(cust);
// Now, add this object to the cache for future reference
  Cache.Insert(key, cust, null,
  Cache.NoAbsoluteExpiration,
  Cache.NoSlidingExpiration,
  CacheItemPriority.Default, null );
}
  return cust;
}

Um cache distribuído na memória pode ser mais rápido e mais escalável do que um banco de dados relacional. Figura 2 mostra alguns dados de desempenho para lhe dar uma idéia. Como você pode ver, a escalabilidade é linear. Compare isto com o seu banco de dados relacional ou seu armazenamento de estado de sessão do ASP.NET e você verá o benefício.

Figura 2 números de desempenho para um típico Cache distribuído

Tamanho do cluster Leituras por segundo Escreve por segundo
2-nó cluster 50,000 32,000
3-nó cluster 72,000 48,000
4-nó cluster 72,000 64,000
5-nó cluster 120,000 80,000
6-nó cluster 144,000 96,000

Estado de sessão ASP.NET , estado de exibição e de saída da página de cache

Usando na memória cache distribuído no Azure também ajuda com o estado de sessão do ASP.NET , estado de exibição ASP.NET e ASP.NET de Cache de saída. Você precisará armazenar estado de sessão do ASP.NET em algum lugar. Isso pode se tornar um gargalo de escalabilidade maiores. No Azure, você pode armazenar o estado de sessão ASP.NET em um banco de dados SQL, Azure Table Storage ou um cache distribuído na memória.

Um banco de dados SQL não é ideal para armazenar o estado da sessão. Bancos de dados relacionais nunca foram projetados para o armazenamento de Blob, e um objeto de estado da sessão ASP.NET é armazenado como um Blob. Isso pode causar problemas de desempenho e tornar-se um gargalo de escalabilidade.

Da mesma forma, o Azure Table Storage não é ideal para armazenamento de Blob. Destina-se para o armazenamento estruturado de entidades. Embora seja mais escalonável do que um banco de dados SQL, é ainda não é ideal para armazenar estado de sessão do ASP.NET .

Um cache distribuído na memória é mais adequado para o armazenamento de estado de sessão ASP.NET no Azure. É mais rápido e mais escalável do que as outras duas opções. Também reproduz sessões então não há nenhuma perda de dados se um servidor de cache vai para baixo. Se você armazenar sessões em um separado dedicado cache de camada, em seguida Web papéis e VMs de servidor de Web se tornar apátridas, que é bom porque você pode derrubá-los sem perder quaisquer dados de sessão.

Enquanto executar o ASP.NET estado de sessão em cache é ideal do ponto de vista de desempenho, se o cache vai para baixo, seu app inteiro vai descer. E, claro, tudo o que está em sua sessão também teria ido. O novo Cache Redis para provedor de estado de sessão Azure terá uma maneira que você pode saber quando esses tipos de problemas acontecem e, pelo menos, exibi-los para o usuário de forma limpa.

Figura 3 mostra como configurar um cache distribuído na memória para armazenar o estado da sessão ASP.NET .

Figura 3 configurar o armazenamento de estado de sessão ASP.NET em um Cache distribuído

// Check the Cache before going to the database
  Customer Load(string customerId)
{
// The key for will be like Customer:PK:1000
  string key = "Customers:CustomerID:" + customerId;
  Customer cust = (Customer)Cache[key];
  if (cust == null)
{
// Item not found in the cach; therefore, load from database
  LoadCustomerFromDb(cust);
// Now, add this object to the cache for future reference
  Cache.Insert(key, cust, null,
  Cache.NoAbsoluteExpiration,
  Cache.NoSlidingExpiration,
  CacheItemPriority.Default, null );
}
  return cust;
}

Embora ASP.NET framework MVC eliminou a necessidade de usar estado de exibição ASP.NET , a maioria dos aplicativos ASP.NET ainda não se mudou para ASP.NET framework MVC. Portanto, eles ainda exigem ASP.NET estado de exibição.

ASP.NET Estado de exibição pode ser um fardo de grande largura de banda e causar uma queda em seus tempos de resposta do aplicativo ASP.NET . Isso é porque o estado de exibição ASP.NET pode ser centenas de kilobytes para cada usuário. Desnecessariamente é enviado para e partir do navegador em caso de postagem voltar. Se este estado de exibição ASP.NET é armazenada em cache do lado do servidor Web e um identificador exclusivo é enviado para o navegador, ele pode melhorar tempos de resposta e também reduzir o consumo de largura de banda.

No Azure, onde seu aplicativo ASP.NET é executado em várias funções da Web ou VMs, o lugar menos interrupções para este estado de exibição ASP.NET em cache é em um cache distribuído na memória. Dessa forma, você pode obter isso de qualquer servidor Web. Aqui está como você pode configurar o estado de exibição ASP.NET para armazenamento em um cache distribuído na memória:

<!-- /App_Browsers/Default.browser -->
<browsers>
  <browser refID="Default" >
    <controlAdapters>
      <adapter
      controlType="System.Web.UI.Page"
      adapterType="DistCache.Adapters.PageAdapter"/>       
    </controlAdapters>
  </browser>
</browsers>

ASP.NET também fornece uma estrutura de cache de saída que permite armazenar em cache de saída da página que não seja susceptível de alterar. Assim que você não precisa executar a página... da próxima vez. Isto economiza recursos de CPU e acelera o tempo de resposta ASP.NET . Em uma implantação de vários servidores, o melhor lugar para o cache de saída da página é dentro de um cache distribuído, para que seja acessível de todos os servidores Web. Felizmente, o Cache de saída ASP.NET tem uma arquitetura baseada em provedor então você pode facilmente conectar um cache distribuído na memória (ver Figura 4).

Figura 4 configurar o Cache de saída ASP.NET para na memória Cache distribuído

<!-- web.config -->
<system.web>
  <caching>
    <outputCache defaultProvider="DistributedCache">
      <providers>
        <add name="DistributedCache"
          type="Vendor.Web.DistributedCache.DistCacheOutputCacheProvider,
            Vendor.Web.DistributedCache"
          cacheName="default"
          dataCacheClientName="default"/>
      </providers>
    </outputCache>
  </caching>
</system.web>

Compartilhamento através de eventos de dados de tempo de execução

Outro motivo para considerar o uso de memória cache distribuído no Azure é o compartilhamento de dados de tempo de execução. Aplicações tipicamente fazer das seguintes maneiras de compartilhamento de dados de tempo de execução:

  1. Bancos de dados relacionais para detectar as alterações de dados de sondagem
  2. Usando eventos de banco de dados (tais como SqlDependency ou OracleDepedency)
  3. Usando filas de mensagem como MSMQ

Todas essas abordagens fornecem funcionalidade básica, mas cada um tem certos problemas de desempenho e escalabilidade. Sondagem é normalmente uma má idéia. Isso envolve muitas leituras de banco de dados desnecessários. Bancos de dados já são um gargalo de escalabilidade, mesmo sem eventos de banco de dados adicional. Com o adicionado sobrecarga de eventos de banco de dados, bancos de dados irão sufocar ainda mais rápido sob carga pesada de transação.

Filas de mensagens especializa-se na partilha de dados seqüenciados e eventos persistentes para armazenamento permanente. Eles são bons para situações onde os destinatários não podem receber eventos por um longo tempo, ou onde os aplicativos são distribuídos através da WAN. No entanto, quando se trata de um ambiente de alta transação, filas de mensagens não podem executar ou escala como um cache distribuído na memória.

Então se você tem um ambiente de alta transação onde vários aplicativos precisam compartilhar dados em tempo de execução sem qualquer seqüenciamento e você não precisa persistir eventos por um longo tempo, você pode querer considerar o uso de um cache distribuído na memória para compartilhamento de dados de tempo de execução. Um cache distribuído na memória permite que você compartilhe dados em tempo de execução em uma variedade de maneiras, todos os quais são assíncronos:

  1. Item eventos na atualização de nível e de remover
  2. Nível de grupo/região e cache - eventos
  3. Eventos baseados em consulta contínuos
  4. Eventos baseados em tópico (para o modelo de publicação/assinatura)

Os três primeiros recursos são essencialmente diferentes maneiras para monitorar as alterações de dados dentro do cache. Seu aplicativo registra retornos de chamada para cada uma delas. O cache distribuído é responsável por "disparando o evento" sempre que altera os dados correspondentes no cache. Isso resulta em seu retorno de chamada do aplicativo sendo chamado.

Quando um determinado item em cache é atualizado ou removido, haverá um evento de nível de item disparado. Cache - e a nível de grupo/região eventos são disparados quando dados naquele "contentor" são adicionados, atualizados ou removidos. Contínua consulta consiste de critérios de pesquisa para definir um dataset em cache distribuído. O cache distribuído aciona eventos sempre que você adiciona, atualizar ou remove dados deste dataset. Você pode usar isto para monitorar as alterações de cache:

string queryString = "SELECT Customers WHERE this.City = ?";
Hashtable values = new Hashtable();
values.Add("City", "New York");
Cache cache = CacheManager.GetCache(cacheName);
ContinuousQuery cQuery = new ContinuousQuery(queryString, values);
cQuery.RegisterAddNotification(
  new CQItemAddedCallback(cqItemAdded));
cQuery.RegisterUpdateNotification(
  new CQItemUpdatedCallback(cqItemUpdated));
cQuery.RegisterRemoveNotification(
  new CQItemRemovedCallback(cqItemRemoved));
cache.RegisterCQ(query);

Eventos baseados em tópico são de uso geral e não são amarrados a quaisquer alterações de dados no cache. Neste caso, um cliente de cache é responsável por "disparar o evento." O cache distribuído se torna algo como um barramento de mensagens e transporta esse evento para todos os outros clientes conectados ao cache.

Com eventos baseados em tópico, seus aplicativos podem compartilhar dados em um modelo de publicação/assinatura, onde um aplicativo publica dados e dispara um evento baseado no tópico. Outros aplicativos Esperem para esse evento e começam a consumir dados, uma vez que é recebido.

Arquitetura de Cache distribuído

Apps de alto tráfego não podem pagar o tempo de inatividade. Para estas aplicações rodando no Azure, existem três aspectos importantes em-memória cache distribuído:

  1. Alta disponibilidade
  2. Escalabilidade linear
  3. Confiabilidade e replicação de dados

Elasticidade de cache é um aspecto essencial da manutenção de seu cache distribuído na memória. Muitos na memória caches distribuídos alcançar elasticidade e alta disponibilidade com o seguinte:

Auto-recuperação do cluster de cache peer-to-peer: Todos os servidores de cache formam um cluster de cache. Um cluster de peer-to-peer auto-recuperação ajusta-se sempre que nós são adicionados ou removidos. O mais poderoso caches forma um self-healing-to-peer cluster de cache, enquanto outros formam aglomerados de mestre/escravo. Peer-to-peer é dinâmico e permite que você adicionar ou remover servidores de cache sem parar o cache. Clusters de mestre/escravo são limitados porque um ou mais de nós designado descendo cabazes operações de cache. Alguns caches como Memcached não forma qualquer cluster de cache e, portanto, não são considerados elástica.

Failover de conexão: Os clientes de cache são aplicativos em execução em servidores de aplicativos e servidores Web que acessar os servidores de cache. Capacidade de failover de conexão encontra-se a clientes de cache. Isto significa que se qualquer servidor de cache no cluster vai para baixo, o cliente de cache continuará trabalhando por encontrar outros servidores no cluster.

Configuração dinâmica: os dois servidores de cache e cache clientes têm essa capacidade. Em vez de exigir que os clientes de cache para detalhes de configuração de codificar, servidores de cache propagam essa informação para os clientes de cache em tempo de execução, incluindo quaisquer alterações.

Topologias de cache

Em muitos casos, você está cache de dados que não existem no banco de dados, tais como o estado de sessão ASP.NET . Portanto, a perda de dados pode ser bastante doloroso. Até onde existem dados no banco de dados, perder muita coisa quando um nó de cache cair severamente pode afetar desempenho de app.

Portanto, é melhor se o seu cache distribuído na memória Replica seus dados. No entanto, a replicação tem custos de armazenamento e desempenho. Um bom na memória cache fornece um conjunto de cache topologias para lidar com diferentes tipos de necessidades de armazenamento e replicação de dados:

Cache espelhado: Esta topologia tem um ativo e um servidor de cache passivo. Todas as leituras e gravações são feitas contra o nó ativo e atualizações são aplicadas de forma assíncrona para o espelho. Esta topologia é normalmente usada quando você somente pode dispensar um servidor cache dedicado e compartilhar um servidor de app/Web como o espelho.

Cache replicado: Esta topologia tem dois ou mais servidores de cache ativo. Todo o cache é replicado para todos eles. Todas as atualizações são síncronas — são aplicadas a todos os servidores de cache como uma única operação. Leia o transações escala linearmente como você adicionar mais servidores. A desvantagem é que adicionar mais nós não aumentar o armazenamento ou atualizar a capacidade de transação.

Cache particionado: Esta topologia tem todo o cache particionado, com cada servidor de cache que contém uma partição. Clientes de cache geralmente conectam todos os servidores de cache, para que eles possam acessar diretamente os dados na partição desejada. Sua capacidade de armazenamento e transação cresce à medida que você adiciona mais servidores para que haja escalabilidade linear. Não há nenhuma replicação, embora, assim que você pode perder dados se um servidor de cache vai para baixo.

Cache replicado particionado: Isto é como um Cache particionado, exceto que cada partição é replicada para pelo menos um outro servidor de cache. Você não perderá quaisquer dados, se um servidor de cache vai para baixo. A partição é geralmente ativa e a réplica é passiva. Seu aplicativo não interage diretamente com a réplica. Esta topologia fornece os benefícios de um Cache particionado como escalabilidade linear, além de confiabilidade dos dados. Há uma ligeiro desempenho e custo de armazenamento associado a replicação.

Cliente Cache (Cache de perto): Clientes de cache normalmente executem em servidores de app/Web, para que acessar o cache normalmente envolve o tráfego de rede. Cache do cliente (também chamado de Cache de perto) é um cache local de dados mantém freqüentemente usado perto seu app e salva viagens de rede. Este cache local é também conectado e sincronizado com o cache distribuído. Cache de cliente pode ser InProc (que significa dentro de seu processo de candidatura) ou OutProc.

Implantação de Cache distribuído no Azure

No Azure, você tem várias opções de cache distribuído, incluindo Microsoft Azure Cache, NCache para Azure e Memcached. Cada cache fornece um conjunto diferente de opções. Estas são as opções mais comuns de implantação para uma única região:

  1. Cache em papel (co-localizado ou dedicado)
  2. Serviço de cache
  3. Cache VMs (dedicadas)
  4. VMs cache WAN (várias regiões)

Papel-em Cache você pode implantar um cache no papel um papel co-localizado ou dedicado no Azure. Co-localizado significa sua aplicação também está executando essa VM e dedicado significa que ele está executando apenas o cache. Embora um bom cache distribuído fornece elasticidade e alta disponibilidade, há sobrecarga associada à adição ou remoção de servidores de cache do cluster de cache. Sua preferência deve ser ter um cluster de cache estável. Você deve adicionar ou remover servidores de cache somente quando você deseja expandir ou reduzir sua capacidade de cache ou quando você tem um servidor de cache para baixo.

O cache no papel é mais volátil do que outras opções de implantação porque Azure pode facilmente iniciar e parar a funções. Em um papel co-localizados, o cache é também compartilhar recursos de CPU e memória com seus aplicativos. Para uma ou duas instâncias, é OK para usar esta opção de implantação. Não é adequado para implantações maiores, no entanto, devido ao impacto negativo no desempenho.

Você também pode considerar usar um cache em papel dedicado. Tenha em mente esse cache é implantado como parte de seu serviço de nuvem e só é visível dentro desse serviço. Você não pode compartilhar esse cache através de vários aplicativos. Além disso, o cache é executado somente contanto que seu serviço está sendo executado. Então, se você precisa ter o cache, mesmo quando você parar seu aplicativo em execução, não use esta opção.

Microsoft Azure Cache e NCache para Azure ambos oferecem a opção de implantação no papel. Você pode fazer o Memcached executar esta configuração com alguns ajustes, mas você perder dados se um papel é reciclado porque Memcached não replica dados.

Serviço de cache em um serviço de Cache, o cache distribuído é implantado independente de seu serviço e oferece-lhe uma vista de nível de cache. Você alocar uma certa quantidade de memória e capacidade de CPU e cria seu cache. O benefício de um serviço de Cache é a simplicidade. Você não instalar e configurar qualquer software cache distribuído se. Como resultado, seu esforço de gerenciamento de cache é reduzido porque Azure está gerenciando o cluster de cache distribuído para você. Outro benefício é que você pode compartilhar esse cache entre vários aplicativos.

A desvantagem de um serviço de Cache é seu acesso limitado. Você não pode controlar ou manipular o cache VMs dentro do cluster, como você faria em um cache distribuído no local. Além disso, não é possível implantar qualquer codificar server-side como leitura, Write-through, carregador de cache e assim por diante. Você não pode controlar o número de VMs de cache no cluster porque ela é manipulada pelo Azure. Você só pode escolher entre as opções de implantação Basic, Standard e Premium. Microsoft Azure Cache fornece uma opção de implantação do serviço de Cache, enquanto NCache para Azure não.

VMs em cache outra opção é implantar seu cache distribuído no Azure. Isso lhe dá controle total sobre seu cache distribuído. Quando você implanta seu aplicativo na Web de funções, funções de operador ou VMs dedicadas, você também pode implantar a parte cliente do cache distribuído (as bibliotecas). Você também pode instalar o cliente de cache através do Windows Installer quando você criar o seu papel. Isso lhe dá mais opções de instalação como OutProc cliente Cache (Cache de perto).

Então você pode alocar separadas dedicadas VMs como seus servidores de cache, instalar o software de cache distribuído e construir seu cluster de cache baseado em suas necessidades. Essas VMs cache dedicado são estáveis e mantém funcionando mesmo quando seu aplicativo é interrompido. Suas conversas de cliente de cache para cache cluster através de um protocolo TCP. Para uma VM de Cache, existem dois cenários de implantação, que você pode usar:

  1. Implante dentro da sua rede virtual: Seus aplicativo funções/VMs e as VMs de cache estão todos dentro da mesma rede virtual. Não há nenhum ponto de extremidade entre seu aplicativo e o cache distribuído. Como resultado, o acesso de cache é rápido. O cache também é totalmente escondido do mundo exterior e, portanto, mais segura.
  2. Implante em redes virtuais separadas: Seus aplicativo funções/VMs e as VMs de cache estão em diferentes redes virtuais. O cache distribuído na sua própria rede virtual e expostos através de pontos de extremidade. Como resultado, você pode compartilhar o cache através de várias regiões e várias aplicações. No entanto, você tem muito mais controle sobre suas VMs de Cache que um serviço de Cache.

Em ambas as opções de implantação de Cache VM, você tem acesso total a todos os servidores de cache. Isso permite que você implantar o código do lado do servidor, tais como leitura, gravação e cache de carregador, como você faria em uma implantação no local. Você também tem mais informações de monitoramento, porque você tem acesso completo para o cache de VM. Microsoft Azure Cache não oferece a opção de Cache VM, Considerando que está disponível em NCache para Azure e Memcached.

Microsoft planeja ter seu cache gerenciado em disponibilidade geral em julho, que irá substituir o existente serviço de cache compartilhado. Ele provavelmente não terá uma presença portal Azure e exigirá uma linha de comando do Windows PowerShell para criar e gerenciar.

Você pode instalar NCache para Azure em VMs dedicadas e acessá-lo de sua Web e funções de trabalho. Você também pode instalar NCache para Azure na Web e funções de trabalho, mas isso não é uma estratégia recomendada. NCache para Azure não vem como um serviço de cache. Microsoft Azure também fornece serviço de Cache Redis, que está disponível através do portal de gerenciamento.

Cache VMs através de WAN se você tem um serviço de nuvem que é implantado em várias regiões, considerar a implantação de seu Cache VMs através da WAN. A implantação de Cache VM em cada região é o mesmo que a opção anterior. No entanto, você tem uma situação com dois requisitos adicionais:

  1. Sessões ASP.NET multi-site: Você pode transferir uma sessão ASP.NET de um local para outro, se um usuário é reencaminhado. Esta é uma ocorrência freqüente para aplicativos implantados em vários sites ativos. Eles podem redirecionar o tráfego para lidar com estouros ou porque eles estão trazendo um site para baixo.
  2. WAN replicação de cache: Você pode replicar todas as atualizações de cache de um local para outro. Isto pode ser uma implantação de vários local ativo-passivo ou ativo-ativo. No ativo-passivo, atualizações são replicadas em uma direção. Na ativa-ativa, é bidirecional. O cache é mantido sincronizado através de vários sites através da replicação de WAN, mas mantenha em mente que consome largura de banda.

Importantes recursos de cache

Quando você usa um cache distribuído na memória, ele vai lidar com um monte de dados. Um básico na memória cache distribuído apenas fornece uma interface de hashtable (chave, valor). Um cache distribuído de nível corporativo pode fornecer os seguintes recursos também:

Recursos de busca: ao invés de sempre procurar dados com base em uma chave, que é muito mais fácil de procurar o cache baseado em outros dados lógicos. Por exemplo, muitos caches distribuídos deixem usar grupos e tags para agrupar logicamente itens armazenados em cache. Muitos também permitem que você procure o cache através do LINQ, que é popular para o objeto de pesquisa no .NET Framework. Alguns também fornecem seus próprios Object Query Language (OQL), uma linguagem de consulta SQL-como com o qual você pode pesquisar o cache. A capacidade de Pesquisar um cache distribuído com base em atributos que não sejam chaves faz o cache distribuído olhar e sentir como um banco de dados relacional. Figura 5 mostra como você pode executar essa busca.

Figura 5 configurar uma pesquisa LINQ de um Cache distribuído

public IList<Customer> GetCutomers(string city)
{
  // Use LINQ to search distributed cache
  IQueryable<Customer> customers = 
    new DistCacheQuery<Customer>(cache);
  try {
    var result = from customer in customers
      where customer.City = city
      select customer;
    IList<Customer> prods = new List<Customer>();
    foreach (Customer cust in result) {
      customers.Add(cust);
    }
  }
  return customers;
}

Leitura e gravação-através de/write-behind: Manipuladores de leitura e gravação-através de simplificam o seu código de aplicativo porque você seguiu um grande pedaço do seu código persistente no cluster de cache. Seu aplicativo simplesmente assume que o cache é seu armazenamento de dados. Esta é uma outra forma de reutilização de código entre vários aplicativos.

O cache chama leitura sempre que seu aplicativo tenta buscar algo que não está no cache (isto é chamado uma "menina"). Quando acontece uma falta, o cache chama o manipulador de read-through e ele busca os dados de seu banco de dados (ver Figura 6). O cache distribuído coloca em cache e retorna ao seu aplicativo.

Figura 6 manipulador de leitura para um Cache distribuído

public class SqlReadThruProvider : IReadhThruProvider
{
  // Called upon startup to initialize connection
  public void Start(IDictionary parameters) { ... }
  // Called at the end to close connection
  public void Stop() { ... }
  // Responsible for loading object from external data source
  public object Load(string key, ref CacheDependency dep)
  {
    string sql = "SELECT * FROM Customers WHERE ";
    sql += "CustomerID = @ID";
    SqlCommand cmd = new SqlCommand(sql, _connection);
    cmd.Parameters.Add("@ID", System.Data.SqlDbType.VarChar);
      // Extract actual customerID from "key"
      int keyFormatLen = "Customers:CustomerID:".Length;
      string custId = key.Substring(keyFormatLen, 
        key.Length - keyFormatLen);
      cmd.Parameters["@ID"].Value = custId;
    // Fetch the row in the table
    SqlDataReader reader = cmd.ExecuteReader();
    // Copy data from "reader" to "cust" object
    Customers cust = new Customers();
    FillCustomers(reader, cust);
    // Specify a SqlCacheDependency for this object
    dep = new SqlCacheDependency(cmd);
    return cust;
  }
}

O cache também chama seu manipulador de write-through, sempre que você atualizar o cache e quer atualizar automaticamente o banco de dados. Seu manipulador de write-through é executado em um ou mais servidores de cache no cluster e fala para seu banco de dados. Se o write-through é chamado de forma assíncrona após um atraso e não como parte da transação de atualização do cache, no entanto, esta operação é chamada write-behind. Write-behind melhora o desempenho do aplicativo porque você não tem que esperar para a atualização do banco de dados ser concluída.

Sincronize o cache com Banco de dados relacional: A maioria dos dados dentro de um cache distribuído vem do seu banco de dados do aplicativo. Isso significa que existem agora duas cópias dos dados, a cópia mestre no banco de dados e outro no cache distribuído. Se você tem aplicações diretamente atualizar dados no banco de dados, mas não tenho acesso ao seu cache distribuído na memória, você acabar com dados desatualizados no cache.

Alguns caches distribuídos fornecem sincronização de banco de dados para garantir que o cache nunca tem dados obsoletos. Essa sincronização é orientada a eventos (usando notificações de banco de dados como SqlDependency) ou baseados em pesquisa. Evento-driven é mais perto do tempo real, mas tem mais sobrecarga porque ele cria um SqlDependency separado no servidor de banco de dados para cada cache item. Sondagem é mais eficiente porque uma chamada de banco de dados pode sincronizar milhares de itens. Mas normalmente há um atraso na sincronização, a fim de evitar inundações o banco de dados com chamadas desnecessárias de sondagem. Então, sua escolha é entre sincronização de banco de dados mais perto em tempo real ou mais eficiente sincronização baseada em sondagem com um ligeiro atraso.

Manipulação de dados relacionais em um cache distribuído: Um cache distribuído na memória é um armazenamento de objetos de chave-valor, mas a maioria dos dados armazenados em cache dentro vem de um banco de dados relacional. Esses dados tem relacionamentos um-para-muitos, um e muitos-para-muitos. Bancos de dados relacionais fornecem restrições de integridade referencial e atualizações em cascata e exclusões para impor essas relações. O cache precisa de algo semelhante também.

CacheDependency permite-lhe ter um item em cache dependem da outra. Se o outro item em cache é atualizado ou excluído, o item em cache original é excluído automaticamente. Isto funciona como uma exclusão em cascata. É útil para a manipulação de um para um e um-para-muitos relacionamentos entre objetos no cache. Alguns caches distribuídos na memória implementou esse recurso também. Figura 7 mostra como você configuraria CacheDependency.

Figura 7 uso CacheDependency para gerenciar relacionamentos no Cache

public void CacheCustomerAndOrder(Customer cust, Order order)
{
  Cache cache = HttpRuntime.Cache;
  // Customer has one-to-many with Order. Cache customer first
  // then cache Order and create CacheDependency on customer
  string custKey = "Customer:CustomerId:" + cust.CustomerId;
  cache.Add(custKey, cust, null,
    Cache.NoAbsoluteExpiration,
    Cache.NoSlidingExpiration,
    CacheItemPriority.Default, null);
  // CacheDependency ensures order is removed if Cust updated or removed
  string[] keys = new string[1];
  keys[0] = custKey;
  CacheDependency dep = new CacheDependency(null, keys);
  string orderKey = "Order:CustomerId:" + order.CustomerId
    + ":ProductId:" + order.ProductId;
  // This will cache Order object with CacheDependency on customer
  cache.Add(orderKey, order, dep,
    absolutionExpiration,
    slidingExpiration,
    priority, null);
}

Conclusão

Microsoft Azure é uma plataforma de nuvem poderosa e um ambiente escalável. Um cache distribuído na memória pode ser um componente importante deste ambiente. Se você já escreveu seu aplicativo do .NET Framework, então você deve considerar usar um .NET cache distribuído. Se for em Java, você tem vários Java-baseado soluções de cache distribuídas. Se você tem uma combinação de aplicativos .NET e Java , use um cache distribuído que ofereça suporte a ambos e fornece portabilidade dos dados. A maioria dos caches são totalmente focados em .NET ou Java, embora alguns suportam ambos.

Para PHP, Ruby, Python e outros aplicativos, você pode usar o Memcached. Isto suporta todos esses ambientes. Memcached não é um cache de elástico e, conseqüentemente, tem alta disponibilidade e dados -­limitações de confiabilidade. De qualquer forma, tenha em mente que um cache distribuído é uma parte sensível do seu ambiente de produção. Portanto, você deve avaliar todas as soluções de armazenamento em cache disponíveis em seu ambiente completamente e selecionar aquele que melhor atende às suas necessidades.


Iqbal Khan é o divulgador da tecnologia da Alachisoft, que fornece cache Ncache distribuído para .NET e o Microsoft Azure. Você pode contatá-lo em iqbal@alachisoft.com.

Jeremiah Talkar é um evangelista de tecnologia Microsoft Azure dentro da Microsoft desenvolvedor plataforma evangelismo corporativa equipe com 26 anos de experiência em produtos de engenharia, consultoria e vendas. Contactá-lo no jtalkar@microsoft.com.

Agradecemos aos seguintes especialistas técnicos da Microsoft pela revisão deste artigo: Scott Hunter, Masashi Narumoto e Trent Swanson