Anti-padrão de Persistência MonolíticaMonolithic Persistence antipattern

Colocar todos os dados de uma aplicação num arquivo de dados único pode prejudicar o desempenho, porque este leva à contenção de recursos ou porque o arquivo de dados não é uma boa opção para alguns dos dados.Putting all of an application's data into a single data store can hurt performance, either because it leads to resource contention, or because the data store is not a good fit for some of the data.

Descrição do problemaProblem description

Historicamente, as aplicações utilizaram frequentemente um único arquivo de dados, independentemente dos diferentes tipos de dados que a aplicação possa ter de armazenar.Historically, applications have often used a single data store, regardless of the different types of data that the application might need to store. Normalmente, isto é feito para simplificar a estrutura da aplicação ou para corresponder ao conjunto de competências existente da equipa de desenvolvimento.Usually this was done to simplify the application design, or else to match the existing skill set of the development team.

Muitas vezes, sistemas baseados em cloud modernos têm requisitos adicionais funcionais e não funcionais e têm de armazenar muitos tipos de dados heterogéneos, como documentos, imagens, dados em cache, mensagens em fila, registos de aplicações e telemetria.Modern cloud-based systems often have additional functional and nonfunctional requirements, and need to store many heterogenous types of data, such as documents, images, cached data, queued messages, application logs, and telemetry. Seguir a abordagem tradicional e colocar todas estas informações no mesmo arquivo de dados pode prejudicar o desempenho, por duas razões principais:Following the traditional approach and putting all of this information into the same data store can hurt performance, for two main reasons:

  • Armazenar e obter grandes quantidades de dados não relacionados no mesmo arquivo de dados pode provocar a contenção, que por sua vez origina tempos de resposta mais lentos e falhas de ligação.Storing and retrieving large amounts of unrelated data in the same data store can cause contention, which in turn leads to slow response times and connection failures.
  • Independentemente do arquivo de dados escolhido, poderá não ser a melhor opção para todos os diferentes tipos de dados ou pode não ser otimizado para as operações que a aplicação executa.Whichever data store is chosen, it might not be the best fit for all of the different types of data, or it might not be optimized for the operations that the application performs.

O exemplo seguinte mostra um controlador de API Web do ASP.NET que adiciona um novo registo a uma base de dados e também regista o resultado num registo.The following example shows an ASP.NET Web API controller that adds a new record to a database and also records the result to a log. O registo está retido na mesma base de dados que os dados empresariais.The log is held in the same database as the business data. Pode encontrar o exemplo completo aqui.You can find the complete sample here.

public class MonoController : ApiController
{
    private static readonly string ProductionDb = ...;

    public async Task<IHttpActionResult> PostAsync([FromBody]string value)
    {
        await DataAccess.InsertPurchaseOrderHeaderAsync(ProductionDb);
        await DataAccess.LogAsync(ProductionDb, LogTableName);
        return Ok();
    }
}

A velocidade em que os registos são gerados provavelmente irá afetar o desempenho das operações empresariais.The rate at which log records are generated will probably affect the performance of the business operations. E, se outro componente, por exemplo, um monitor do processo de aplicação, regularmente lê e processa dados de registo, isso também pode afetar as operações empresariais.And if another component, such as an application process monitor, regularly reads and processes the log data, that can also affect the business operations.

Como resolver o problemaHow to fix the problem

Separe os dados de acordo com a sua utilização.Separate data according to its use. Para cada conjunto de dados, selecione um arquivo de dados que melhor corresponda à forma como esse conjunto de dados será utilizado.For each data set, select a data store that best matches how that data set will be used. No exemplo anterior, a aplicação deve registar um arquivo separado da base de dados que contém dados de empresariais:In the previous example, the application should be logging to a separate store from the database that holds business data:

public class PolyController : ApiController
{
    private static readonly string ProductionDb = ...;
    private static readonly string LogDb = ...;

    public async Task<IHttpActionResult> PostAsync([FromBody]string value)
    {
        await DataAccess.InsertPurchaseOrderHeaderAsync(ProductionDb);
        // Log to a different data store.
        await DataAccess.LogAsync(LogDb, LogTableName);
        return Ok();
    }
}

