Descrição do problemaProblem description

Obter repetidamente as mesmas informações de um recurso que é dispendioso de aceder, em termos de custos gerais de E/S ou latência.Repeatedly fetching the same information from a resource that is expensive to access, in terms of I/O overhead or latency.

Como resolver o problemaHow to fix the problem

A estratégia de colocação em cache mais popular é a pedido ou cache-aside.The most popular caching strategy is the on-demand or cache-aside strategy.

Na leitura, a aplicação tenta ler os dados da cache.On read, the application tries to read the data from the cache.Se os dados não estiverem na cache, a aplicação obtém os mesmos da origem de dados e adiciona-os à cache.If the data isn't in the cache, the application retrieves it from the data source and adds it to the cache.

Na escrita, a aplicação escreve a alteração diretamente na origem de dados e remove o valor antigo da cache.On write, the application writes the change directly to the data source and removes the old value from the cache.Será obtido e adicionado à cache da próxima vez que for necessário.It will be retrieved and added to the cache the next time it is required.

ConsideraçõesConsiderations

Se a cache não estiver disponível, talvez devido a uma falha transitória, não devolva um erro ao cliente.If the cache is unavailable, perhaps because of a transient failure, don't return an error to the client.Em vez disso, obtenha os dados da origem de dados original.Instead, fetch the data from the original data source.No entanto, tenha em atenção que, enquanto a cache está a ser recuperada, o arquivo de dados original pode ser inundado de pedidos, o que resulta em tempos limite e falhas de ligações.However, be aware that while the cache is being recovered, the original data store could be swamped with requests, resulting in timeouts and failed connections.(Afinal de contas, esta é uma das motivações para utilizar uma cache.) Utilize uma técnica, como o [padrão Disjuntor Automático] circuit-breaker para evitar sobrecarregar a origem de dados.(After all, this is one of the motivations for using a cache in the first place.) Use a technique such as the Circuit Breaker pattern to avoid overwhelming the data source.

Não tem de colocar todas as entidades em cache.You don't have to cache entire entities.Se a maior parte de uma entidade for estática, mas apenas uma pequena parte for alterada com frequência, coloque os elementos estáticos em cache e obtenha os elementos dinâmicos da origem de dados.If most of an entity is static but only a small piece changes frequently, cache the static elements and retrieve the dynamic elements from the data source.Esta abordagem pode ajudar a reduzir o volume de E/S a efetuar na origem de dados.This approach can help to reduce the volume of I/O being performed against the data source.

Poderá ser útil avisar a cache quando a aplicação for iniciada.It might be useful to prime the cache when the application starts.Povoe a cache com os dados com maior probabilidade de serem utilizados.Populate the cache with the data that is most likely to be used.

Instrumente a aplicação e monitorize o sistema para descobrir com que frequência a aplicação obtém dados ou calcula informações.Instrument the application and monitor the live system to find out how frequently the application retrieves data or calculates information.

Crie um perfil da aplicação num ambiente de teste para capturar as métricas de baixo nível sobre os custos gerais associados a operações de acesso a dados ou a outros cálculos efetuados frequentemente.Profile the application in a test environment to capture low-level metrics about the overhead associated with data access operations or other frequently performed calculations.

Execute testes de carga num ambiente de teste para identificar como o sistema responde a uma carga de trabalho normal e a uma sobrecarga.Perform load testing in a test environment to identify how the system responds under a normal workload and under heavy load.Os testes de carga devem simular o padrão de acesso a dados observado no ambiente de produção através de cargas de trabalho realistas.Load testing should simulate the pattern of data access observed in the production environment using realistic workloads.

Examine as estatísticas de acesso a dados dos arquivos de dados subjacentes e reveja com que frequência são repetidos os mesmos pedidos de dados.Examine the data access statistics for the underlying data stores and review how often the same data requests are repeated.

Diagnóstico de exemploExample diagnosis

Instrumentar a aplicação e monitorizar o sistemaInstrument the application and monitor the live system

Instrumente a aplicação e monitorize-a para obter informações sobre os pedidos específicos que os utilizadores fazem enquanto a aplicação está em produção.Instrument the application and monitor it to get information about the specific requests that users make while the application is in production.

A imagem seguinte mostra a captura de dados de monitorização do New Relic durante um teste de carga.The following image shows monitoring data captured by New Relic during a load test.Neste caso, a única operação GET de HTTP efetuada é Person/GetAsync.In this case, the only HTTP GET operation performed is Person/GetAsync.No entanto, num ambiente de produção, conhecer a frequência relativa em que cada pedido é efetuado pode dar-lhe informações sobre que recursos devem ser colocados em cache.But in a live production environment, knowing the relative frequency that each request is performed can give you insight into which resources should be cached.

Se precisar de uma análise mais detalhada, pode utilizar um gerador de perfis para capturar os dados de desempenho de baixo nível num ambiente de teste (não o sistema de produção).If you need a deeper analysis, you can use a profiler to capture low-level performance data in a test environment (not the production system).Observe as métricas, como taxas de pedidos de E/S, utilização da memória e utilização da CPU.Look at metrics such as I/O request rates, memory usage, and CPU utilization.Estas métricas podem mostrar um elevado número de pedidos para um arquivo de dados ou serviço, bem como o processamento repetido que executa o mesmo cálculo.These metrics may show a large number of requests to a data store or service, or repeated processing that performs the same calculation.

Testar a carga da aplicaçãoLoad test the application

O gráfico seguinte mostra os resultados do teste de carga da aplicação de exemplo.The following graph shows the results of load testing the sample application.O teste de carga simula uma carga de até 800 utilizadores a executar uma série típica de operações.The load test simulates a step load of up to 800 users performing a typical series of operations.

O número de testes com êxito efetuados por segundo atinge um patamar, o que origina um abrandamento dos pedidos adicionais.The number of successful tests performed each second reaches a plateau, and additional requests are slowed as a result.O tempo médio de teste aumenta firmemente com a carga de trabalho.The average test time steadily increases with the workload.O tempo de resposta uniformiza após os picos de carga dos utilizadores.The response time levels off once the user load peaks.

Examinar as estatísticas de acesso a dadosExamine data access statistics

A coluna UseCount nos resultados indica a frequência de execução de cada consulta.The UseCount column in the results indicates how frequently each query is run.A imagem seguinte mostra que a terceira consulta foi executada mais de 250 000 vezes, significativamente mais do que qualquer outra consulta.The following image shows that the third query was run more than 250,000 times, significantly more than any other query.

Segue-se a consulta SQL Server que está a causar muitos pedidos da base de dados:Here is the SQL query that is causing so many database requests:

(@p__linq__0 int)SELECT TOP (2)
[Extent1].[BusinessEntityId] AS [BusinessEntityId],
[Extent1].[FirstName] AS [FirstName],
[Extent1].[LastName] AS [LastName]
FROM [Person].[Person] AS [Extent1]
WHERE [Extent1].[BusinessEntityId] = @p__linq__0