Colocação em cacheCaching

A colocação em cache é uma técnica comum que visa melhorar o desempenho e a escalabilidade de um sistema.Caching is a common technique that aims to improve the performance and scalability of a system. Fá-lo copiando temporariamente os dados acedidos com frequência para o armazenamento rápido que está localizado próximo da aplicação.It does this by temporarily copying frequently accessed data to fast storage that's located close to the application. Se este armazenamento de dados rápido estiver localizado mais próximo da aplicação que a origem original, a colocação em cache pode melhorar significativamente os tempos de resposta para aplicações cliente ao servir os dados mais rapidamente.If this fast data storage is located closer to the application than the original source, then caching can significantly improve response times for client applications by serving data more quickly.

A colocação em cache é mais eficaz quando uma instância de cliente lê repetidamente os mesmos dados, especialmente se todas as condições seguintes se aplicarem ao arquivo de dados original:Caching is most effective when a client instance repeatedly reads the same data, especially if all the following conditions apply to the original data store:

  • Permanece relativamente estático.It remains relatively static.
  • É lento em comparação com a velocidade da cache.It's slow compared to the speed of the cache.
  • Está sujeito a um elevado nível de contenção.It's subject to a high level of contention.
  • Está longe quando a latência de rede pode tornar o acesso lento.It's far away when network latency can cause access to be slow.

Colocação em cache em aplicações distribuídasCaching in distributed applications

Normalmente, as aplicações distribuídas implementam uma ou ambas as estratégias seguintes ao colocar dados em cache:Distributed applications typically implement either or both of the following strategies when caching data:

  • Com uma cache privada, onde os dados são mantidos localmente no computador que está a executar uma instância de uma aplicação ou serviço.Using a private cache, where data is held locally on the computer that's running an instance of an application or service.
  • Com uma cache partilhada, que serve como uma origem comum que pode ser acedida por vários processos e/ou computadores.Using a shared cache, serving as a common source which can be accessed by multiple processes and/or machines.

Em ambos os casos, a colocação em cache pode ser realizada do lado do cliente e/ou do lado do servidor.In both cases, caching can be performed client-side and/or server-side. A colocação em cache do lado do cliente é realizada pelo processo que fornece a interface de utilizador para um sistema, como um browser ou uma aplicação de ambiente de trabalho.Client-side caching is done by the process that provides the user interface for a system, such as a web browser or desktop application. A colocação em cache do lado do servidor é realizada pelo processo que fornece os serviços empresariais que estão a ser executados remotamente.Server-side caching is done by the process that provides the business services that are running remotely.

Colocação em cache privadaPrivate caching

O tipo mais básico de cache é um arquivo dentro da memória.The most basic type of cache is an in-memory store. É mantido no espaço de endereços de um processo único e acedido diretamente pelo código que é executado nesse processo.It's held in the address space of a single process and accessed directly by the code that runs in that process. O acesso a este tipo de cache é muito rápido.This type of cache is very quick to access. Também pode fornecer um meio extremamente eficaz para armazenar pequenas quantidades de dados estáticos, uma vez que o tamanho de uma cache normalmente é limitado pelo volume de memória que está disponível no computador que aloja o processo.It can also provide an extremely effective means for storing modest amounts of static data, since the size of a cache is typically constrained by the volume of memory that's available on the machine hosting the process.

Se precisar de colocar em cache mais informações do que é fisicamente possível na memória, pode escrever dados em cache no sistema de ficheiros local.If you need to cache more information than is physically possible in memory, you can write cached data to the local file system. O acesso a estes dados será mais lento do que aos dados mantidos dentro da memória, mas ainda assim deve ser mais rápido e mais fiável do que obter dados através de uma rede.This will be slower to access than data that's held in-memory, but should still be faster and more reliable than retrieving data across a network.

Se tiver várias instâncias de uma aplicação que utiliza este modelo em execução em simultâneo, cada instância da aplicação tem a sua própria cache independente que contém a sua própria cópia dos dados.If you have multiple instances of an application that uses this model running concurrently, each application instance has its own independent cache holding its own copy of the data.

Pense numa cache como um instantâneo dos dados originais em algum momento no passado.Think of a cache as a snapshot of the original data at some point in the past. Se estes dados não forem estáticos, é provável que diferentes instâncias da aplicação contenham versões diferentes dos dados nas respetivas caches.If this data is not static, it is likely that different application instances hold different versions of the data in their caches. Por conseguinte, a mesma consulta realizada por estas instâncias pode devolver resultados diferentes, conforme mostra a Figura 1.Therefore, the same query performed by these instances can return different results, as shown in Figure 1.

Utilizar uma cache dentro da memória em diferentes instâncias de uma aplicação

Figura 1: Utilizar uma cache de memória em diferentes instâncias de uma aplicação.Figure 1: Using an in-memory cache in different instances of an application.

Colocação em cache partilhadaShared caching

A utilização de uma cache partilhada pode ajudar a atenuar as preocupações de que os dados poderão diferir em cada cache, o que pode ocorrer com a colocação em cache dentro da memória.Using a shared cache can help alleviate concerns that data might differ in each cache, which can occur with in-memory caching. A colocação em cache partilhada garante que diferentes instâncias da aplicação veem a mesma vista de dados em cache.Shared caching ensures that different application instances see the same view of cached data. Fá-lo ao localizar a cache num local separado, normalmente alojado como parte de um serviço separado, conforme mostra a Figura 2.It does this by locating the cache in a separate location, typically hosted as part of a separate service, as shown in Figure 2.

Utilizar uma cache partilhada

Figura 2: Utilizar uma cache partilhada.Figure 2: Using a shared cache.

Uma vantagem importante da abordagem de colocação em cache partilhada é a escalabilidade que oferece.An important benefit of the shared caching approach is the scalability it provides. Muitos serviços de cache partilhada são implementados através de um cluster de servidores e utilizam software que distribui os dados pelo cluster de forma transparente.Many shared cache services are implemented by using a cluster of servers, and utilize software that distributes the data across the cluster in a transparent manner. Uma instância de aplicação simplesmente envia um pedido para o serviço de cache.An application instance simply sends a request to the cache service. A infraestrutura subjacente é responsável por determinar a localização dos dados em cache no cluster.The underlying infrastructure is responsible for determining the location of the cached data in the cluster. Pode dimensionar facilmente a cache ao adicionar mais servidores.You can easily scale the cache by adding more servers.

Existem duas desvantagens principais da abordagem de colocação em cache partilhada:There are two main disadvantages of the shared caching approach:

  • O acesso à cache é mais lento porque esta já não é mantida localmente para cada instância da aplicação.The cache is slower to access because it is no longer held locally to each application instance.
  • O requisito de implementação de um serviço de cache separado poderá adicionar complexidade à solução.The requirement to implement a separate cache service might add complexity to the solution.

Considerações sobre a utilização da colocação em cacheConsiderations for using caching

As secções seguintes descrevem mais pormenorizadamente as considerações sobre a conceção e utilização de uma cache.The following sections describe in more detail the considerations for designing and using a cache.

Decidir quando colocar dados em cacheDecide when to cache data

A colocação em cache pode melhorar significativamente o desempenho, a escalabilidade e a disponibilidade.Caching can dramatically improve performance, scalability, and availability. Quanto mais dados tiver e quanto maior for o número de utilizadores que precisam de aceder a estes dados, maiores serão as vantagens da colocação em cache.The more data that you have and the larger the number of users that need to access this data, the greater the benefits of caching become. Isto acontece porque a colocação em cache reduz a latência e a contenção associadas ao processamento de grandes volumes de pedidos simultâneos no arquivo de dados original.That's because caching reduces the latency and contention that's associated with handling large volumes of concurrent requests in the original data store.

Por exemplo, uma base de dados poderá suportar um número limitado de ligações simultâneas.For example, a database might support a limited number of concurrent connections. No entanto, a obtenção de dados de uma cache partilhada, em vez da base de dados subjacente, permite que uma aplicação cliente aceda a estes dados, mesmo se o número de ligações disponíveis estiver esgotado no momento.Retrieving data from a shared cache, however, rather than the underlying database, makes it possible for a client application to access this data even if the number of available connections is currently exhausted. Além disso, se a base de dados ficar indisponível, as aplicações cliente poderão continuar ao utilizarem os dados que são mantidos na cache.Additionally, if the database becomes unavailable, client applications might be able to continue by using the data that's held in the cache.

Considere a colocação em cache de dados que são lidos com frequência, mas modificados com pouca frequência (por exemplo, os dados que têm uma maior proporção de operações de leitura do que operações de escrita).Consider caching data that is read frequently but modified infrequently (for example, data that has a higher proportion of read operations than write operations). No entanto, não recomendamos a utilização da cache como o arquivo autoritativo de informações importantes.However, we don't recommend that you use the cache as the authoritative store of critical information. Em alternativa, certifique-se de que todas as alterações que a aplicação não se pode dar ao luxo de perder são sempre guardadas num arquivo de dados persistente.Instead, ensure that all changes that your application cannot afford to lose are always saved to a persistent data store. Isto significa que, se a cache não estiver disponível, a aplicação pode continuar a funcionar utilizando o arquivo de dados e, assim, não perderá informações importantes.This means that if the cache is unavailable, your application can still continue to operate by using the data store, and you won't lose important information.

Determinar como colocar dados em cache de forma eficazDetermine how to cache data effectively

A solução para utilizar uma cache de forma eficaz passa por determinar os dados mais adequados para colocar em cache e colocá-los em cache no momento apropriado.The key to using a cache effectively lies in determining the most appropriate data to cache, and caching it at the appropriate time. Os dados podem ser adicionados à cache a pedido da primeira vez que forem obtidos por uma aplicação.The data can be added to the cache on demand the first time it is retrieved by an application. Isto significa que a aplicação só precisa de obter os dados uma vez a partir do arquivo de dados e esse acesso subsequente pode ser satisfeito ao utilizar a cache.This means that the application needs to fetch the data only once from the data store, and that subsequent access can be satisfied by using the cache.

Em alternativa, uma cache pode ser total ou parcialmente preenchida com dados antecipadamente, normalmente quando a aplicação é iniciada (uma abordagem conhecida como seeding).Alternatively, a cache can be partially or fully populated with data in advance, typically when the application starts (an approach known as seeding). No entanto, poderá não ser aconselhável implementar o seeding para uma cache de grandes dimensões porque esta abordagem pode impor uma carga elevada repentina no arquivo de dados original quando a aplicação entrar em execução.However, it might not be advisable to implement seeding for a large cache because this approach can impose a sudden, high load on the original data store when the application starts running.

Muitas vezes, uma análise de padrões de utilização pode ajudar a decidir se deve pré-povoar total ou parcialmente uma cache e a escolher os dados a colocar em cache.Often an analysis of usage patterns can help you decide whether to fully or partially prepopulate a cache, and to choose the data to cache. Por exemplo, pode ser útil efetuar o seeding da cache com os dados de perfil de utilizador estáticos para os clientes que utilizam regularmente a aplicação (talvez todos os dias), mas não para os clientes que utilizam a aplicação apenas uma vez por semana.For example, it can be useful to seed the cache with the static user profile data for customers who use the application regularly (perhaps every day), but not for customers who use the application only once a week.

A colocação em cache normalmente funciona bem com os dados que são imutáveis ou que são alterados com pouca frequência.Caching typically works well with data that is immutable or that changes infrequently. Alguns exemplos incluem informações de referência, tais como informações sobre preços e produtos numa aplicação de comércio eletrónico, ou recursos estáticos partilhados cuja construção é dispendiosa.Examples include reference information such as product and pricing information in an e-commerce application, or shared static resources that are costly to construct. A totalidade ou parte destes dados podem ser carregados para a cache durante o arranque da aplicação para minimizar a exigência sobre os recursos e para melhorar o desempenho.Some or all of this data can be loaded into the cache at application startup to minimize demand on resources and to improve performance. Também poderá ser conveniente ter um processo em segundo plano que atualize periodicamente os dados de referência na cache para garantir que estão atualizados ou que atualize a cache quando os dados de referência forem alterados.It might also be appropriate to have a background process that periodically updates reference data in the cache to ensure it is up to date, or that refreshes the cache when reference data changes.

A colocação em cache é menos útil para dados dinâmicos, embora existam algumas exceções a esta consideração (veja a secção «Colocar em cache dados altamente dinâmicos» mais à frente neste artigo para obter mais informações).Caching is less useful for dynamic data, although there are some exceptions to this consideration (see the section Cache highly dynamic data later in this article for more information). Quando os dados originais são alterados regularmente, as informações em cache tornam-se obsoletas muito rapidamente ou a sobrecarga de sincronizar a cache com o arquivo de dados original reduz a eficácia da colocação em cache.When the original data changes regularly, either the cached information becomes stale very quickly or the overhead of synchronizing the cache with the original data store reduces the effectiveness of caching.

Tenha em atenção que uma cache não tem de incluir os dados completos de uma entidade.Note that a cache does not have to include the complete data for an entity. Por exemplo, se um item de dados representar um objeto com valores múltiplos, tal como um cliente bancário com um nome, endereço e saldo da conta, alguns destes elementos poderão permanecer estáticos (como o nome e o endereço), enquanto outros (como o saldo da conta) poderão ser mais dinâmicos.For example, if a data item represents a multivalued object such as a bank customer with a name, address, and account balance, some of these elements might remain static (such as the name and address), while others (such as the account balance) might be more dynamic. Nestas situações, pode ser útil colocar em cache as partes estáticas dos dados e obter (ou calcular) apenas as restantes informações quando forem necessárias.In these situations, it can be useful to cache the static portions of the data and retrieve (or calculate) only the remaining information when it is required.

Recomendamos a realização de testes de desempenho e análise de utilização para determinar se é adequado fazer o pré-povoamento ou o carregamento a pedido da cache, ou uma combinação de ambos.We recommend that you carry out performance testing and usage analysis to determine whether pre-population or on-demand loading of the cache, or a combination of both, is appropriate. A decisão deve basear-se no padrão de utilização e volatilidade dos dados.The decision should be based on the volatility and usage pattern of the data. A análise do desempenho e da utilização da cache é particularmente importante em aplicações que encontram cargas pesadas e têm de ser extremamente dimensionáveis.Cache utilization and performance analysis is particularly important in applications that encounter heavy loads and must be highly scalable. Por exemplo, em cenários extremamente dimensionáveis poderá fazer sentido efetuar o seeding da cache para reduzir a carga no arquivo de dados em períodos de pico.For example, in highly scalable scenarios it might make sense to seed the cache to reduce the load on the data store at peak times.