ConsideraçõesConsiderations

  • Separe os dados pela forma como são utilizados e acedidos.Separate data by the way it is used and how it is accessed. Por exemplo, não armazene dados empresariais e informações de registo no mesmo arquivo de dados.For example, don't store log information and business data in the same data store. Estes tipos de dados têm requisitos significativamente diferentes e padrões de acesso.These types of data have significantly different requirements and patterns of access. Os registos de registo são inerentemente sequenciais, enquanto os dados empresariais são mais prováveis de requererem acesso aleatório e, muitas vezes, são relacionais.Log records are inherently sequential, while business data is more likely to require random access, and is often relational.

  • Considere o padrão de acesso de dados para cada tipo de dados.Consider the data access pattern for each type of data. Por exemplo, armazene relatórios formatados e documentos numa base de dados de documentos, como o Cosmos DB, mas utilize a Cache de Redis do Azure para colocar dados temporários em cache.For example, store formatted reports and documents in a document database such as Cosmos DB, but use Azure Redis Cache to cache temporary data.

  • Se seguir esta documentação de orientação, mas ainda atingir os limites da base de dados, poderá ter de aumentar verticalmente a base de dados.If you follow this guidance but still reach the limits of the database, you may need to scale up the database. Considere também dimensionar horizontalmente e criar partições de carga entre servidores de base de dados.Also consider scaling horizontally and partitioning the load across database servers. No entanto, a criação de partições pode exigir a reestruturação da aplicação.However, partitioning may require redesigning the application. Para obter mais informações, veja Criação de partições.For more information, see Data partitioning.

Como detetar o problemaHow to detect the problem

O sistema irá provavelmente ficar muito mais lento e, eventualmente, falhar, uma vez que o sistema fica sem recursos, como ligações de base de dados.The system will likely slow down dramatically and eventually fail, as the system runs out of resources such as database connections.

Pode realizar os passos seguintes para ajudar a identificar a causa.You can perform the following steps to help identify the cause.

  1. Instrumente o sistema para gravar as estatísticas do desempenho chave.Instrument the system to record the key performance statistics. Capture informações de tempo para cada operação, bem como os pontos de onde a aplicação lê e escreve dados.Capture timing information for each operation, as well as the points where the application reads and writes data.
  2. Se puder, monitorize o sistema em execução durante alguns dias num ambiente de produção para obter uma vista do mundo real de como o sistema é utilizado.If possible, monitor the system running for a few days in a production environment to get a real-world view of how the system is used. Se não puder, execute os testes de carga com script com um volume realista de utilizadores virtuais a realizar uma série típica de operações.If this is not possible, run scripted load tests with a realistic volume of virtual users performing a typical series of operations.
  3. Utilize os dados telemétricos para identificar períodos de fraco desempenho.Use the telemetry data to identify periods of poor performance.
  4. Identifique quais os arquivos de dados que foram acedidos durante esses períodos.Identify which data stores were accessed during those periods.
  5. Identifique os recursos de armazenamento de dados que podem apresentar contenção.Identify data storage resources that might be experiencing contention.

Diagnóstico de exemploExample diagnosis

As secções seguintes aplicam estes passos para o exemplo de aplicação descrito anteriormente.The following sections apply these steps to the sample application described earlier.

Instrumente e monitorize o sistemaInstrument and monitor the system

O gráfico seguinte mostra os resultados do teste de carga da aplicação de exemplo descrito anteriormente.The following graph shows the results of load testing the sample application described earlier. O teste utilizou uma carga de até 1000 utilizadores em simultâneo.The test used a step load of up to 1000 concurrent users.

Resultados do desempenho do teste de carga para o controlador baseado em SQL

À medida que a carga aumenta para 700 utilizadores, o débito também aumenta.As the load increases to 700 users, so does the throughput. Mas nessa altura, os níveis de débito e o sistema parecem estar em execução na capacidade máxima.But at that point, throughput levels off, and the system appears to be running at its maximum capacity. A resposta média aumenta gradualmente com a carga do utilizador, mostrando que o sistema não consegue acompanhar a procura.The average response gradually increases with user load, showing that the system can't keep up with demand.

Identificar períodos de fraco desempenhoIdentify periods of poor performance

Se estiver a monitorizar o sistema de produção, pode ser que repare em padrões.If you are monitoring the production system, you might notice patterns. Por exemplo, os tempos de resposta poderão baixar significativamente em simultâneo todos os dias.For example, response times might drop off significantly at the same time each day. Isto pode ser causado por uma carga de trabalho regular ou tarefa de lote agendada, ou apenas porque o sistema tem mais utilizadores em determinadas alturas.This could be caused by a regular workload or scheduled batch job, or just because the system has more users at certain times. Deve focar-se nos dados telemétricos para estes eventos.You should focus on the telemetry data for these events.