A colocação em cache também pode ser utilizada para evitar a repetição de cálculos enquanto a aplicação está em execução.Caching can also be used to avoid repeating computations while the application is running. Se uma operação transformar dados ou realizar um cálculo complicado, pode guardar os resultados da operação na cache.If an operation transforms data or performs a complicated calculation, it can save the results of the operation in the cache. Se o mesmo cálculo for necessário mais tarde, a aplicação pode simplesmente obter os resultados da cache.If the same calculation is required afterward, the application can simply retrieve the results from the cache.

Uma aplicação pode modificar os dados que são mantidos numa cache.An application can modify data that's held in a cache. No entanto, recomendamos pensar na cache como um arquivo de dados transitório que poderá desaparecer em qualquer altura.However, we recommend thinking of the cache as a transient data store that could disappear at any time. Não armazene dados valiosos apenas na cache; certifique-se de que mantém as informações também no arquivo de dados original.Do not store valuable data in the cache only; make sure that you maintain the information in the original data store as well. Isto significa que se a cache ficar indisponível, minimiza a possibilidade de perda de dados.This means that if the cache becomes unavailable, you minimize the chance of losing data.

Colocar em cache dados altamente dinâmicosCache highly dynamic data

O armazenamento de informações que mudam rapidamente num arquivo de dados persistente poderá impor uma sobrecarga no sistema.When you store rapidly-changing information in a persistent data store, it can impose an overhead on the system. Por exemplo, considere um dispositivo que reporta continuamente um estado ou qualquer outra medida.For example, consider a device that continually reports status or some other measurement. Se uma aplicação optar por não colocar em cache estes dados com base no facto de que as informações em cache estarão quase sempre desatualizadas, a mesma consideração poderá ser verdadeira ao armazenar e obter estas informações a partir do arquivo de dados.If an application chooses not to cache this data on the basis that the cached information will nearly always be outdated, then the same consideration could be true when storing and retrieving this information from the data store. No tempo que demora a guardar e a obter estes dados, poderão já ter sido alterados.In the time it takes to save and fetch this data, it might have changed.

Numa situação como esta, considere as vantagens de armazenar as informações dinâmicas diretamente na cache em vez de armazenar no arquivo de dados persistente.In a situation such as this, consider the benefits of storing the dynamic information directly in the cache instead of in the persistent data store. Se os dados não forem críticos e não precisarem de auditoria, é irrelevante se a alteração ocasional se perca.If the data is non-critical and does not require auditing, then it doesn't matter if the occasional change is lost.

Gerir a expiração de dados numa cacheManage data expiration in a cache

Na maioria dos casos, os dados que são mantidos numa cache são uma cópia dos dados que estão contidos no arquivo de dados original.In most cases, data that's held in a cache is a copy of data that's held in the original data store. Os dados no arquivo de dados original poderão sofrer alterações depois de serem colocados em cache, o que faz com que os dados em cache se tornem obsoletos.The data in the original data store might change after it was cached, causing the cached data to become stale. Muitos sistemas de colocação em cache permitem configurar a cache para expirar dados e reduzir o período durante o qual os dados podem estar desatualizados.Many caching systems enable you to configure the cache to expire data and reduce the period for which data may be out of date.

Quando os dados em cache expiram, são removidos da cache e a aplicação tem de obter os dados do arquivo de dados original (pode voltar a colocar as informações obtidas recentemente na cache).When cached data expires, it's removed from the cache, and the application must retrieve the data from the original data store (it can put the newly-fetched information back into cache). Pode definir uma política de expiração predefinida quando configurar a cache.You can set a default expiration policy when you configure the cache. Em muitos serviços de cache, também pode estipular o período de expiração para objetos individuais quando os armazena através de programação na cache.In many cache services, you can also stipulate the expiration period for individual objects when you store them programmatically in the cache. Algumas caches permitem especificar o período de expiração como um valor absoluto ou como um valor deslizante que faz com que o item seja removido da cache se não for acedido no período de tempo especificado.Some caches enable you to specify the expiration period as an absolute value, or as a sliding value that causes the item to be removed from the cache if it is not accessed within the specified time. Esta definição substitui qualquer política de expiração em toda a cache, mas apenas para os objetos especificados.This setting overrides any cache-wide expiration policy, but only for the specified objects.

Nota

Considere o período de expiração para a cache e os objetos que contém cuidadosamente.Consider the expiration period for the cache and the objects that it contains carefully. Se definir um período demasiado curto, os objetos irão expirar demasiado rápido e reduzirá as vantagens de utilizar a cache.If you make it too short, objects will expire too quickly and you will reduce the benefits of using the cache. Se definir um período demasiado longo, corre o risco de os dados se tornarem obsoletos.If you make the period too long, you risk the data becoming stale.

Também é possível que a cache fique cheia se permitir que os dados permaneçam residentes durante muito tempo.It's also possible that the cache might fill up if data is allowed to remain resident for a long time. Neste caso, quaisquer pedidos para adicionar novos itens à cache poderão causar a remoção forçada de alguns itens num processo conhecido como expulsão.In this case, any requests to add new items to the cache might cause some items to be forcibly removed in a process known as eviction. Normalmente, os serviços de cache expulsam dados numa base menos recentemente utilizados (LRU), mas, normalmente, pode substituir esta política e impedir que os itens sejam expulsos.Cache services typically evict data on a least-recently-used (LRU) basis, but you can usually override this policy and prevent items from being evicted. No entanto, se adotar esta abordagem, corre o risco de exceder a memória disponível na cache.However, if you adopt this approach, you risk exceeding the memory that's available in the cache. Uma aplicação que tente adicionar um item à cache irá falhar com uma exceção.An application that attempts to add an item to the cache will fail with an exception.

Algumas implementações de colocação em cache poderão fornecer políticas adicionais de expulsão.Some caching implementations might provide additional eviction policies. Existem vários tipos de políticas de expulsão.There are several types of eviction policies. Estas incluem:These include:

  • Uma política de dados mais recentemente utilizados (na expectativa de que os dados não vão voltar a ser precisos).A most-recently-used policy (in the expectation that the data will not be required again).
  • Uma política first-in, first-out (os dados mais antigos são expulsos em primeiro lugar).A first-in-first-out policy (oldest data is evicted first).
  • Uma política de remoção explícita com base num evento acionado (por exemplo, os dados estão a ser modificados).An explicit removal policy based on a triggered event (such as the data being modified).

Invalidar dados numa cache do lado do clienteInvalidate data in a client-side cache

Normalmente, considera-se que os dados que são mantidos numa cache do lado do cliente estão fora dos auspícios do serviço que fornece os dados ao cliente.Data that's held in a client-side cache is generally considered to be outside the auspices of the service that provides the data to the client. Um serviço não pode forçar diretamente um cliente a adicionar ou remover informações de uma cache do lado do cliente.A service cannot directly force a client to add or remove information from a client-side cache.

Isto significa que é possível que um cliente que utiliza uma cache mal configurada continue a utilizar as informações desatualizadas.This means that it's possible for a client that uses a poorly configured cache to continue using outdated information. Por exemplo, se as políticas de expiração da cache não forem corretamente implementadas, um cliente poderá utilizar informações desatualizadas que são colocadas em cache localmente quando as informações na origem de dados original forem alteradas.For example, if the expiration policies of the cache aren't properly implemented, a client might use outdated information that's cached locally when the information in the original data source has changed.

Se estiver a criar uma aplicação Web que serve os dados através de uma ligação HTTP, pode forçar implicitamente um cliente Web (por exemplo, um browser ou um proxy Web) a obter as informações mais recentes.If you are building a web application that serves data over an HTTP connection, you can implicitly force a web client (such as a browser or web proxy) to fetch the most recent information. Pode fazê-lo se um recurso for atualizado por uma alteração no URI desse recurso.You can do this if a resource is updated by a change in the URI of that resource. Normalmente,os clientes Web utilizam o URI de um recurso como chave na cache do lado do cliente, pelo que se o URI for alterado, o cliente Web ignora as versões de um recurso colocadas em cache anteriormente e obtém a nova versão.Web clients typically use the URI of a resource as the key in the client-side cache, so if the URI changes, the web client ignores any previously cached versions of a resource and fetches the new version instead.

Gerir a simultaneidade numa cacheManaging concurrency in a cache

Muitas vezes, as caches são estruturadas para serem partilhadas por várias instâncias de uma aplicação.Caches are often designed to be shared by multiple instances of an application. Cada instância da aplicação pode ler e modificar os dados na cache.Each application instance can read and modify data in the cache. Por conseguinte, os mesmo problemas de simultaneidade que surjam com qualquer arquivo de dados partilhado também se aplicam a uma cache.Consequently, the same concurrency issues that arise with any shared data store also apply to a cache. Numa situação em que uma aplicação precisa de modificar os dados que são mantidos na cache, poderá ter de certificar-se de que as atualizações feitas por uma instância da aplicação não substituem as alterações feitas por outra instância.In a situation where an application needs to modify data that's held in the cache, you might need to ensure that updates made by one instance of the application do not overwrite the changes made by another instance.

Dependendo da natureza dos dados e da probabilidade de colisões, pode adotar uma de duas abordagens à simultaneidade:Depending on the nature of the data and the likelihood of collisions, you can adopt one of two approaches to concurrency:

  • Otimista.Optimistic. Imediatamente antes de atualizar os dados, a aplicação verifica se os dados na cache foram alterados desde que foram obtidos.Immediately prior to updating the data, the application checks to see whether the data in the cache has changed since it was retrieved. Se os dados ainda forem os mesmos, a alteração pode ser feita.If the data is still the same, the change can be made. Caso contrário, a aplicação tem de decidir se pretende atualizá-los.Otherwise, the application has to decide whether to update it. (A lógica de negócio que conduz a esta decisão será específica da aplicação.) Esta abordagem é adequada para situações em que as atualizações são pouco frequentes ou em que é improvável que ocorram colisões.(The business logic that drives this decision will be application-specific.) This approach is suitable for situations where updates are infrequent, or where collisions are unlikely to occur.
  • Pessimista.Pessimistic. Quando obtém os dados, a aplicação bloqueia-os na cache para impedir que outra instância os altere.When it retrieves the data, the application locks it in the cache to prevent another instance from changing it. Este processo garante que não podem ocorrer colisões, mas também pode bloquear outras instâncias que precisam de processar os mesmos dados.This process ensures that collisions cannot occur, but they can also block other instances that need to process the same data. A simultaneidade pessimista pode afetar a escalabilidade de uma solução e é recomendada apenas para operações de curta duração.Pessimistic concurrency can affect the scalability of a solution and is recommended only for short-lived operations. Esta abordagem poderá ser adequada para situações em que as colisões sejam mais prováveis, especialmente se uma aplicação atualizar vários itens na cache e tiver de garantir que estas alterações são aplicadas de forma consistente.This approach might be appropriate for situations where collisions are more likely, especially if an application updates multiple items in the cache and must ensure that these changes are applied consistently.

Implementar a elevada disponibilidade e escalabilidade e melhorar o desempenhoImplement high availability and scalability, and improve performance

Evite utilizar uma cache como repositório principal de dados; esta é a função do arquivo de dados original a partir do qual a cache é preenchida.Avoid using a cache as the primary repository of data; this is the role of the original data store from which the cache is populated. O arquivo de dados original é responsável por assegurar a persistência dos dados.The original data store is responsible for ensuring the persistence of the data.

Tenha cuidado para não introduzir dependências críticas da disponibilidade de um serviço de cache partilhada nas suas soluções.Be careful not to introduce critical dependencies on the availability of a shared cache service into your solutions. Uma aplicação deve poder continuar a funcionar se o serviço que fornece a cache partilhada não estiver disponível.An application should be able to continue functioning if the service that provides the shared cache is unavailable. A aplicação não deve falhar ou deixar de responder enquanto aguarda que o serviço de cache seja retomado.The application should not hang or fail while waiting for the cache service to resume.

Por isso, a aplicação tem de estar preparada para detetar a disponibilidade do serviço de cache e reverter para o arquivo de dados original se a cache não estiver acessível.Therefore, the application must be prepared to detect the availability of the cache service and fall back to the original data store if the cache is inaccessible. O padrão Disjuntor é útil para processar este cenário.The Circuit-Breaker pattern is useful for handling this scenario. O serviço que fornece a cache pode ser recuperado e, depois de ficar disponível, a cache pode ser novamente preenchida à medida que os dados são lidos a partir do arquivo de dados original, seguindo uma estratégia como o padrão cache-aside.The service that provides the cache can be recovered, and once it becomes available, the cache can be repopulated as data is read from the original data store, following a strategy such as the Cache-aside pattern.

No entanto, poderá existir um impacto de escalabilidade no sistema se a aplicação reverter para o arquivo de dados original quando a cache está temporariamente indisponível.However, there might be a scalability impact on the system if the application falls back to the original data store when the cache is temporarily unavailable. Enquanto o arquivo de dados estiver a ser recuperado, o arquivo de dados original pode ser sobrecarregado com pedidos de dados, o que resulta em tempos limite e falhas de ligações.While the data store is being recovered, the original data store could be swamped with requests for data, resulting in timeouts and failed connections.

Pondere implementar uma cache local privada em cada instância de uma aplicação, juntamente com a cache partilhada à qual todas as instâncias da aplicação acedem.Consider implementing a local, private cache in each instance of an application, together with the shared cache that all application instances access. Quando a aplicação obtém um item, pode verificar primeiro na respetiva cache local, em seguida na cache partilhada e, por último, no arquivo de dados original.When the application retrieves an item, it can check first in its local cache, then in the shared cache, and finally in the original data store. A cache local pode ser preenchida com os dados na cache partilhada ou na base de dados se a cache partilhada não estiver disponível.The local cache can be populated using the data in either the shared cache, or in the database if the shared cache is unavailable.

Esta abordagem requer uma configuração cuidadosa para evitar que a cache local se torne demasiado obsoleta em relação à cache partilhada.This approach requires careful configuration to prevent the local cache from becoming too stale with respect to the shared cache. No entanto, a cache local funciona como uma memória intermédia se a cache partilhada não estiver acessível.However, the local cache acts as a buffer if the shared cache is unreachable. A Figura 3 mostra esta estrutura.Figure 3 shows this structure.

Utilizar uma cache privada local com uma cache partilhada

Figura 3: Utilizar uma cache privada local com uma cache partilhada.Figure 3: Using a local private cache with a shared cache.

Para suportar caches grandes que contêm dados de duração relativamente longa, alguns serviços cache fornecem uma opção de elevada disponibilidade que implementa a ativação pós-falha automática se a cache ficar indisponível.To support large caches that hold relatively long-lived data, some cache services provide a high-availability option that implements automatic failover if the cache becomes unavailable. Normalmente, esta abordagem envolve a replicação dos dados em cache que estão armazenados num servidor de cache primário para um servidor de cache secundário e a mudança para o servidor secundário se o servidor primário falhar ou se a conectividade se perder.This approach typically involves replicating the cached data that's stored on a primary cache server to a secondary cache server, and switching to the secondary server if the primary server fails or connectivity is lost.