Procure correlações entre os tempos de resposta aumentados e a atividade de base de dados aumentada ou E/S para recursos partilhados.Look for correlations between increased response times and increased database activity or I/O to shared resources. Se existirem correlações, significa que a base de dados poderá ter sofrido um estrangulamento.If there are correlations, it means the database might be a bottleneck.

Identifique quais os arquivos de dados que são acedidos durante esses períodosIdentify which data stores are accessed during those periods

O gráfico seguinte mostra a utilização das unidades de débito de base de dados (DTU) durante o teste de carga.The next graph shows the utilization of database throughput units (DTU) during the load test. (Uma DTU é uma medida de capacidade disponível e é uma combinação de utilização da CPU, alocação de memória, velocidade de E/S.) A utilização de DTUs alcançou rapidamente 100%.(A DTU is a measure of available capacity, and is a combination of CPU utilization, memory allocation, I/O rate.) Utilization of DTUs quickly reached 100%. Este é aproximadamente o ponto em que o débito atingiu o pico no gráfico anterior.This is roughly the point where throughput peaked in the previous graph. A utilização da base de dados permaneceu muito elevada até o teste estar concluído.Database utilization remained very high until the test finished. Existe uma ligeira redução em direção ao final, que pode ser causada pela limitação, pela concorrência das ligações de base de dados ou por outros fatores.There is a slight drop toward the end, which could be caused by throttling, competition for database connections, or other factors.

O monitor da base de dados no portal clássico do Azure mostra a utilização de recursos da base de dados

Examinar a telemetria dos arquivos de dadosExamine the telemetry for the data stores

Instrumente os arquivos de dados para capturar os detalhes de baixo nível da atividade.Instrument the data stores to capture the low-level details of the activity. No exemplo de aplicação, as estatísticas do acesso aos dados mostraram um grande volume de operações de inserção executadas na tabela PurchaseOrderHeader e na tabela MonoLog.In the sample application, the data access statistics showed a high volume of insert operations performed against both the PurchaseOrderHeader table and the MonoLog table.

As estatísticas de acesso de dados para o exemplo de aplicação

Identificar a contenção de recursosIdentify resource contention

Neste momento, pode rever o código de origem, com foco nos pontos em que os recursos disponíveis são acedidos pela aplicação.At this point, you can review the source code, focusing on the points where contended resources are accessed by the application. Procure situações, como:Look for situations such as:

  • Os dados que estão logicamente separados escritos no mesmo arquivo.Data that is logically separate being written to the same store. Dados, como registos, relatórios e mensagens em fila não devem ser mantidos na mesma base de dados como informações empresariais.Data such as logs, reports, and queued messages should not be held in the same database as business information.
  • Um erro de correspondência entre a escolha do arquivo de dados e o tipo de dados, como blobs grandes ou documentos XML numa base de dados relacional.A mismatch between the choice of data store and the type of data, such as large blobs or XML documents in a relational database.
  • Dados com padrões de utilização significativamente diferentes que partilham o mesmo arquivo, como dados de alta-escrita/baixa-leitura a ser armazenados com dados de baixa escrita/alta leitura.Data with significantly different usage patterns that share the same store, such as high-write/low-read data being stored with low-write/high-read data.

Implementar a solução e verificar o resultadoImplement the solution and verify the result

A aplicação foi alterada para registos de escrita para um arquivo de dados separado.The application was changed to write logs to a separate data store. Seguem-se os resultados do teste de carga:Here are the load test results:

Resultados de desempenho do teste de carga com o controlador Polyglot

O padrão de débito é semelhante ao gráfico anterior, mas o ponto no qual os picos de desempenho é de aproximadamente 500 pedidos por segundo mais alto.The pattern of throughput is similar to the earlier graph, but the point at which performance peaks is approximately 500 requests per second higher. O tempo de resposta médio é ligeiramente inferior.The average response time is marginally lower. No entanto, estas estatísticas não mostram tudo.However, these statistics don't tell the full story. A telemetria para a base de dados empresarial mostra que os picos de utilização da DTU estão em cerca de 75%, em vez de 100%.Telemetry for the business database shows that DTU utilization peaks at around 75%, rather than 100%.

O monitor da base de dados no portal clássico do Azure mostra a utilização de recursos da base de dados no cenário polyglot

Da mesma forma, a utilização de DTU máxima de base de dados do registo atinge apenas cerca de 70%.Similarly, the maximum DTU utilization of the log database only reaches about 70%. As bases de dados já não são o fator restritivo no desempenho do sistema.The databases are no longer the limiting factor in the performance of the system.

O monitor da base de dados no portal clássico do Azure mostra a utilização de recursos da base de dados de registo no cenário polyglot