Para reduzir a latência associada à escrita em vários destinos, a replicação para o servidor secundário poderá ocorrer no modo assíncrono quando os dados são escritos na cache no servidor primário.To reduce the latency that's associated with writing to multiple destinations, the replication to the secondary server might occur asynchronously when data is written to the cache on the primary server. Essa abordagem leva à possibilidade que algumas informações em cache se perderem em caso de falha, mas a proporção destes dados deve ser pequena em comparação com o tamanho geral da cache.This approach leads to the possibility that some cached information might be lost in the event of a failure, but the proportion of this data shuld be small compared to the overall size of the cache.

Se uma cache partilhada for grande, poderá ser vantajoso criar partições dos dados em cache entre os nós para reduzir as possibilidades de contenção e melhorar a escalabilidade.If a shared cache is large, it might be beneficial to partition the cached data across nodes to reduce the chances of contention and improve scalability. Muitas caches partilhadas suportam a capacidade de adicionar (e remover) dinamicamente nós e rebalancear os dados entre partições.Many shared caches support the ability to dynamically add (and remove) nodes and rebalance the data across partitions. Esta abordagem poderá envolver clustering, em que a coleção de nós é apresentada às aplicações cliente como uma única cache totalmente integrada.This approach might involve clustering, in which the collection of nodes is presented to client applications as a seamless, single cache. No entanto, internamente, os dados estão dispersos entre nós, seguindo uma estratégia de distribuição predefinida que equilibra a carga de forma uniforme.Internally, however, the data is dispersed between nodes following a predefined distribution strategy that balances the load evenly. Para obter mais informações sobre possíveis estratégias de criação de partições, consulte documentação de orientação de criação de partições de dados.For more information about possible partitioning strategies, see Data partitioning guidance.

O clustering também pode aumentar a disponibilidade da cache.Clustering can also increase the availability of the cache. Se um nó falhar, o resto da cache continua acessível.If a node fails, the remainder of the cache is still accessible. O clustering é frequentemente utilizado em conjunto com a replicação e ativação pós-falha.Clustering is frequently used in conjunction with replication and failover. Cada nó pode ser replicado e a réplica pode ser rapidamente colocada online se o nó falhar.Each node can be replicated, and the replica can be quickly brought online if the node fails.

Muitas operações de leitura e escrita são passíveis de envolver objetos ou valores de dados únicos.Many read and write operations are likely to involve single data values or objects. No entanto, por vezes poderá ser necessário armazenar ou obter rapidamente grandes volumes de dados.However, at times it might be necessary to store or retrieve large volumes of data quickly. Por exemplo, o seeding de uma cache pode implicar escrever centenas ou milhares de itens na cache.For example, seeding a cache could involve writing hundreds or thousands of items to the cache. Uma aplicação também poderá ter de obter um grande número de itens relacionados da cache como parte do mesmo pedido.An application might also need to retrieve a large number of related items from the cache as part of the same request.

Muitas caches de grande escala fornecem operações de lote para estes fins.Many large-scale caches provide batch operations for these purposes. Isto permite que uma aplicação cliente coloque um grande volume de itens num pacote num único pedido e reduz a sobrecarga que está associada à realização de um grande número de pequenos pedidos.This enables a client application to package up a large volume of items into a single request and reduces the overhead that's associated with performing a large number of small requests.

Colocação em cache e consistência eventualCaching and eventual consistency

Para que o padrão cache-aside funcione, a instância da aplicação que preenche a cache tem de ter acesso à versão mais recente e consistente dos dados.For the cache-aside pattern to work, the instance of the application that populates the cache must have access to the most recent and consistent version of the data. Num sistema que implementa a consistência eventual (por exemplo, um arquivo de dados replicado), este pode não ser o caso.In a system that implements eventual consistency (such as a replicated data store) this might not be the case.

Uma instância de uma aplicação poderá modificar um item de dados e invalidar a versão em cache desse item.One instance of an application could modify a data item and invalidate the cached version of that item. Outra instância da aplicação poderá tentar ler este item a partir de uma cache, o que provoca uma falha de acerto na cache, pelo que lê os dados do arquivo de dados e adiciona-os à cache.Another instance of the application might attempt to read this item from a cache, which causes a cache-miss, so it reads the data from the data store and adds it to the cache. No entanto, se o arquivo de dados não tiver sido totalmente sincronizado com as outras réplicas, a instância da aplicação poderá ler e preencher a cache com o valor antigo.However, if the data store has not been fully synchronized with the other replicas, the application instance could read and populate the cache with the old value.

Para obter mais informações sobre o processamento da consistência eventual, veja o Data consistency primer (Manual básico sobre a consistência dos dados).For more information about handling data consistency, see the Data consistency primer.

Proteger os dados em cacheProtect cached data

Independentemente do serviço de cache que utilizar, considere como proteger os dados que são mantidos na cache contra o acesso não autorizado.Irrespective of the cache service you use, consider how to protect the data that's held in the cache from unauthorized access. Existem duas preocupações principais:There are two main concerns:

  • A privacidade dos dados na cache.The privacy of the data in the cache.
  • A privacidade dos dados à medida que fluem entre a cache e a aplicação que está a utilizar a cache.The privacy of data as it flows between the cache and the application that's using the cache.

Para proteger os dados na cache, o serviço de cache pode implementar um mecanismo de autenticação que exige que as aplicações especifiquem o seguinte:To protect data in the cache, the cache service might implement an authentication mechanism that requires that applications specify the following:

  • As identidades que podem aceder a dados na cache.Which identities can access data in the cache.
  • As operações (leitura e escrita) que estas identidades estão autorizadas a executar.Which operations (read and write) that these identities are allowed to perform.

Para reduzir a sobrecarga associada à leitura e escrita de dados, depois de ser concedido a uma identidade acesso de escrita e/ou leitura à cache, essa identidade pode utilizar quaisquer dados na cache.To reduce overhead that's associated with reading and writing data, after an identity has been granted write and/or read access to the cache, that identity can use any data in the cache.

Se precisar de restringir o acesso a subconjuntos de dados em cache, pode executar um dos seguintes procedimentos:If you need to restrict access to subsets of the cached data, you can do one of the following:

  • Divida a cache em partições (utilizando diferentes servidores de cache) e conceda apenas acesso a identidades para as partições que devem estar autorizadas a utilizar.Split the cache into partitions (by using different cache servers) and only grant access to identities for the partitions that they should be allowed to use.
  • Encripte os dados em cada subconjunto utilizando chaves diferentes e forneça as chaves de encriptação apenas às identidades que devem ter acesso a cada subconjunto.Encrypt the data in each subset by using different keys, and provide the encryption keys only to identities that should have access to each subset. Uma aplicação cliente poderá continuar a poder obter todos os dados na cache, mas só poderá desencriptar os dados para os quais tem as chaves.A client application might still be able to retrieve all of the data in the cache, but it will only be able to decrypt the data for which it has the keys.

Também terá de proteger os dados à medida que entram e saem da cache.You must also protect the data as it flows in and out of the cache. Para tal, depende das funcionalidades de segurança fornecidas pela infraestrutura de rede que as aplicações cliente utilizam para ligar à cache.To do this, you depend on the security features provided by the network infrastructure that client applications use to connect to the cache. Se o cache for implementada com um servidor no local dentro da mesma organização que aloja as aplicações de cliente, em seguida, o isolamento da própria rede poderá não exigir que efetuar passos adicionais.If the cache is implemented using an on-site server within the same organization that hosts the client applications, then the isolation of the network itself might not require you to take additional steps. Se a cache estiver localizada remotamente e precisar de uma ligação TCP ou HTTP através de uma rede pública (como a Internet), considere a implementação de SSL.If the cache is located remotely and requires a TCP or HTTP connection over a public network (such as the Internet), consider implementing SSL.

Considerações para implementar a colocação em cache no AzureConsiderations for implementing caching in Azure

A Cache de Redis do Azure é uma implementação da cache de Redis de código aberto, que é executada como um serviço num datacenter do Azure.Azure Redis Cache is an implementation of the open source Redis cache that runs as a service in an Azure datacenter. Fornece um serviço de colocação em cache que pode ser acedido a partir de qualquer aplicação do Azure, quer a aplicação esteja implementada como um serviço cloud, um site ou dentro de uma máquina virtual do Azure.It provides a caching service that can be accessed from any Azure application, whether the application is implemented as a cloud service, a website, or inside an Azure virtual machine. As caches podem ser partilhadas por aplicações cliente que tenham a chave de acesso adequada.Caches can be shared by client applications that have the appropriate access key.

A Cache de Redis do Azure é uma solução de colocação em cache de elevado desempenho que fornece disponibilidade, escalabilidade e segurança.Azure Redis Cache is a high-performance caching solution that provides availability, scalability and security. Normalmente, é executada como um serviço distribuído por uma ou mais máquinas dedicadas.It typically runs as a service spread across one or more dedicated machines. Tenta armazenar a maior quantidade de informações possível na memória para garantir o acesso rápido.It attempts to store as much information as it can in memory to ensure fast access. Esta arquitetura visa fornecer latência baixa e débito elevado ao reduzir a necessidade de executar operações de E/S lentas.This architecture is intended to provide low latency and high throughput by reducing the need to perform slow I/O operations.

A Cache de Redis do Azure é compatível com muitas das diversas APIs que são utilizadas por aplicações cliente.Azure Redis Cache is compatible with many of the various APIs that are used by client applications. Se tiver aplicações que já utilizam a Cache de Redis do Azure em execução no local, a Cache de Redis do Azure fornece um caminho de migração rápido para a colocação em cache na cloud.If you have existing applications that already use Azure Redis Cache running on-premises, the Azure Redis Cache provides a quick migration path to caching in the cloud.

Funcionalidades de RedisFeatures of Redis

O Redis é mais do que um simples servidor de cache.Redis is more than a simple cache server. Fornece uma base de dados dentro da memória distribuída com um vasto conjunto de comandos que suporta muitos cenários comuns.It provides a distributed in-memory database with an extensive command set that supports many common scenarios. Estas são descritas posteriormente neste documento, na secção de Redis através de colocação em cache.These are described later in this document, in the section Using Redis caching. Esta secção resume algumas das principais funcionalidades fornecidas pelo Redis.This section summarizes some of the key features that Redis provides.

Redis como uma base de dados dentro da memóriaRedis as an in-memory database

O Redis suporta operações de leitura e escrita.Redis supports both read and write operations. No Redis, as escritas podem ser protegidas de falha de sistema ao serem periodicamente armazenadas num ficheiro de instantâneo local ou num ficheiro de registo só de acréscimo.In Redis, writes can be protected from system failure either by being stored periodically in a local snapshot file or in an append-only log file. Não é o caso em muitas caches (que devem ser consideradas arquivos de dados transitórios).This is not the case in many caches (which should be considered transitory data stores).

Todas as escritas são assíncronas e não impedem os clientes de ler e escrever dados.All writes are asynchronous and do not block clients from reading and writing data. Quando o Redis começa a ser executado, lê os dados a partir do ficheiro de registo ou instantâneo e utiliza-os para construir a cache dentro da memória.When Redis starts running, it reads the data from the snapshot or log file and uses it to construct the in-memory cache. Para obter mais informações, veja Redis persistence (Persistência de Redis) no site do Redis.For more information, see Redis persistence on the Redis website.

Nota

O Redis não garante que todas as escritas serão guardadas na eventualidade de ocorrer uma falha catastrófica, mas, na pior das hipóteses, poderá perder apenas alguns segundos de dados.Redis does not guarantee that all writes will be saved in the event of a catastrophic failure, but at worst you might lose only a few seconds worth of data. Lembre-se que uma cache não se destina a funcionar como uma origem de dados autoritativa e é da responsabilidade das aplicações que utilizam a cache garantir que os dados críticos são guardados com êxito num arquivo de dados adequado.Remember that a cache is not intended to act as an authoritative data source, and it is the responsibility of the applications using the cache to ensure that critical data is saved successfully to an appropriate data store. Para obter mais informações, consulte a padrão Cache-aside.For more information, see the Cache-aside pattern.

Tipos de dados de RedisRedis data types

O Redis é um arquivo de chave-valor onde os valores podem conter tipos simples ou estruturas de dados complexas, tais como hashes, listas e conjuntos.Redis is a key-value store, where values can contain simple types or complex data structures such as hashes, lists, and sets. Suporta um conjunto de operações atómicas nestes tipos de dados.It supports a set of atomic operations on these data types. As chaves podem ser permanentes ou marcadas com um TTL limitado, altura em que a chave e o seu valor correspondente são automaticamente removidos da cache.Keys can be permanent or tagged with a limited time-to-live, at which point the key and its corresponding value are automatically removed from the cache. Para obter mais informações sobre as chaves e valores de Redis, visite a página An introduction to Redis data types and abstractions (Uma introdução aos tipos de dados e abstrações de Redis) no site do Redis.For more information about Redis keys and values, visit the page An introduction to Redis data types and abstractions on the Redis website.

Replicação e clustering de RedisRedis replication and clustering

O Redis suporta a replicação mestre/subordinada para ajudar a garantir a disponibilidade e a manter o débito.Redis supports master/subordinate replication to help ensure availability and maintain throughput. As operações de escrita num nó mestre do Redis são replicadas para um ou mais nós subordinados.Write operations to a Redis master node are replicated to one or more subordinate nodes. As operações de leitura podem ser servidas pelo mestre ou por qualquer um dos subordinados.Read operations can be served by the master or any of the subordinates.

No caso de uma partição da rede, os subordinados podem continuar a servir dados e, em seguida, a ressincronizar de forma transparente com o mestre quando a ligação for restabelecida.In the event of a network partition, subordinates can continue to serve data and then transparently resynchronize with the master when the connection is reestablished. Para obter mais detalhes, visite a página Replication (Replicação) no site do Redis.For further details, visit the Replication page on the Redis website.

O redis também fornece clustering, que lhe permite particionar os dados em partições horizontais em servidores e distribuir a carga de forma transparente.Redis also provides clustering, which enables you to transparently partition data into shards across servers and spread the load. Esta funcionalidade melhora a escalabilidade porque podem ser adicionados novos servidores Redis e podem ser criadas novas partições dos dados à medida que o tamanho da cache aumenta.This feature improves scalability, because new Redis servers can be added and the data repartitioned as the size of the cache increases.

Além disso, cada servidor no cluster pode ser replicado através de replicação mestre/subordinada.Furthermore, each server in the cluster can be replicated by using master/subordinate replication. Isto garante a disponibilidade em cada um dos nós do cluster.This ensures availability across each node in the cluster. Para obter mais informações sobre clustering e fragmentação, visite a página Redis cluster tutorial (Tutorial sobre o cluster de Redis) no site do Redis.For more information about clustering and sharding, visit the Redis cluster tutorial page on the Redis website.

Utilização de memória do RedisRedis memory use

Uma cache de Redis tem um tamanho finito que depende dos recursos disponíveis no computador anfitrião.A Redis cache has a finite size that depends on the resources available on the host computer. Quando configura um servidor Redis, pode especificar a quantidade máxima de memória que este pode utilizar.When you configure a Redis server, you can specify the maximum amount of memory it can use. Também pode configurar uma chave numa cache de Redis com um prazo de expiração, após o qual é automaticamente removida da cache.You can also configure a key in a Redis cache to have an expiration time, after which it is automatically removed from the cache. Esta funcionalidade pode ajudar a impedir que a cache dentro da memória seja preenchida com dados antigos ou obsoletos.This feature can help prevent the in-memory cache from filling with old or stale data.

À medida que a memória é preenchida, o Redis pode automaticamente expulsar chaves e os respetivos valores ao seguir várias políticas.As memory fills up, Redis can automatically evict keys and their values by following a number of policies. A predefinição é LRU (menos recentemente utilizado), mas também pode selecionar outras políticas, tais como expulsar as chaves aleatoriamente ou desativar completamente a expulsão (caso este em que as tentativas de adicionar itens à cache falham se estiver cheia).The default is LRU (least recently used), but you can also select other policies such as evicting keys at random or turning off eviction altogether (in which, case attempts to add items to the cache fail if it is full). A página Using Redis as an LRU cache (Utilizar o Redis como uma cache LRU) fornece mais informações.The page Using Redis as an LRU cache provides more information.

Transações e lotes de RedisRedis transactions and batches

O Redis permite que uma aplicação cliente submeta uma série de operações que leem e escrevem dados na cache como uma transação atómica.Redis enables a client application to submit a series of operations that read and write data in the cache as an atomic transaction. Todos os comandos na transação têm a garantia de ser executados sequencialmente e nenhum comando emitido por outros clientes simultâneos será interligado entre eles.All the commands in the transaction are guaranteed to run sequentially, and no commands issued by other concurrent clients will be interwoven between them.

No entanto, estas transações não são verdadeiras como uma base de dados relacional as executaria.However, these are not true transactions as a relational database would perform them. O processamento de transações consiste em duas fases: a primeira é quando os comandos são colocados em fila e a segunda é quando os comandos são executados.Transaction processing consists of two stages--the first is when the commands are queued, and the second is when the commands are run. Durante a fase de colocação de comandos em fila, os comandos que compõem a transação são submetidos pelo cliente.During the command queuing stage, the commands that comprise the transaction are submitted by the client. Se ocorrer algum tipo de erro neste momento (por exemplo, um erro de sintaxe ou um número incorreto de parâmetros), o Redis recusa-se a processar toda a transação e elimina-a.If some sort of error occurs at this point (such as a syntax error, or the wrong number of parameters) then Redis refuses to process the entire transaction and discards it.

Durante a fase de execução, o Redis executa cada comando em fila na sequência.During the run phase, Redis performs each queued command in sequence. Se um comando falhar durante esta fase, o Redis continua com o comando em fila seguinte e não reverte os efeitos de quaisquer comandos que já tenham sido executados.If a command fails during this phase, Redis continues with the next queued command and does not roll back the effects of any commands that have already been run. Esta forma simplificada de transação ajuda a manter o desempenho e a evitar problemas de desempenho causados por contenção.This simplified form of transaction helps to maintain performance and avoid performance problems that are caused by contention.

O Redis implementa uma forma de bloqueio otimista para ajudar a manter a consistência.Redis does implement a form of optimistic locking to assist in maintaining consistency. Para obter informações detalhadas sobre transações e o bloqueio com Redis, visite a página Transactions (Transações) no site do Redis.For detailed information about transactions and locking with Redis, visit the Transactions page on the Redis website.

O Redis também suporta a criação de batches não transacional de pedidos.Redis also supports non-transactional batching of requests. O protocolo de Redis que os clientes utilizam para enviar comandos para um servidor Redis permite que um cliente envie uma série de operações como parte do mesmo pedido.The Redis protocol that clients use to send commands to a Redis server enables a client to send a series of operations as part of the same request. Isto pode ajudar a reduzir a fragmentação de pacotes na rede.This can help to reduce packet fragmentation on the network. Quando o lote é processado, cada comando é executado.When the batch is processed, each command is performed. Se qualquer um destes comandos estiver incorreto, será rejeitado (o que não acontece com uma transação), mas os comandos restantes serão executados.If any of these commands are malformed, they will be rejected (which doesn't happen with a transaction), but the remaining commands will be performed. Também não existe qualquer garantia sobre a ordem pela qual os comandos no lote serão processados.There is also no guarantee about the order in which the commands in the batch will be processed.

Segurança de RedisRedis security

O Redis concentra-se puramente em fornecer acesso rápido aos dados e foi concebido para ser executado dentro de um ambiente fidedigno, que pode ser acedido apenas por clientes fidedignos.Redis is focused purely on providing fast access to data, and is designed to run inside a trusted environment that can be accessed only by trusted clients. O Redis suporta um modelo de segurança limitada com base na autenticação por palavra-passe.Redis supports a limited security model based on password authentication. (É possível remover completamente a autenticação, apesar de não ser recomendável.)(It is possible to remove authentication completely, although we don't recommend this.)

Todos os clientes autenticados partilham a mesma palavra-passe global e têm acesso aos mesmos recursos.All authenticated clients share the same global password and have access to the same resources. Se precisar de segurança de início de sessão mais completa, tem de implementar a sua própria camada de segurança no servidor Redis e todos os pedidos de cliente devem passar por esta camada adicional.If you need more comprehensive sign-in security, you must implement your own security layer in front of the Redis server, and all client requests should pass through this additional layer. O Redis não deve ser exposto diretamente a clientes não fidedignos ou não autenticados.Redis should not be directly exposed to untrusted or unauthenticated clients.

Pode restringir o acesso aos comandos ao desativá-los ou mudar o nome dos mesmos (e ao fornecer os novos nomes apenas a clientes com privilégios).You can restrict access to commands by disabling them or renaming them (and by providing only privileged clients with the new names).

O Redis não suporta diretamente qualquer forma de encriptação de dados, pelo que toda a codificação tem de ser executada por aplicações cliente.Redis does not directly support any form of data encryption, so all encoding must be performed by client applications. Além disso, o Redis não fornece qualquer forma de segurança de transporte.Additionally, Redis does not provide any form of transport security. Se precisar de proteger os dados à medida que fluem através da rede, recomendamos a implementação de um proxy SSL.If you need to protect data as it flows across the network, we recommend implementing an SSL proxy.

Para obter mais informações, visite a página Redis security (Segurança de Redis) no site do Redis.For more information, visit the Redis security page on the Redis website.

Nota

A Cache de Redis do Azure fornece a sua própria camada de segurança através da qual os clientes se ligam.Azure Redis Cache provides its own security layer through which clients connect. Os servidores Redis subjacentes não são expostos à rede pública.The underlying Redis servers are not exposed to the public network.

Cache de Redis do AzureAzure Redis cache

A Cache de Redis do Azure fornece acesso aos servidores Redis que são alojados num datacenter do Azure.Azure Redis Cache provides access to Redis servers that are hosted at an Azure datacenter. Funciona como uma fachada que fornece controlo de acesso e segurança.It acts as a façade that provides access control and security. Pode aprovisionar uma cache com o portal do Azure.You can provision a cache by using the Azure portal.

O portal fornece diversas configurações predefinidas.The portal provides a number of predefined configurations. Estas variam desde uma cache de 53 GB em execução como um serviço dedicado que suporta comunicações SSL (para privacidade) e replicação mestre/subordinada com um SLA de 99,9% de disponibilidade, até uma cache de 250 MB sem replicação (sem garantias de disponibilidade) em execução em hardware partilhado.These range from a 53 GB cache running as a dedicated service that supports SSL communications (for privacy) and master/subordinate replication with an SLA of 99.9% availability, down to a 250 MB cache without replication (no availability guarantees) running on shared hardware.

Com o portal do Azure, também pode configurar a política de expulsão da cache e controlar o acesso à cache ao adicionar utilizadores às funções fornecidas.Using the Azure portal, you can also configure the eviction policy of the cache, and control access to the cache by adding users to the roles provided. Estas funções, que definem as operações que os membros podem executar, incluem proprietário, Contribuidor e leitor.These roles, which define the operations that members can perform, include Owner, Contributor, and Reader. Por exemplo, os membros da função Proprietário têm controlo total sobre a cache (incluindo segurança) e os respetivos conteúdos, os membros da função Contribuidor podem ler e escrever informações na cache e os membros da função Leitor só podem obter dados da cache.For example, members of the Owner role have complete control over the cache (including security) and its contents, members of the Contributor role can read and write information in the cache, and members of the Reader role can only retrieve data from the cache.

A maioria das tarefas administrativas são realizadas através do portal do Azure.Most administrative tasks are performed through the Azure portal. Por este motivo, muitos dos comandos administrativos que estão disponíveis na versão standard do Redis não estão disponíveis, incluindo a capacidade de modificar a configuração através de programação, encerrar o servidor Redis, configurar subordinados adicionais ou guardar à força dados no disco.For this reason, many of the administrative commands that are available in the standard version of Redis are not available, including the ability to modify the configuration programmatically, shut down the Redis server, configure additional subordinates, or forcibly save data to disk.

O portal do Azure inclui uma visualização gráfica conveniente que lhe permite monitorizar o desempenho da cache.The Azure portal includes a convenient graphical display that enables you to monitor the performance of the cache. Por exemplo, pode ver o número de ligações que estão a ser estabelecidas, o número de pedidos que estão a ser realizados, o volume de leituras e escritas, e o número de acertos na cache por oposição às falhas de acerto na cache.For example, you can view the number of connections being made, the number of requests being performed, the volume of reads and writes, and the number of cache hits versus cache misses. Com estas informações, pode determinar a eficácia da cache e, se for necessário, mudar para uma configuração diferente ou alterar a política de expulsão.Using this information, you can determine the effectiveness of the cache and if necessary, switch to a different configuration or change the eviction policy.

Além disso, pode criar alertas que enviam mensagens de e-mail a um administrador se uma ou mais métricas críticas estiverem fora de um intervalo esperado.Additionally, you can create alerts that send email messages to an administrator if one or more critical metrics fall outside of an expected range. Por exemplo, poderá querer alertar um administrador se o número de falhas de acerto na cache exceder um valor especificado na última hora, porque significa que a cache poderá ser demasiado pequena ou os dados poderão estar a ser expulsos de forma demasiado rápida.For example, you might want to alert an administrator if the number of cache misses exceeds a specified value in the last hour, because it means the cache might be too small or data might be being evicted too quickly.

Também pode monitorizar a CPU, memória e utilização da rede para a cache.You can also monitor the CPU, memory, and network usage for the cache.

Para obter mais informações e exemplos que mostram como criar e configurar uma Cache de Redis do Azure, visite a página Lap around Azure Redis Cache (Uma volta em torno da Cache de Redis do Azure) no blogue do Azure.For further information and examples showing how to create and configure an Azure Redis Cache, visit the page Lap around Azure Redis Cache on the Azure blog.

Colocação em cache do estado de sessão e da saída HTMLCaching session state and HTML output

Se estiver a criar aplicações Web ASP.NET que são executadas através de funções da Web do Azure, pode guardar as informações sobre o estado de sessão e saída HTML numa Cache de Redis do Azure.If you're building ASP.NET web applications that run by using Azure web roles, you can save session state information and HTML output in an Azure Redis Cache. O fornecedor de estado de sessão para a Cache de Redis do Azure permite-lhe partilhar informações de sessão entre instâncias diferentes de uma aplicação Web ASP.NET e é muito útil em situações de web farm em que a afinidade de cliente-servidor não está disponível e a colocação em cache de dados de sessão dentro da memória não seria adequada.The session state provider for Azure Redis Cache enables you to share session information between different instances of an ASP.NET web application, and is very useful in web farm situations where client-server affinity is not available and caching session data in-memory would not be appropriate.

A utilização do fornecedor de estado de sessão com a Cache de Redis do Azure oferece várias vantagens, incluindo:Using the session state provider with Azure Redis Cache delivers several benefits, including:

  • Partilha do estado de sessão com um grande número de instâncias de aplicações Web ASP.NET.Sharing session state with a large number of instances of ASP.NET web applications.
  • Fornecimento de escalabilidade melhorada.Providing improved scalability.
  • Suporte de acesso simultâneo controlado aos mesmos dados de estado de sessão para vários leitores e um único escritor.Supporting controlled, concurrent access to the same session state data for multiple readers and a single writer.
  • Utilização da compressão para poupar memória e melhorar o desempenho da rede.Using compression to save memory and improve network performance.

Para obter mais informações, veja Fornecedor de estado de sessão ASP.NET para a Cache de Redis do Azure.For more information, see ASP.NET session state provider for Azure Redis Cache.

Nota

Não utilize o fornecedor de estado de sessão para a Cache de Redis do Azure com aplicações ASP.NET que são executadas fora do ambiente do Azure.Do not use the session state provider for Azure Redis Cache with ASP.NET applications that run outside of the Azure environment. A latência do acesso à cache de fora do Azure pode eliminar os benefícios de desempenho da colocação em cache de dados.The latency of accessing the cache from outside of Azure can eliminate the performance benefits of caching data.

Da mesma forma, o fornecedor de cache de saída para a Cache de Redis do Azure permite-lhe guardar as respostas HTTP geradas por uma aplicação Web ASP.NET.Similarly, the output cache provider for Azure Redis Cache enables you to save the HTTP responses generated by an ASP.NET web application. A utilização do fornecedor de cache de saída com a Cache de Redis do Azure pode melhorar os tempos de resposta das aplicações que compõem uma saída HTML complexa.Using the output cache provider with Azure Redis Cache can improve the response times of applications that render complex HTML output. As instâncias de aplicações que geram respostas semelhantes podem fazer uso dos fragmentos de saída partilhados na cache em vez de gerarem novamente esta saída HTML.Application instances that generate similar responses can make use of the shared output fragments in the cache rather than generating this HTML output afresh. Para obter mais informações, veja Fornecedor de cache de saída ASP.NET para a Cache de Redis do Azure.For more information, see ASP.NET output cache provider for Azure Redis Cache.

Criar uma cache de Redis personalizadaBuilding a custom Redis cache

A Cache de Redis do Azure funciona como uma fachada para os servidores Redis subjacentes.Azure Redis Cache acts as a façade to the underlying Redis servers. Se precisar de uma configuração avançada que não esteja abrangida pela cache de Redis do Azure (por exemplo, uma cache superior a 53 GB), pode criar e alojar os seus próprios servidores Redis através da utilização de máquinas virtuais do Azure.If you require an advanced configuration that is not covered by the Azure Redis cache (such as a cache bigger than 53 GB) you can build and host your own Redis servers by using Azure virtual machines.

Este é um processo potencialmente complexo, pois poderá ter de criar várias VMs para funcionarem como nós mestres e subordinados se pretender implementar a replicação.This is a potentially complex process because you might need to create several VMs to act as master and subordinate nodes if you want to implement replication. Além disso, se pretender criar um cluster, precisa de vários servidores mestres e subordinados.Furthermore, if you wish to create a cluster, then you need multiple masters and subordinate servers. Uma topologia de replicação em cluster mínima que fornece um nível elevado de disponibilidade e escalabilidade inclui, pelo menos, seis VMs organizadas como três pares de servidores mestre/subordinado (um cluster tem de conter, pelo menos, três nós mestres).A minimal clustered replication topology that provides a high degree of availability and scalability comprises at least six VMs organized as three pairs of master/subordinate servers (a cluster must contain at least three master nodes).

Cada par de mestre/subordinado deve estar localizado próximo entre si para minimizar a latência.Each master/subordinate pair should be located close together to minimize latency. No entanto, cada conjunto de pares pode ser executado em datacenters diferentes do Azure, localizados em regiões diferentes, se pretender localizar os dados em cache próximos das aplicações que têm maior probabilidade de os utilizar.However, each set of pairs can be running in different Azure datacenters located in different regions, if you wish to locate cached data close to the applications that are most likely to use it. Para ver um exemplo de criação e configuração de um nó de Redis em execução como uma VM do Azure, veja Running Redis on a CentOS Linux VM in Azure (Executar o Redis numa VM Linux CentOS no Azure).For an example of building and configuring a Redis node running as an Azure VM, see Running Redis on a CentOS Linux VM in Azure.

Nota

Tenha em atenção que se implementar a sua própria cache de Redis desta forma, é responsável pela monitorização, gestão e proteção do serviço.Please note that if you implement your own Redis cache in this way, you are responsible for monitoring, managing, and securing the service.

Criação de partições de uma cache de RedisPartitioning a Redis cache

A criação de partições da cache envolve a divisão da cache em vários computadores.Partitioning the cache involves splitting the cache across multiple computers. Esta estrutura oferece várias vantagens em relação à utilização de um único servidor de cache, incluindo:This structure gives you several advantages over using a single cache server, including:

  • Criação de uma cache que é muito maior do que a que pode ser armazenada num único servidor.Creating a cache that is much bigger than can be stored on a single server.
  • Distribuição de dados entre servidores, melhorando a disponibilidade.Distributing data across servers, improving availability. Se um servidor falhar ou ficar inacessível, os dados que contém não estão disponíveis, mas continua a ser possível aceder aos dados nos restantes servidores.If one server fails or becomes inaccessible, the data that it holds is unavailable, but the data on the remaining servers can still be accessed. Para uma cache, isto não é crucial porque os dados em cache são apenas uma cópia transitória dos dados que estão contidos numa base de dados.For a cache, this is not crucial because the cached data is only a transient copy of the data that's held in a database. Os dados em cache num servidor que fique inacessível podem ser colocados em cache num servidor diferente.Cached data on a server that becomes inaccessible can be cached on a different server instead.
  • Distribuição da carga entre servidores, melhorando assim o desempenho e a escalabilidade.Spreading the load across servers, thereby improving performance and scalability.
  • Geolocalização dos dados perto dos utilizadores que acedem aos mesmos, reduzindo assim a latência.Geolocating data close to the users that access it, thus reducing latency.

Para uma cache, a forma mais comum de criação de partições é a fragmentação.For a cache, the most common form of partitioning is sharding. Nesta estratégia, cada partição (ou fragmento) é uma cache de Redis por direito próprio.In this strategy, each partition (or shard) is a Redis cache in its own right. Os dados são direcionados para uma partição específica, utilizando a lógica de fragmentação, que pode utilizar várias abordagens para distribuir os dados.Data is directed to a specific partition by using sharding logic, which can use a variety of approaches to distribute the data. O artigo Padrão de fragmentação fornece mais informações sobre a implementação da fragmentação.The Sharding pattern provides more information about implementing sharding.

Para implementar a criação de partições numa cache de Redis, pode adotar uma das abordagens seguintes:To implement partitioning in a Redis cache, you can take one of the following approaches:

  • Encaminhamento de consulta do lado do servidor.Server-side query routing. Nesta técnica, uma aplicação cliente envia um pedido para qualquer um dos servidores Redis que compõem a cache (provavelmente, o servidor mais próximo).In this technique, a client application sends a request to any of the Redis servers that comprise the cache (probably the closest server). Cada servidor Redis armazena os metadados que descrevem a partição que contém e também inclui informações sobre as partições que estão localizadas noutros servidores.Each Redis server stores metadata that describes the partition that it holds, and also contains information about which partitions are located on other servers. O servidor Redis examina o pedido de cliente.The Redis server examines the client request. Se puder ser resolvido localmente, irá executar a operação pedida.If it can be resolved locally, it will perform the requested operation. Caso contrário, reencaminhará o pedido para o servidor adequado.Otherwise it will forward the request on to the appropriate server. Este modelo é implementado pelo clustering de Redis e está descrito com maior detalhe na página Redis cluster tutorial (Tutorial do cluster Redis) no site do Redis.This model is implemented by Redis clustering, and is described in more detail on the Redis cluster tutorial page on the Redis website. O clustering de Redis é transparente para as aplicações cliente e podem ser adicionados servidores Redis adicionais ao cluster (e os dados podem ser particionados novamente) sem ser preciso que reconfigure os clientes.Redis clustering is transparent to client applications, and additional Redis servers can be added to the cluster (and the data re-partitioned) without requiring that you reconfigure the clients.
  • Criação de partições do lado do cliente.Client-side partitioning. Neste modelo, a aplicação cliente contém a lógica (possivelmente sob a forma de uma biblioteca) que encaminha os pedidos para o servidor Redis adequado.In this model, the client application contains logic (possibly in the form of a library) that routes requests to the appropriate Redis server. Esta abordagem pode ser utilizada com a Cache de Redis do Azure.This approach can be used with Azure Redis Cache. Crie várias Caches de Redis do Azure (uma para cada partição de dados) e implemente a lógica do lado do cliente que encaminha os pedidos para a cache correta.Create multiple Azure Redis Caches (one for each data partition) and implement the client-side logic that routes the requests to the correct cache. Se o esquema de criação de partições for alterado (por exemplo, se forem criadas Caches de Redis do Azure adicionais), as aplicações cliente poderão ter de ser reconfiguradas.If the partitioning scheme changes (if additional Azure Redis Caches are created, for example), client applications might need to be reconfigured.
  • Criação de partições assistida por proxy.Proxy-assisted partitioning. Neste esquema, as aplicações cliente enviam pedidos para um serviço de proxy intermediário que compreende como os dados estão particionados e, em seguida, encaminha o pedido para o servidor Redis adequado.In this scheme, client applications send requests to an intermediary proxy service which understands how the data is partitioned and then routes the request to the appropriate Redis server. Esta abordagem também pode ser utilizada com a Cache de Redis do Azure; o serviço de proxy pode ser implementado como um serviço cloud do Azure.This approach can also be used with Azure Redis Cache; the proxy service can be implemented as an Azure cloud service. Esta abordagem requer um nível adicional de complexidade para implementar o serviço e os pedidos poderão demorar mais tempo a serem executados do que com a criação de partições do lado do cliente.This approach requires an additional level of complexity to implement the service, and requests might take longer to perform than using client-side partitioning.

A página Partitioning: how to split data among multiple Redis instances (Criação de partições: como dividir dados entre várias instâncias de Redis), no site do Redis, fornece mais informações sobre a implementação da criação de partições com o Redis.The page Partitioning: how to split data among multiple Redis instances on the Redis website provides further information about implementing partitioning with Redis.

Implementar aplicações cliente da cache de RedisImplement Redis cache client applications

O Redis suporta aplicações cliente escritas em várias linguagens de programação.Redis supports client applications written in numerous programming languages. Se estiver a criar novas aplicações utilizando o .NET Framework, a abordagem recomendada é utilizar a biblioteca de cliente StackExchange.Redis.If you are building new applications by using the .NET Framework, the recommended approach is to use the StackExchange.Redis client library. Esta biblioteca fornece um modelo de objeto do .NET Framework que resume os detalhes da ligação a um servidor Redis, do envio de comandos e da receção de respostas.This library provides a .NET Framework object model that abstracts the details for connecting to a Redis server, sending commands, and receiving responses. Está disponível no Visual Studio como um pacote NuGet.It is available in Visual Studio as a NuGet package. Pode utilizar esta mesma biblioteca para ligar a uma Cache de Redis do Azure ou a uma cache de Redis personalizada alojada numa VM.You can use this same library to connect to an Azure Redis Cache, or a custom Redis cache hosted on a VM.

Para ligar a um servidor Redis, utilize o método Connect estático da classe ConnectionMultiplexer.To connect to a Redis server you use the static Connect method of the ConnectionMultiplexer class. A ligação que este método cria foi concebida para ser utilizada ao longo da duração da aplicação cliente e a mesma ligação pode ser utilizada por vários threads em simultâneo.The connection that this method creates is designed to be used throughout the lifetime of the client application, and the same connection can be used by multiple concurrent threads. Não voltar a ligar e desligar sempre que executar uma operação de Redis porque pode degradar o desempenho.Do not reconnect and disconnect each time you perform a Redis operation because this can degrade performance.

Pode especificar os parâmetros de ligação, tais como o endereço do anfitrião de Redis e a palavra-passe.You can specify the connection parameters, such as the address of the Redis host and the password. Se estiver a utilizar a Cache de Redis do Azure, a palavra-passe é qualquer um da chave primária ou secundária que é gerada para a Cache de Redis do Azure com o portal de gestão do Azure.If you are using Azure Redis Cache, the password is either the primary or secondary key that is generated for Azure Redis Cache by using the Azure Management portal.

Depois de ligar ao servidor Redis, pode obter um identificador na base de dados Redis que funciona como a cache.After you have connected to the Redis server, you can obtain a handle on the Redis database that acts as the cache. A ligação de Redis fornece o método GetDatabase para fazê-lo.The Redis connection provides the GetDatabase method to do this. Em seguida, pode obter itens da cache e armazenar dados na cache utilizando os métodos StringGet e StringSet.You can then retrieve items from the cache and store data in the cache by using the StringGet and StringSet methods. Estes métodos esperam uma chave como parâmetro e devolvem o item na cache que tem um valor correspondente (StringGet) ou adicionam o item à cache com esta chave (StringSet).These methods expect a key as a parameter, and return the item either in the cache that has a matching value (StringGet) or add the item to the cache with this key (StringSet).

Consoante a localização do servidor Redis, muitas operações podem estar sujeitas a alguma latência enquanto um pedido é transmitido para o servidor e uma resposta é devolvida ao cliente.Depending on the location of the Redis server, many operations might incur some latency while a request is transmitted to the server and a response is returned to the client. A biblioteca StackExchange fornece versões assíncronas de muitos dos métodos que expõe para ajudar as aplicações cliente a manterem-se reativas.The StackExchange library provides asynchronous versions of many of the methods that it exposes to help client applications remain responsive. Estes métodos suportam o padrão assíncrono baseado em tarefa no .NET Framework.These methods support the Task-based Asynchronous pattern in the .NET Framework.

O fragmento de código seguinte mostra um método denominado RetrieveItem.The following code snippet shows a method named RetrieveItem. Ilustra uma implementação do padrão cache-aside com base no Redis e na biblioteca StackExchange.It illustrates an implementation of the cache-aside pattern based on Redis and the StackExchange library. O método assume um valor de chave de cadeia e tenta obter o item correspondente da cache de Redis, chamando o método StringGetAsync (a versão assíncrona de StringGet).The method takes a string key value and attempts to retrieve the corresponding item from the Redis cache by calling the StringGetAsync method (the asynchronous version of StringGet).

Se o item não for encontrado, é obtido a partir da origem de dados subjacente com o método GetItemFromDataSourceAsync (que é um método local e não faz parte da biblioteca StackExchange).If the item is not found, it is fetched from the underlying data source using the GetItemFromDataSourceAsync method (which is a local method and not part of the StackExchange library). Em seguida, é adicionado à cache através do método StringSetAsync, para que possa ser obtido mais rapidamente da próxima vez.It's then added to the cache by using the StringSetAsync method so it can be retrieved more quickly next time.

// Connect to the Azure Redis cache
ConfigurationOptions config = new ConfigurationOptions();
config.EndPoints.Add("<your DNS name>.redis.cache.windows.net");
config.Password = "<Redis cache key from management portal>";
ConnectionMultiplexer redisHostConnection = ConnectionMultiplexer.Connect(config);
IDatabase cache = redisHostConnection.GetDatabase();
...
private async Task<string> RetrieveItem(string itemKey)
{
    // Attempt to retrieve the item from the Redis cache
    string itemValue = await cache.StringGetAsync(itemKey);

    // If the value returned is null, the item was not found in the cache
    // So retrieve the item from the data source and add it to the cache
    if (itemValue == null)
    {
        itemValue = await GetItemFromDataSourceAsync(itemKey);
        await cache.StringSetAsync(itemKey, itemValue);
    }

    // Return the item
    return itemValue;
}

Os métodos StringGet e StringSet não estão limitados à obtenção ou armazenamento de valores de cadeia.The StringGet and StringSet methods are not restricted to retrieving or storing string values. Podem aceitar qualquer item que esteja serializado como uma matriz de bytes.They can take any item that is serialized as an array of bytes. Se precisar de guardar um objeto .NET, pode serializá-lo como um fluxo de bytes e utilizar o método StringSet para gravá-lo na cache.If you need to save a .NET object, you can serialize it as a byte stream and use the StringSet method to write it to the cache.

Da mesma forma, pode ler um objeto da cache através do método StringGet e anular a serialização do mesmo como um objeto .NET.Similarly, you can read an object from the cache by using the StringGet method and deserializing it as a .NET object. O código seguinte mostra um conjunto de métodos de extensão para a interface IDatabase (o método GetDatabase de uma ligação de Redis devolve um objeto IDatabase) e algum código de exemplo que utiliza estes métodos para ler e escrever um objeto BlogPost na cache:The following code shows a set of extension methods for the IDatabase interface (the GetDatabase method of a Redis connection returns an IDatabase object), and some sample code that uses these methods to read and write a BlogPost object to the cache:

public static class RedisCacheExtensions
{
    public static async Task<T> GetAsync<T>(this IDatabase cache, string key)
    {
        return Deserialize<T>(await cache.StringGetAsync(key));
    }

    public static async Task<object> GetAsync(this IDatabase cache, string key)
    {
        return Deserialize<object>(await cache.StringGetAsync(key));
    }

    public static async Task SetAsync(this IDatabase cache, string key, object value)
    {
        await cache.StringSetAsync(key, Serialize(value));
    }

    static byte[] Serialize(object o)
    {
        byte[] objectDataAsStream = null;

        if (o != null)
        {
            BinaryFormatter binaryFormatter = new BinaryFormatter();
            using (MemoryStream memoryStream = new MemoryStream())
            {
                binaryFormatter.Serialize(memoryStream, o);
                objectDataAsStream = memoryStream.ToArray();
            }
        }

        return objectDataAsStream;
    }

    static T Deserialize<T>(byte[] stream)
    {
        T result = default(T);

        if (stream != null)
        {
            BinaryFormatter binaryFormatter = new BinaryFormatter();
            using (MemoryStream memoryStream = new MemoryStream(stream))
            {
                result = (T)binaryFormatter.Deserialize(memoryStream);
            }
        }

        return result;
    }
}

O código seguinte ilustra um método denominado RetrieveBlogPost que utiliza estes métodos de extensão para ler e escrever um objeto BlogPost serializável na cache, seguindo o padrão cache-aside:The following code illustrates a method named RetrieveBlogPost that uses these extension methods to read and write a serializable BlogPost object to the cache following the cache-aside pattern:

// The BlogPost type
[Serializable]
public class BlogPost
{
    private HashSet<string> tags;

    public BlogPost(int id, string title, int score, IEnumerable<string> tags)
    {
        this.Id = id;
        this.Title = title;
        this.Score = score;
        this.tags = new HashSet<string>(tags);
    }

    public int Id { get; set; }
    public string Title { get; set; }
    public int Score { get; set; }
    public ICollection<string> Tags => this.tags;
}
...
private async Task<BlogPost> RetrieveBlogPost(string blogPostKey)
{
    BlogPost blogPost = await cache.GetAsync<BlogPost>(blogPostKey);
    if (blogPost == null)
    {
        blogPost = await GetBlogPostFromDataSourceAsync(blogPostKey);
        await cache.SetAsync(blogPostKey, blogPost);
    }

    return blogPost;
}

O Redis suporta o pipelining de comandos se uma aplicação cliente enviar vários pedidos assíncronos.Redis supports command pipelining if a client application sends multiple asynchronous requests. O Redis pode executar a multiplexação dos pedidos com a mesma ligação em vez de receber e responder a comandos numa sequência estrita.Redis can multiplex the requests using the same connection rather than receiving and responding to commands in a strict sequence.

Esta abordagem ajuda a reduzir a latência, fazendo uma utilização mais eficiente da rede.This approach helps to reduce latency by making more efficient use of the network. O fragmento de código seguinte mostra um exemplo que obtém os detalhes de dois clientes em simultâneo.The following code snippet shows an example that retrieves the details of two customers concurrently. O código submete dois pedidos e, em seguida, executa mais algum processamento (não apresentado) antes de ficar à espera de receber os resultados.The code submits two requests and then performs some other processing (not shown) before waiting to receive the results. O método Wait do objeto de cache é semelhante ao método Task.Wait do .NET Framework:The Wait method of the cache object is similar to the .NET Framework Task.Wait method:

ConnectionMultiplexer redisHostConnection = ...;
IDatabase cache = redisHostConnection.GetDatabase();
...
var task1 = cache.StringGetAsync("customer:1");
var task2 = cache.StringGetAsync("customer:2");
...
var customer1 = cache.Wait(task1);
var customer2 = cache.Wait(task2);

Para obter informações adicionais sobre como escrever aplicações cliente que podem o Cache de Redis do Azure, consulte a Cache do Azure para a documentação do Redis.For additional information on writing client applications that can the Azure Redis Cache, see the Azure Cache for Redis documentation. Também estão disponíveis mais informações em StackExchange.Redis.More information is also available at StackExchange.Redis.

A página Pipelines and multiplexers (Pipelines e multiplexadores), no mesmo site, fornece mais informações sobre operações assíncronas e pipelines com o Redis e a biblioteca StackExchange.The page Pipelines and multiplexers on the same website provides more information about asynchronous operations and pipelining with Redis and the StackExchange library.

Utilizar a colocação em cache de RedisUsing Redis caching

A utilização mais simples do Redis para questões de colocação em cache consiste nos pares chave-valor, em que o valor é uma cadeia não interpretada de comprimento arbitrário que pode conter quaisquer dados binários.The simplest use of Redis for caching concerns is key-value pairs where the value is an uninterpreted string of arbitrary length that can contain any binary data. (É essencialmente uma matriz de bytes que pode ser tratada como uma cadeia de caracteres).(It is essentially an array of bytes that can be treated as a string). Este cenário foi ilustrado na secção Implementar aplicações cliente da cache de Redis mais atrás neste artigo.This scenario was illustrated in the section Implement Redis Cache client applications earlier in this article.

Tenha em atenção que as chaves também contêm dados não interpretados, pelo que pode utilizar informações binárias como a chave.Note that keys also contain uninterpreted data, so you can use any binary information as the key. No entanto, quanto mais longa for a chave, mais espaço de armazenamento ocupará, e mais tempo demorará a executar operações de pesquisa.The longer the key is, however, the more space it will take to store, and the longer it will take to perform lookup operations. Por questões de capacidade de utilização e facilidade de manutenção, estruture cuidadosamente o seu espaço de chaves e utilize chaves explicativas (mas não verbosas).For usability and ease of maintenance, design your keyspace carefully and use meaningful (but not verbose) keys.

Por exemplo, utilize chaves estruturadas, tais como o "cliente:100" para representar a chave para o cliente com o ID 100 em vez de simplesmente "100".For example, use structured keys such as "customer:100" to represent the key for the customer with ID 100 rather than simply "100". Este esquema permite facilmente fazer a distinção entre os valores que armazenam diferentes tipos de dados.This scheme enables you to easily distinguish between values that store different data types. Por exemplo, também podia utilizar a chave "pedidos:100" para representar a chave para o pedido com o ID 100.For example, you could also use the key "orders:100" to represent the key for the order with ID 100.

Para além das cadeias binárias unidimensionais, um valor num par chave-valor de Redis também pode conter informações mais estruturadas, incluindo listas, conjuntos (ordenados e não ordenados) e hashes.Apart from one-dimensional binary strings, a value in a Redis key-value pair can also hold more structured information, including lists, sets (sorted and unsorted), and hashes. O Redis fornece um conjunto de comandos abrangente que pode manipular estes tipos e muitos destes comandos estão disponíveis para aplicações .NET Framework através de uma biblioteca de cliente, como StackExchange.Redis provides a comprehensive command set that can manipulate these types, and many of these commands are available to .NET Framework applications through a client library such as StackExchange. A página An introduction to Redis data types and abstractions (Uma introdução aos tipos de dados e abstrações de Redis), no site do Redis, fornece uma descrição geral mais detalhada destes tipos e dos comandos que pode utilizar para manipulá-los.The page An introduction to Redis data types and abstractions on the Redis website provides a more detailed overview of these types and the commands that you can use to manipulate them.

Esta secção resume alguns casos de utilização comuns para estes tipos de dados e comandos.This section summarizes some common use cases for these data types and commands.

Executar operações atómicas e de lotePerform atomic and batch operations

O Redis suporta uma série de operações get e set atómicas em valores de cadeia.Redis supports a series of atomic get-and-set operations on string values. Estas operações eliminam os possíveis riscos de race que poderão ocorrer ao utilizar comandos GET e SET separados.These operations remove the possible race hazards that might occur when using separate GET and SET commands. As operações que estão disponíveis incluem:The operations that are available include:

  • INCR, INCRBY, DECR e DECRBY, que executam operações atómicas de incremento e diminuição em valores de dados numéricos inteiros.INCR, INCRBY, DECR, and DECRBY, which perform atomic increment and decrement operations on integer numeric data values. A biblioteca StackExchange fornece versões sobrecarregadas dos métodos IDatabase.StringIncrementAsync e IDatabase.StringDecrementAsync para executar estas operações e devolver o valor resultante que é armazenado na cache.The StackExchange library provides overloaded versions of the IDatabase.StringIncrementAsync and IDatabase.StringDecrementAsync methods to perform these operations and return the resulting value that is stored in the cache. O fragmento de código seguinte ilustra como utilizar estes métodos:The following code snippet illustrates how to use these methods:

    ConnectionMultiplexer redisHostConnection = ...;
    IDatabase cache = redisHostConnection.GetDatabase();
    ...
    await cache.StringSetAsync("data:counter", 99);
    ...
    long oldValue = await cache.StringIncrementAsync("data:counter");
    // Increment by 1 (the default)
    // oldValue should be 100
    
    long newValue = await cache.StringDecrementAsync("data:counter", 50);
    // Decrement by 50
    // newValue should be 50
    
  • GETSET, que obtém o valor que está associada a uma chave e altera-o para um novo valor.GETSET, which retrieves the value that's associated with a key and changes it to a new value. A biblioteca StackExchange disponibiliza esta operação através do método IDatabase.StringGetSetAsync.The StackExchange library makes this operation available through the IDatabase.StringGetSetAsync method. O fragmento de código abaixo mostra um exemplo deste método.The code snippet below shows an example of this method. Este código devolve o valor atual que está associado à chave "data:counter" do exemplo anterior.This code returns the current value that's associated with the key "data:counter" from the previous example. Em seguida, repõe o valor para esta chave a zero, tudo como parte da mesma operação:Then it resets the value for this key back to zero, all as part of the same operation:

    ConnectionMultiplexer redisHostConnection = ...;
    IDatabase cache = redisHostConnection.GetDatabase();
    ...
    string oldValue = await cache.StringGetSetAsync("data:counter", 0);
    
  • MGETe MSET, que podem devolver ou alterar um conjunto de valores de cadeia como uma única operação.MGET and MSET, which can return or change a set of string values as a single operation. Os métodos IDatabase.StringGetAsync e IDatabase.StringSetAsync são sobrecarregados para suportar esta funcionalidade, conforme mostra o exemplo seguinte:The IDatabase.StringGetAsync and IDatabase.StringSetAsync methods are overloaded to support this functionality, as shown in the following example:

    ConnectionMultiplexer redisHostConnection = ...;
    IDatabase cache = redisHostConnection.GetDatabase();
    ...
    // Create a list of key-value pairs
    var keysAndValues =
        new List<KeyValuePair<RedisKey, RedisValue>>()
        {
            new KeyValuePair<RedisKey, RedisValue>("data:key1", "value1"),
            new KeyValuePair<RedisKey, RedisValue>("data:key99", "value2"),
            new KeyValuePair<RedisKey, RedisValue>("data:key322", "value3")
        };
    
    // Store the list of key-value pairs in the cache
    cache.StringSet(keysAndValues.ToArray());
    ...
    // Find all values that match a list of keys
    RedisKey[] keys = { "data:key1", "data:key99", "data:key322"};
    // values should contain { "value1", "value2", "value3" }
    RedisValue[] values = cache.StringGet(keys);
    
    

Também pode combinar várias operações numa única transação de Redis, tal como descrito na secção Transações e lotes de Redis mais atrás neste no artigo.You can also combine multiple operations into a single Redis transaction as described in the Redis transactions and batches section earlier in this article. A biblioteca StackExchange fornece suporte para transações através da interface ITransaction.The StackExchange library provides support for transactions through the ITransaction interface.

Para criar um objeto ITransaction, utilize o método IDatabase.CreateTransaction.You create an ITransaction object by using the IDatabase.CreateTransaction method. Para invocar comandos para a transação, utilize os métodos fornecidos pelo objeto ITransaction.You invoke commands to the transaction by using the methods provided by the ITransaction object.

A interface ITransaction proporciona acesso a um conjunto de métodos semelhantes aos métodos acedidos pela interface IDatabase, com a exceção de que todos os métodos são assíncronos.The ITransaction interface provides access to a set of methods that's similar to those accessed by the IDatabase interface, except that all the methods are asynchronous. Isto significa que só são executadas quando o método ITransaction.Execute é invocado.This means that they are only performed when the ITransaction.Execute method is invoked. O valor devolvido pelo método ITransaction.Execute indica se a transação foi criada com êxito (true) ou se falhou (false).The value that's returned by the ITransaction.Execute method indicates whether the transaction was created successfully (true) or if it failed (false).

O fragmento de código seguinte mostra um exemplo que incrementa e diminui dois contadores como parte da mesma transação:The following code snippet shows an example that increments and decrements two counters as part of the same transaction:

ConnectionMultiplexer redisHostConnection = ...;
IDatabase cache = redisHostConnection.GetDatabase();
...
ITransaction transaction = cache.CreateTransaction();
var tx1 = transaction.StringIncrementAsync("data:counter1");
var tx2 = transaction.StringDecrementAsync("data:counter2");
bool result = transaction.Execute();
Console.WriteLine("Transaction {0}", result ? "succeeded" : "failed");
Console.WriteLine("Result of increment: {0}", tx1.Result);
Console.WriteLine("Result of decrement: {0}", tx2.Result);

Lembre-se que as transações de Redis diferentes das transações em bases de dados relacionais.Remember that Redis transactions are unlike transactions in relational databases. O método Execute coloca, simplesmente, em fila todos os comandos que compõem a transação a executar e, se qualquer um deles tiver um formato incorreto, a transação é parada.The Execute method simply queues all the commands that comprise the transaction to be run, and if any of them is malformed then the transaction is stopped. Se todos os comandos tiverem sido colocados em fila com êxito, cada comando é executado no modo assíncrono.If all the commands have been queued successfully, each command runs asynchronously.

Se qualquer um dos comandos falhar, os outros continuam a ser processados.If any command fails, the others still continue processing. Se precisar de verificar se um comando foi concluído com êxito, terá de obter os resultados do comando através da propriedade Resultado da tarefa correspondente, tal como mostra o exemplo acima.If you need to verify that a command has completed successfully, you must fetch the results of the command by using the Result property of the corresponding task, as shown in the example above. A leitura da propriedade Resultado irá bloquear o thread de chamada até que a tarefa seja concluída.Reading the Result property will block the calling thread until the task has completed.

Para obter mais informações, consulte transações no Redis.For more information, see Transactions in Redis.

Quando executar operações de lote, pode utilizar a interface IBatch da biblioteca StackExchange.When performing batch operations, you can use the IBatch interface of the StackExchange library. A interface proporciona acesso a um conjunto de métodos semelhantes aos métodos acedidos pela interface IDatabase, com a exceção de que todos os métodos são assíncronos.This interface provides access to a set of methods similar to those accessed by the IDatabase interface, except that all the methods are asynchronous.

Para criar um objeto IBatch, tem de utilizar o método IDatabase.CreateBatch e, em seguida, executar o lote através do comando IBatch.Execute, tal como mostra o exemplo seguinte.You create an IBatch object by using the IDatabase.CreateBatch method, and then run the batch by using the IBatch.Execute method, as shown in the following example. Este código define, simplesmente, um valor de cadeia, incrementa e diminui os mesmos contadores utilizados no exemplo anterior e apresenta os resultados:This code simply sets a string value, increments and decrements the same counters used in the previous example, and displays the results:

ConnectionMultiplexer redisHostConnection = ...;
IDatabase cache = redisHostConnection.GetDatabase();
...
IBatch batch = cache.CreateBatch();
batch.StringSetAsync("data:key1", 11);
var t1 = batch.StringIncrementAsync("data:counter1");
var t2 = batch.StringDecrementAsync("data:counter2");
batch.Execute();
Console.WriteLine("{0}", t1.Result);
Console.WriteLine("{0}", t2.Result);

É importante compreender que, ao contrário de uma transação, se um comando num lote falhar porque tem um formato incorreto, os outros comandos poderão continuar a ser executados.It is important to understand that unlike a transaction, if a command in a batch fails because it is malformed, the other commands might still run. O método IBatch.Execute não devolve qualquer indicação de êxito ou falha.The IBatch.Execute method does not return any indication of success or failure.

Executar operações de cache «fire and forget»Perform fire and forget cache operations

O Redis suporta operações «fire and forget», utilizando sinalizadores de comando.Redis supports fire and forget operations by using command flags. Nesta situação, o cliente simplesmente inicia uma operação, mas não tem qualquer interesse no resultado e não aguarda pela conclusão do comando.In this situation, the client simply initiates an operation but has no interest in the result and does not wait for the command to be completed. O exemplo abaixo mostra como executar o comando INCR como uma operação «fire and forget»:The example below shows how to perform the INCR command as a fire and forget operation:

ConnectionMultiplexer redisHostConnection = ...;
IDatabase cache = redisHostConnection.GetDatabase();
...
await cache.StringSetAsync("data:key1", 99);
...
cache.StringIncrement("data:key1", flags: CommandFlags.FireAndForget);

Especificar chaves que expiram automaticamenteSpecify automatically expiring keys

Quando armazena um item numa cache de Redis, pode especificar um tempo limite após o qual o item será automaticamente removido da cache.When you store an item in a Redis cache, you can specify a timeout after which the item will be automatically removed from the cache. Também pode consultar a quantidade de tempo que uma chave tem até expirar, utilizando o comando TTL.You can also query how much more time a key has before it expires by using the TTL command. Este comando está disponível para aplicações StackExchange através do método IDatabase.KeyTimeToLive.This command is available to StackExchange applications by using the IDatabase.KeyTimeToLive method.

O fragmento de código seguinte mostra como definir um prazo de expiração de 20 segundos numa chave e consultar a duração restante da chave:The following code snippet shows how to set an expiration time of 20 seconds on a key, and query the remaining lifetime of the key:

ConnectionMultiplexer redisHostConnection = ...;
IDatabase cache = redisHostConnection.GetDatabase();
...
// Add a key with an expiration time of 20 seconds
await cache.StringSetAsync("data:key1", 99, TimeSpan.FromSeconds(20));
...
// Query how much time a key has left to live
// If the key has already expired, the KeyTimeToLive function returns a null
TimeSpan? expiry = cache.KeyTimeToLive("data:key1");

Também pode definir o prazo de expiração como uma data e hora específicas, utilizando o comando EXPIRE, que está disponível na biblioteca StackExchange como o método KeyExpireAsync:You can also set the expiration time to a specific date and time by using the EXPIRE command, which is available in the StackExchange library as the KeyExpireAsync method:

ConnectionMultiplexer redisHostConnection = ...;
IDatabase cache = redisHostConnection.GetDatabase();
...
// Add a key with an expiration date of midnight on 1st January 2015
await cache.StringSetAsync("data:key1", 99);
await cache.KeyExpireAsync("data:key1",
    new DateTime(2015, 1, 1, 0, 0, 0, DateTimeKind.Utc));
...

Dica

Pode remover manualmente um item da cache através do comando DEL, que está disponível através da biblioteca StackExchange como o método IDatabase.KeyDeleteAsync.You can manually remove an item from the cache by using the DEL command, which is available through the StackExchange library as the IDatabase.KeyDeleteAsync method.

Utilizar etiquetas para fazer a correlação cruzada de itens em cacheUse tags to cross-correlate cached items

Um conjunto de Redis é uma coleção de vários itens que partilham uma chave única.A Redis set is a collection of multiple items that share a single key. Pode criar um conjunto, utilizando o comando SADD.You can create a set by using the SADD command. Pode obter os itens de um conjunto, utilizando o comando SMEMBERS.You can retrieve the items in a set by using the SMEMBERS command. A biblioteca StackExchange implementa o comando SADD com o método IDatabase.SetAddAsync e o comando SMEMBERS com o método IDatabase.SetMembersAsync.The StackExchange library implements the SADD command with the IDatabase.SetAddAsync method, and the SMEMBERS command with the IDatabase.SetMembersAsync method.

Também pode combinar conjuntos existentes para criar novos conjuntos através dos comandos SDIFF (diferença do conjunto), SINTER (interseção do conjunto) e SUNION (união do conjunto).You can also combine existing sets to create new sets by using the SDIFF (set difference), SINTER (set intersection), and SUNION (set union) commands. A biblioteca StackExchange unifica estas operações no método IDatabase.SetCombineAsync.The StackExchange library unifies these operations in the IDatabase.SetCombineAsync method. O primeiro parâmetro deste método especifica a operação de conjunto a executar.The first parameter to this method specifies the set operation to perform.

Os fragmentos de código seguintes mostram como os conjuntos podem ser úteis para armazenar e obter rapidamente coleções de itens relacionados.The following code snippets show how sets can be useful for quickly storing and retrieving collections of related items. Este código utiliza o tipo BlogPost que foi descrito na secção Implementar aplicações cliente da cache de Redis, mais atrás neste artigo.This code uses the BlogPost type that was described in the section Implement Redis Cache Client Applications earlier in this article.

Um objeto BlogPost contém quatro campos: um ID, um título, uma pontuação de classificação e uma coleção de etiquetas.A BlogPost object contains four fields—an ID, a title, a ranking score, and a collection of tags. O primeiro fragmento de código abaixo mostra os dados de exemplo que são utilizados para preencher uma lista de C# de objetos BlogPost:The first code snippet below shows the sample data that's used for populating a C# list of BlogPost objects:

List<string[]> tags = new List<string[]>
{
    new[] { "iot","csharp" },
    new[] { "iot","azure","csharp" },
    new[] { "csharp","git","big data" },
    new[] { "iot","git","database" },
    new[] { "database","git" },
    new[] { "csharp","database" },
    new[] { "iot" },
    new[] { "iot","database","git" },
    new[] { "azure","database","big data","git","csharp" },
    new[] { "azure" }
};

List<BlogPost> posts = new List<BlogPost>();
int blogKey = 1;
int numberOfPosts = 20;
Random random = new Random();
for (int i = 0; i < numberOfPosts; i++)
{
    blogKey++;
    posts.Add(new BlogPost(
        blogKey,                  // Blog post ID
        string.Format(CultureInfo.InvariantCulture, "Blog Post #{0}",
            blogKey),             // Blog post title
        random.Next(100, 10000),  // Ranking score
        tags[i % tags.Count]));   // Tags--assigned from a collection
                                  // in the tags list
}

Pode armazenar as etiquetas para cada objeto BlogPost como um conjunto numa cache de Redis e associar cada conjunto ao ID do BlogPost.You can store the tags for each BlogPost object as a set in a Redis cache and associate each set with the ID of the BlogPost. Isto permite que uma aplicação localize rapidamente todas as etiquetas que pertencem a uma mensagem de blogue específica.This enables an application to quickly find all the tags that belong to a specific blog post. Para ativar a pesquisa na direção oposta e localizar todas as mensagens de blogue que partilham uma etiqueta específica, pode criar outro conjunto que contenha as mensagens de blogue que fazem referência ao ID de etiqueta na chave:To enable searching in the opposite direction and find all blog posts that share a specific tag, you can create another set that holds the blog posts referencing the tag ID in the key:

ConnectionMultiplexer redisHostConnection = ...;
IDatabase cache = redisHostConnection.GetDatabase();
...
// Tags are easily represented as Redis Sets
foreach (BlogPost post in posts)
{
    string redisKey = string.Format(CultureInfo.InvariantCulture,
        "blog:posts:{0}:tags", post.Id);
    // Add tags to the blog post in Redis
    await cache.SetAddAsync(
        redisKey, post.Tags.Select(s => (RedisValue)s).ToArray());

    // Now do the inverse so we can figure how which blog posts have a given tag
    foreach (var tag in post.Tags)
    {
        await cache.SetAddAsync(string.Format(CultureInfo.InvariantCulture,
            "tag:{0}:blog:posts", tag), post.Id);
    }
}

Estas estruturas permitem realizar muitas consultas comuns de forma muito eficiente.These structures enable you to perform many common queries very efficiently. Por exemplo, pode localizar e apresentar todas as etiquetas para a mensagem de blogue 1 desta forma:For example, you can find and display all of the tags for blog post 1 like this:

// Show the tags for blog post #1
foreach (var value in await cache.SetMembersAsync("blog:posts:1:tags"))
{
    Console.WriteLine(value);
}

Pode localizar todas as etiquetas que são comuns à mensagem de blogue 1 e à mensagem de blogue 2, executando uma operação de interseção do conjunto, da seguinte forma:You can find all tags that are common to blog post 1 and blog post 2 by performing a set intersection operation, as follows:

// Show the tags in common for blog posts #1 and #2
foreach (var value in await cache.SetCombineAsync(SetOperation.Intersect, new RedisKey[]
    { "blog:posts:1:tags", "blog:posts:2:tags" }))
{
    Console.WriteLine(value);
}

E pode localizar todas as mensagens de blogue que contêm uma etiqueta específica:And you can find all blog posts that contain a specific tag:

// Show the ids of the blog posts that have the tag "iot".
foreach (var value in await cache.SetMembersAsync("tag:iot:blog:posts"))
{
    Console.WriteLine(value);
}

Localizar itens acedidos recentementeFind recently accessed items

Uma tarefa comum necessária de muitas aplicações é localizar os itens acedidos mais recentemente.A common task required of many applications is to find the most recently accessed items. Por exemplo, um site de blogging poderá querer apresentar informações sobre as mensagens de blogue lidas mais recentemente.For example, a blogging site might want to display information about the most recently read blog posts.

Pode implementar esta funcionalidade através de uma lista de Redis.You can implement this functionality by using a Redis list. Uma lista de Redis contém vários itens que partilham a mesma chave.A Redis list contains multiple items that share the same key. A lista funciona como uma fila de extremidade dupla.The list acts as a double-ended queue. Pode enviar por push itens para ambas as extremidade da lista através dos comandos LPUSH (push à esquerda) e RPUSH (push à direita).You can push items to either end of the list by using the LPUSH (left push) and RPUSH (right push) commands. Pode obter itens de ambas as extremidades da lista através dos comandos LPOP e RPOP.You can retrieve items from either end of the list by using the LPOP and RPOP commands. Também pode devolver um conjunto de elementos através dos comandos LRANGE e RRANGE.You can also return a set of elements by using the LRANGE and RRANGE commands.

Os fragmentos de código abaixo mostram como pode executar estas operações através da biblioteca StackExchange.The code snippets below show how you can perform these operations by using the StackExchange library. Este código utiliza o tipo BlogPost dos exemplos anteriores.This code uses the BlogPost type from the previous examples. À medida que uma mensagem de blogue é lida por um utilizador, o método IDatabase.ListLeftPushAsync envia por push o título da mensagem de blogue para uma lista que está associada à chave "blog:recent_posts" na cache de Redis.As a blog post is read by a user, the IDatabase.ListLeftPushAsync method pushes the title of the blog post onto a list that's associated with the key "blog:recent_posts" in the Redis cache.

ConnectionMultiplexer redisHostConnection = ...;
IDatabase cache = redisHostConnection.GetDatabase();
...
string redisKey = "blog:recent_posts";
BlogPost blogPost = ...; // Reference to the blog post that has just been read
await cache.ListLeftPushAsync(
    redisKey, blogPost.Title); // Push the blog post onto the list

À medida que são lidas mais mensagens de blogue, os respetivos títulos são enviados por push para a mesma lista.As more blog posts are read, their titles are pushed onto the same list. A lista é ordenada pela sequência em que os títulos foram adicionados.The list is ordered by the sequence in which the titles have been added. As mensagens de blogue lidas mais recentemente situam-se na extremidade esquerda da lista.The most recently read blog posts are towards the left end of the list. (Se a mesma mensagem de blogue for lida mais do que uma vez, terá várias entradas na lista.)(If the same blog post is read more than once, it will have multiple entries in the list.)

Pode apresentar os títulos das mensagens lidas mais recentemente através do método IDatabase.ListRange.You can display the titles of the most recently read posts by using the IDatabase.ListRange method. Este método aceita a chave que contém a lista, um ponto de partida e um ponto de fim.This method takes the key that contains the list, a starting point, and an ending point. O código seguinte obtém os títulos das 10 mensagens de blogue (itens de 0 a 9) na extremidade mais à esquerda da lista:The following code retrieves the titles of the 10 blog posts (items from 0 to 9) at the left-most end of the list:

// Show latest ten posts
foreach (string postTitle in await cache.ListRangeAsync(redisKey, 0, 9))
{
    Console.WriteLine(postTitle);
}

Tenha em atenção que o método ListRangeAsync não remove itens da lista.Note that the ListRangeAsync method does not remove items from the list. Para tal, pode utilizar os métodos IDatabase.ListLeftPopAsync e IDatabase.ListRightPopAsync.To do this, you can use the IDatabase.ListLeftPopAsync and IDatabase.ListRightPopAsync methods.

Para impedir que a lista cresça indefinidamente, pode eliminar periodicamente itens ao cortar a lista.To prevent the list from growing indefinitely, you can periodically cull items by trimming the list. O fragmento de código abaixo mostra como remover todos os itens, exceto os cinco itens mais à esquerda, da lista:The code snippet below shows you how to remove all but the five left-most items from the list:

await cache.ListTrimAsync(redisKey, 0, 5);

Implementar um quadro líderImplement a leader board

Por predefinição, os itens de um conjunto não são guardados por qualquer ordem específica.By default, the items in a set are not held in any specific order. Pode criar um conjunto ordenado através do comando ZADD (o método IDatabase.SortedSetAdd na biblioteca StackExchange).You can create an ordered set by using the ZADD command (the IDatabase.SortedSetAdd method in the StackExchange library). Os itens são ordenados, utilizando um valor numérico denominado pontuação, que é fornecido como parâmetro para o comando.The items are ordered by using a numeric value called a score, which is provided as a parameter to the command.

O fragmento de código seguinte adiciona o título de uma mensagem de blogue a uma lista ordenada.The following code snippet adds the title of a blog post to an ordered list. Neste exemplo, cada mensagem de blogue também tem um campo de pontuação que contém a classificação da mensagem de blogue.In this example, each blog post also has a score field that contains the ranking of the blog post.

ConnectionMultiplexer redisHostConnection = ...;
IDatabase cache = redisHostConnection.GetDatabase();
...
string redisKey = "blog:post_rankings";
BlogPost blogPost = ...; // Reference to a blog post that has just been rated
await cache.SortedSetAddAsync(redisKey, blogPost.Title, blogPost.Score);

Pode obter os títulos e as pontuações da mensagem de blogue por ordem ascendente de pontuação através do comando IDatabase.SortedSetRangeByRankWithScores:You can retrieve the blog post titles and scores in ascending score order by using the IDatabase.SortedSetRangeByRankWithScores method:

foreach (var post in await cache.SortedSetRangeByRankWithScoresAsync(redisKey))
{
    Console.WriteLine(post);
}

Nota

A biblioteca StackExchange também disponibiliza o método IDatabase.SortedSetRangeByRankAsync, que devolve os dados por ordem de pontuação, mas não devolve as pontuações.The StackExchange library also provides the IDatabase.SortedSetRangeByRankAsync method, which returns the data in score order, but does not return the scores.

Também pode obter itens por ordem descendente de pontuações e limitar o número de itens que são devolvidos ao fornecer parâmetros adicionais para o método IDatabase.SortedSetRangeByRankWithScoresAsync.You can also retrieve items in descending order of scores, and limit the number of items that are returned by providing additional parameters to the IDatabase.SortedSetRangeByRankWithScoresAsync method. O exemplo seguinte mostra os títulos e as pontuações das 10 mensagens de blogue com melhor classificação:The next example displays the titles and scores of the top 10 ranked blog posts:

foreach (var post in await cache.SortedSetRangeByRankWithScoresAsync(
                               redisKey, 0, 9, Order.Descending))
{
    Console.WriteLine(post);
}

O exemplo seguinte utiliza o método IDatabase.SortedSetRangeByScoreWithScoresAsync, que pode utilizar para limitar os itens que são devolvidos àqueles que se inserem num determinado intervalo de pontuação:The next example uses the IDatabase.SortedSetRangeByScoreWithScoresAsync method, which you can use to limit the items that are returned to those that fall within a given score range:

// Blog posts with scores between 5000 and 100000
foreach (var post in await cache.SortedSetRangeByScoreWithScoresAsync(
                               redisKey, 5000, 100000))
{
    Console.WriteLine(post);
}

Mensagem através de canaisMessage by using channels

Para além de funcionar como uma cache de dados, um servidor Redis fornece mensagens através de um mecanismo publicador/subscritor de elevado desempenho.Apart from acting as a data cache, a Redis server provides messaging through a high-performance publisher/subscriber mechanism. As aplicações cliente podem subscrever um canal e os outros serviços ou aplicações podem publicar mensagens no canal.Client applications can subscribe to a channel, and other applications or services can publish messages to the channel. As aplicações de subscrição recebem, em seguida, estas mensagens e podem processá-las.Subscribing applications will then receive these messages and can process them.

O Redis fornece o comando SUBSCRIBE para as aplicações cliente utilizarem para subscrever canais.Redis provides the SUBSCRIBE command for client applications to use to subscribe to channels. Este comando espera o nome de um ou mais canais nos quais a aplicação irá aceitar mensagens.This command expects the name of one or more channels on which the application will accept messages. A biblioteca StackExchange inclui a interfaceISubscription, que permite que uma aplicação .NET Framework subscreva e publique em canais.The StackExchange library includes the ISubscription interface, which enables a .NET Framework application to subscribe and publish to channels.

Para criar um objeto ISubscription, utilize o método GetSubscriber da ligação ao servidor Redis.You create an ISubscription object by using the GetSubscriber method of the connection to the Redis server. Em seguida, para escutar as mensagens num canal, utilize o método SubscribeAsync deste objeto.Then you listen for messages on a channel by using the SubscribeAsync method of this object. O exemplo de código seguinte mostra como subscrever um canal chamado "messages:blogPosts":The following code example shows how to subscribe to a channel named "messages:blogPosts":

ConnectionMultiplexer redisHostConnection = ...;
ISubscriber subscriber = redisHostConnection.GetSubscriber();
...
await subscriber.SubscribeAsync("messages:blogPosts", (channel, message) => Console.WriteLine("Title is: {0}", message));

O primeiro parâmetro para o método Subscribe é o nome do canal.The first parameter to the Subscribe method is the name of the channel. Este nome segue-se as mesmas convenções que são utilizadas pelas chaves na cache.This name follows the same conventions that are used by keys in the cache. O nome pode conter quaisquer dados binários, embora seja aconselhável utilizar cadeias explicativas relativamente curtas, para ajudar a garantir o bom desempenho e manutenção.The name can contain any binary data, although it is advisable to use relatively short, meaningful strings to help ensure good performance and maintainability.

Tenha também em atenção que o espaço de nomes utilizado pelos canais é distinto daquele utilizado pelas chaves.Note also that the namespace used by channels is separate from that used by keys. Isto significa que pode ter canais e chaves com o mesmo nome, embora isto possa dificultar a manutenção do código da sua aplicação.This means you can have channels and keys that have the same name, although this may make your application code more difficult to maintain.

O segundo parâmetro é um delegado de ação.The second parameter is an Action delegate. Este delegado é executado no modo assíncrono sempre que uma nova mensagem for apresentada no canal.This delegate runs asynchronously whenever a new message appears on the channel. Este exemplo apresenta simplesmente a mensagem na consola (a mensagem incluirá o título de uma mensagem de blogue).This example simply displays the message on the console (the message will contain the title of a blog post).

Para publicar num canal, uma aplicação pode utilizar o comando PUBLISH do Redis.To publish to a channel, an application can use the Redis PUBLISH command. A biblioteca StackExchange fornece o método IServer.PublishAsync para executar esta operação.The StackExchange library provides the IServer.PublishAsync method to perform this operation. O fragmento de código seguinte mostra como publicar uma mensagem no canal "messages:blogPosts":The next code snippet shows how to publish a message to the "messages:blogPosts" channel:

ConnectionMultiplexer redisHostConnection = ...;
ISubscriber subscriber = redisHostConnection.GetSubscriber();
...
BlogPost blogPost = ...;
subscriber.PublishAsync("messages:blogPosts", blogPost.Title);

Existem vários pontos que deve compreender sobre o mecanismo de publicação/subscrição:There are several points you should understand about the publish/subscribe mechanism:

  • Vários subscritores podem subscrever o mesmo canal e todos eles receberão as mensagens publicadas nesse canal.Multiple subscribers can subscribe to the same channel, and they will all receive the messages that are published to that channel.
  • Os subscritores apenas recebem as mensagens que foram publicadas depois de terem feito a subscrição.Subscribers only receive messages that have been published after they have subscribed. Os canais não são colocados na memória intermédia e, assim que uma mensagem for publicada, a infraestrutura de Redis envia por push a mensagem para cada subscritor e, em seguida, remove-a.Channels are not buffered, and once a message is published, the Redis infrastructure pushes the message to each subscriber and then removes it.
  • Por predefinição, as mensagens são recebidas pelos subscritores pela ordem com que são enviadas.By default, messages are received by subscribers in the order in which they are sent. Num sistema muito ativo com um grande número de mensagens e muitos subscritores e publicadores, a entrega sequencial garantida de mensagens pode abrandar o desempenho do sistema.In a highly active system with a large number of messages and many subscribers and publishers, guaranteed sequential delivery of messages can slow performance of the system. Se cada mensagem for independente e a ordem não for importante, pode ativar o processamento simultâneo pelo sistema de Redis, o que pode ajudar a melhorar a capacidade de resposta.If each message is independent and the order is unimportant, you can enable concurrent processing by the Redis system, which can help to improve responsiveness. Poderá fazê-lo num cliente StackExchange, definindo PreserveAsyncOrder da ligação utilizada pelo subscritor como false:You can achieve this in a StackExchange client by setting the PreserveAsyncOrder of the connection used by the subscriber to false:
ConnectionMultiplexer redisHostConnection = ...;
redisHostConnection.PreserveAsyncOrder = false;
ISubscriber subscriber = redisHostConnection.GetSubscriber();

Considerações sobre serializaçãoSerialization considerations

Quando seleciona um formato de serialização, considere um compromisso entre desempenho, interoperabilidade, controlo de versões, compatibilidade com sistemas existentes, compressão de dados e sobrecarga de memória.When you choose a serialization format, consider tradeoffs between performance, interoperability, versioning, compatibility with existing systems, data compression, and memory overhead. Quando estiver a avaliar o desempenho, lembre-se que os testes de referência estão altamente dependentes do contexto.When you are evaluating performance, remember that benchmarks are highly dependent on context. Podem não refletir a carga de trabalho real e podem não considerar bibliotecas ou versões mais recentes.They may not reflect your actual workload, and may not consider newer libraries or versions. Não existe um serializador "mais rápido" único para todos os cenários.There is no single "fastest" serializer for all scenarios.

Algumas opções a ter em consideração incluem:Some options to consider include:

  • Protocol Buffers (também chamadas protobuf) é um formato de serialização desenvolvido pela Google para serializar dados estruturados de forma eficiente.Protocol Buffers (also called protobuf) is a serialization format developed by Google for serializing structured data efficiently. Utiliza ficheiros de definição com tipos de dados inflexíveis para definir as estruturas de mensagens.It uses strongly-typed definition files to define message structures. Em seguida, estes ficheiros de definição são compilados em código específico da linguagem para serializar e anular a serialização de mensagens.These definition files are then compiled to language-specific code for serializing and deserializing messages. O protobuf pode ser utilizado sobre os mecanismos RPC existentes ou pode gerar um serviço RPC.Protobuf can be used over existing RPC mechanisms, or it can generate an RPC service.

  • Apache Thrift utiliza uma abordagem semelhante, com ficheiros de definição com tipos de dados inflexíveis e um passo de compilação para gerar o código de serialização e os serviços RPC.Apache Thrift uses a similar approach, with strongly typed definition files and a compilation step to generate the serialization code and RPC services.

  • Apache Avro oferece uma funcionalidade semelhante a Protocol Buffers e Thrift, mas não existe qualquer passo de compilação.Apache Avro provides similar functionality to Protocol Buffers and Thrift, but there is no compilation step. Em alternativa, os dados serializados incluem sempre um esquema que descreve a estrutura.Instead, serialized data always includes a schema that describes the structure.

  • JSON é um padrão aberto que utiliza campos de texto legíveis por humanos.JSON is an open standard that uses human-readable text fields. Possui um amplo suporte em várias plataformas.It has broad cross-platform support. JSON não utiliza esquemas de mensagem.JSON does not use message schemas. Sendo um formato baseado em texto, não é muito eficiente por fio.Being a text-based format, it is not very efficient over the wire. No entanto, em alguns casos, pode estar a devolver itens em cache diretamente para um cliente através de HTTP, caso este em que armazenar o JSON podia poupar o custo de anular a serialização de outro formato e, em seguida, serializar para JSON.In some cases, however, you may be returning cached items directly to a client via HTTP, in which case storing JSON could save the cost of deserializing from another format and then serializing to JSON.

  • BSON é um formato de serialização binário que utiliza uma estrutura semelhante à do JSON.BSON is a binary serialization format that uses a structure similar to JSON. O BSON foi concebido para ser simples, fácil de analisar e rápido de serializar e anular a serialização, relativamente ao JSON.BSON was designed to be lightweight, easy to scan, and fast to serialize and deserialize, relative to JSON. As payloads são comparáveis em termos de tamanho com o JSON.Payloads are comparable in size to JSON. Consoante os dados, uma payload de BSON pode ser menor ou maior do que uma payload de JSON.Depending on the data, a BSON payload may be smaller or larger than a JSON payload. O BSON tem alguns tipos de dados adicionais que não estão disponíveis no JSON, nomeadamente BinData (para matrizes de bytes) e Date.BSON has some additional data types that are not available in JSON, notably BinData (for byte arrays) and Date.

  • MessagePack é um formato de serialização binário que foi concebido para ser compacto para transmissão por fio.MessagePack is a binary serialization format that is designed to be compact for transmission over the wire. Não existem esquemas de mensagem ou verificação de tipo de mensagem.There are no message schemas or message type checking.

  • Bond é uma estrutura multi-plataforma para trabalhar com dados esquematizados.Bond is a cross-platform framework for working with schematized data. Suporta a serialização e a anulação da serialização em diferentes linguagens.It supports cross-language serialization and deserialization. As diferenças relevantes em relação a outros sistemas aqui listados são o suporte de herança, aliases de tipo e genéricos.Notable differences from other systems listed here are support for inheritance, type aliases, and generics.

  • gRPC é um sistema RPC de open source desenvolvido pela Google.gRPC is an open source RPC system developed by Google. Por predefinição, utiliza Protocol Buffers como linguagem de definição e formato de intercâmbio de mensagem subjacente.By default, it uses Protocol Buffers as its definition language and underlying message interchange format.

Os seguintes padrões também podem ser relevantes ao seu cenário quando implementar a colocação em cache em seus aplicativos:The following patterns might also be relevant to your scenario when you implement caching in your applications:

  • Padrão cache-aside: Este padrão descreve como carregar dados a pedido para uma cache a partir de um arquivo de dados.Cache-aside pattern: This pattern describes how to load data on demand into a cache from a data store. Este padrão também ajuda a manter a consistência entre os dados mantidos na cache e os dados do arquivo de dados original.This pattern also helps to maintain consistency between data that's held in the cache and the data in the original data store.

  • O Padrão de fragmentação fornece informações sobre a implementação da criação de partições horizontais para ajudar a melhorar a escalabilidade ao armazenar e aceder a grandes volumes de dados.The Sharding pattern provides information about implementing horizontal partitioning to help improve scalability when storing and accessing large volumes of data.

Mais informaçõesMore information