Padrão de fragmentaçãoSharding pattern

Divida um arquivo de dados num conjunto de partições horizontais ou shards.Divide a data store into a set of horizontal partitions or shards. Deste modo, pode melhorar a escalabilidade ao armazenar e aceder a grandes volumes de dados.This can improve scalability when storing and accessing large volumes of data.

Contexto e problemaContext and problem

Um arquivo de dados alojado por um único servidor poderá estar sujeito às seguintes limitações:A data store hosted by a single server might be subject to the following limitations:

  • Espaço de armazenamento.Storage space. É esperado que um arquivo de dados para uma aplicação na cloud em grande escala contenha um grande volume de dados que poderá aumentar significativamente com o tempo.A data store for a large-scale cloud application is expected to contain a huge volume of data that could increase significantly over time. Um servidor normalmente proporciona apenas uma quantidade finita de armazenamento em disco, mas pode substituir discos existentes por outros maiores ou adicionar mais discos a um computador à medida que os volumes de dados aumentam.A server typically provides only a finite amount of disk storage, but you can replace existing disks with larger ones, or add further disks to a machine as data volumes grow. No entanto, o sistema acabará por chegar a um limite onde não poderá aumentar facilmente a capacidade de armazenamento num determinado servidor.However, the system will eventually reach a limit where it isn't possible to easily increase the storage capacity on a given server.

  • Recursos informáticos.Computing resources. Precisa de uma aplicação na cloud para suportar um grande número de utilizadores em simultâneo, sendo que cada um executa consultas que obtêm informações do arquivo de dados.A cloud application is required to support a large number of concurrent users, each of which run queries that retrieve information from the data store. Um único servidor que aloja o arquivo de dados poderá não ser capaz de proporcionar a capacidade informática necessária para suportar esta carga, resultando em tempos de resposta longos para utilizadores e falhas frequentes, uma vez que as aplicações que tentam armazenar e obter dados excedem o tempo limite. Poderá conseguir adicionar memória ou atualizar os processadores, mas o sistema atingirá um limite em que não poderá aumentar mais os recursos de computação.A single server hosting the data store might not be able to provide the necessary computing power to support this load, resulting in extended response times for users and frequent failures as applications attempting to store and retrieve data time out. It might be possible to add memory or upgrade processors, but the system will reach a limit when it isn't possible to increase the compute resources any further.

  • Largura de banda de rede.Network bandwidth. Em última análise, o desempenho de um arquivo de dados em execução num único servidor é regido pela taxa a que o servidor consegue receber os pedidos e enviar as respostas.Ultimately, the performance of a data store running on a single server is governed by the rate the server can receive requests and send replies. O volume do tráfego de rede pode exceder a capacidade da rede utilizada para ligar ao servidor, resultando em pedidos falhados.It's possible that the volume of network traffic might exceed the capacity of the network used to connect to the server, resulting in failed requests.

  • Geografia.Geography. Poderá ser preciso armazenar dados gerados por utilizadores específicos na mesma região deles por motivos legais, de compatibilidade ou de desempenho ou para reduzir a latência do acesso aos dados.It might be necessary to store data generated by specific users in the same region as those users for legal, compliance, or performance reasons, or to reduce latency of data access. Se os utilizadores estiverem distribuídos por diferentes países ou regiões, poderá não conseguir armazenar todos os dados da aplicação num único arquivo de dados.If the users are dispersed across different countries or regions, it might not be possible to store the entire data for the application in a single data store.

O dimensionamento vertical, ao adicionar mais capacidade de disco, potência de processamento, memória e ligações de rede, pode adiar os efeitos de algumas destas limitações, mas é provável que seja apenas uma solução temporária.Scaling vertically by adding more disk capacity, processing power, memory, and network connections can postpone the effects of some of these limitations, but it's likely to only be a temporary solution. Uma aplicação comercial na cloud capaz de suportar grandes números de utilizadores e elevados volumes de dados tem de ser capaz de dimensionar quase indefinidamente, pelo que o dimensionamento vertical não é necessariamente a melhor solução.A commercial cloud application capable of supporting large numbers of users and high volumes of data must be able to scale almost indefinitely, so vertical scaling isn't necessarily the best solution.

SoluçãoSolution

Divida o arquivo de dados em partições horizontais.Divide the data store into horizontal partitions or shards. Cada partição horizontal tem o mesmo esquema, mas mantém o seu próprio subconjunto de dados distinto.Each shard has the same schema, but holds its own distinct subset of the data. Uma partição horizontal é um arquivo de dados por direito próprio (pode conter os dados de muitas entidades de diferentes tipos), em execução num servidor a funcionar como um nó de armazenamento.A shard is a data store in its own right (it can contain the data for many entities of different types), running on a server acting as a storage node.

Este padrão possui as vantagens seguintes:This pattern has the following benefits:

  • Pode aumentar horizontalmente o sistema ao adicionar mais partições horizontais em execução em nós de armazenamento adicionais.You can scale the system out by adding further shards running on additional storage nodes.

  • Um sistema pode utilizar hardware pronto a utilizar em vez de computadores dispendiosos e especializados para cada nó de armazenamento.A system can use off-the-shelf hardware rather than specialized and expensive computers for each storage node.

  • Pode reduzir a disputa e melhorar o desempenho ao balancear a carga de trabalho nas partições horizontais.You can reduce contention and improve performance by balancing the workload across shards.

  • Na cloud, as partições horizontais podem estar localizadas fisicamente perto dos utilizadores que irão aceder aos dados.In the cloud, shards can be located physically close to the users that'll access the data.

Ao dividir um arquivo de dados em partições horizontais, decida que dados devem ser colocados em cada partição horizontal.When dividing a data store up into shards, decide which data should be placed in each shard. Normalmente, uma partição horizontal contém itens que se inserem num intervalo especificado, determinado por um ou mais atributos dos dados.A shard typically contains items that fall within a specified range determined by one or more attributes of the data. Estes atributos formam a chave de partição horizontal (por vezes, denominada chave de partição).These attributes form the shard key (sometimes referred to as the partition key). A chave de partição horizontal deve ser estática.The shard key should be static. Não deve basear-se em dados passíveis de serem alterados.It shouldn't be based on data that might change.

A fragmentação organiza fisicamente os dados.Sharding physically organizes the data. Quando uma aplicação armazena e obtém dados, a lógica de fragmentação direciona a aplicação para a partição horizontal adequada.When an application stores and retrieves data, the sharding logic directs the application to the appropriate shard. Esta lógica de fragmentação poderá ser implementada como parte do código de acesso de dados na aplicação ou poderá ser implementada pelo sistema de armazenamento de dados se suportar a fragmentação de forma transparente.This sharding logic can be implemented as part of the data access code in the application, or it could be implemented by the data storage system if it transparently supports sharding.

Ao abstrair a localização física dos dados na lógica de fragmentação, proporciona um elevado nível de controlo sobre que partições horizontais contêm determinados dados.Abstracting the physical location of the data in the sharding logic provides a high level of control over which shards contain which data. Também permitirá que os dados migrem entre partições horizontais sem reformular a lógica de negócio de uma aplicação se os dados nas partições horizontais tiverem de ser redistribuídos mais tarde (por exemplo, se as partições horizontais ficarem desequilibradas).It also enables data to migrate between shards without reworking the business logic of an application if the data in the shards need to be redistributed later (for example, if the shards become unbalanced). O compromisso é o custo do acesso aos dados adicional necessário para determinar a localização de cada item de dados, à medida que é obtido.The tradeoff is the additional data access overhead required in determining the location of each data item as it's retrieved.

Para garantir um desempenho e escalabilidade ideais, é importante dividir os dados de uma forma que seja adequada para os tipos de consultas que a aplicação executa.To ensure optimal performance and scalability, it's important to split the data in a way that's appropriate for the types of queries that the application performs. Em muitos casos, não é provável que o esquema de fragmentação corresponda exatamente aos requisitos de cada consulta.In many cases, it's unlikely that the sharding scheme will exactly match the requirements of every query. Por exemplo, num sistema multi-inquilino, uma aplicação poderá ter de obter dados do inquilino com o ID do inquilino, mas também poderá ter de procurar estes dados com base noutro atributo como a localização ou o nome do inquilino.For example, in a multi-tenant system an application might need to retrieve tenant data using the tenant ID, but it might also need to look up this data based on some other attribute such as the tenant’s name or location. Para processar estas situações, implemente uma estratégia de fragmentação com uma chave de partição horizontal que suporte as consultas executadas com mais frequência.To handle these situations, implement a sharding strategy with a shard key that supports the most commonly performed queries.

Se as consultas obtiverem regularmente dados através de uma combinação de valores de atributos, será provável que possa definir uma chave de partição horizontal composta ao associar atributos.If queries regularly retrieve data using a combination of attribute values, you can likely define a composite shard key by linking attributes together. Em alternativa, utilize um padrão como Tabela de Índice para proporcionar uma pesquisa rápida de dados com base em atributos que não são abrangidos pela chave de partição horizontal.Alternatively, use a pattern such as Index Table to provide fast lookup to data based on attributes that aren't covered by the shard key.

Estratégias de fragmentaçãoSharding strategies

As três estratégias são frequentemente utilizadas ao selecionar a chave de partição horizontal e ao decidir como distribuir os dados pelas partições horizontais.Three strategies are commonly used when selecting the shard key and deciding how to distribute data across shards. Tenha em atenção que não é necessário existir obrigatoriamente uma correspondência exata entre as partições horizontais e os servidores que as alojam — um único servidor pode alojar várias partições horizontais.Note that there doesn't have to be a one-to-one correspondence between shards and the servers that host them—a single server can host multiple shards. As estratégias são:The strategies are:

Estratégia de Pesquisa.The Lookup strategy. Nesta estratégia, a lógica de fragmentação implementa um mapa que encaminha um pedido de dados para a partição horizontal que contém os dados através da chave de partição horizontal.In this strategy the sharding logic implements a map that routes a request for data to the shard that contains that data using the shard key. Numa aplicação multi-inquilino, todos os dados de um inquilino poderão ser armazenados em conjunto numa partição horizontal com o ID do inquilino como a chave de partição horizontal.In a multi-tenant application all the data for a tenant might be stored together in a shard using the tenant ID as the shard key. Vários inquilinos podem partilhar a mesma partição horizontal, mas os dados de um único inquilino não serão distribuídos por várias partições horizontais.Multiple tenants might share the same shard, but the data for a single tenant won't be spread across multiple shards. A figura ilustra a fragmentação dos dados de inquilino com base nos IDs de inquilino.The figure illustrates sharding tenant data based on tenant IDs.

Figura 1 – Fragmentação dos dados de inquilino com base nos IDs de inquilino

O mapeamento entre a chave de partição horizontal e o armazenamento físico pode basear-se em partições horizontais físicas, em que cada chave de partição horizontal mapeia para uma partição física.The mapping between the shard key and the physical storage can be based on physical shards where each shard key maps to a physical partition. Em alternativa, uma técnica mais flexível para reequilibrar as partições horizontais é a criação de partições horizontais virtuais, onde as chaves de partições horizontais mapeiam para o mesmo número de partições horizontais virtuais, que, por sua vez, mapeiam para menos partições horizontais físicas.Alternatively, a more flexible technique for rebalancing shards is virtual partitioning, where shard keys map to the same number of virtual shards, which in turn map to fewer physical partitions. Nesta abordagem, uma aplicação localiza os dados através de uma chave de partição horizontal que menciona uma partição horizontal virtual e o sistema mapeia as partições horizontais virtuais de forma transparente para as partições físicas.In this approach, an application locates data using a shard key that refers to a virtual shard, and the system transparently maps virtual shards to physical partitions. Pode alterar o mapeamento entre uma partição horizontal virtual e uma partição física sem ter de modificar o código da aplicação para utilizar um conjunto diferente de chaves de partições horizontais.The mapping between a virtual shard and a physical partition can change without requiring the application code be modified to use a different set of shard keys.

Estratégia de intervalo.The Range strategy. Esta estratégia agrupa itens relacionados na mesma partição horizontal e ordena-as pela chave de partição horizontal — as chaves de partições horizontais são sequenciais.This strategy groups related items together in the same shard, and orders them by shard key—the shard keys are sequential. É útil para aplicações que, frequentemente, obtêm conjuntos de itens através de consultas de intervalo (consultas que devolvem um conjunto de itens de dados para uma chave de partição horizontal que se encontrem dentro de um determinado intervalo).It's useful for applications that frequently retrieve sets of items using range queries (queries that return a set of data items for a shard key that falls within a given range). Por exemplo, se uma aplicação precisar regularmente de localizar todas as encomendas realizadas num determinado mês, estes dados poderão ser obtidos mais rapidamente se todas as encomendas de um mês forem armazenadas por ordem de data e hora na mesma partição horizontal.For example, if an application regularly needs to find all orders placed in a given month, this data can be retrieved more quickly if all orders for a month are stored in date and time order in the same shard. Se cada encomenda for armazenada numa partição horizontal diferente, terá de ser obtida individualmente ao executar um grande número de consultas pontuais (consultas que devolvem um único item de dados).If each order was stored in a different shard, they'd have to be fetched individually by performing a large number of point queries (queries that return a single data item). A figura seguinte ilustra o armazenamento de conjuntos (intervalos) de dados sequenciais na partição horizontal.The next figure illustrates storing sequential sets (ranges) of data in shard.

Figura 2 – Armazenamento de conjuntos sequenciais (intervalos) de dados em partições horizontais

Neste exemplo, a chave de partição horizontal é uma chave composta, que contém o mês da encomenda como o elemento mais significativo, seguido do dia e hora da encomenda.In this example, the shard key is a composite key containing the order month as the most significant element, followed by the order day and the time. Os dados das encomendas são ordenados naturalmente quando são criadas novas encomendas e adicionadas a uma partição horizontal.The data for orders is naturally sorted when new orders are created and added to a shard. Alguns arquivos de dados suportam chaves de partições horizontais de duas partes que contêm um elemento de chave de partição que identifica a partição horizontal e uma chave de linha que identifica exclusivamente um item na partição horizontal.Some data stores support two-part shard keys containing a partition key element that identifies the shard and a row key that uniquely identifies an item in the shard. Normalmente, os dados estão contidos de acordo com a ordem de chave da linha na partição horizontal.Data is usually held in row key order in the shard. Os itens que estão sujeitos a consultas de intervalo e que têm de ser agrupados em conjunto podem utilizar uma chave de partição horizontal que tenha o mesmo valor para a chave de partição, mas um valor exclusivo para a chave de linha.Items that are subject to range queries and need to be grouped together can use a shard key that has the same value for the partition key but a unique value for the row key.

Estratégia de hash.The Hash strategy. O objetivo desta estratégia é reduzir a possibilidade de hotspots (partições horizontais que recebem uma quantidade desproporcionada de carga).The purpose of this strategy is to reduce the chance of hotspots (shards that receive a disproportionate amount of load). Distribui os dados pelas partições horizontais de uma forma que alcança um equilíbrio entre o tamanho de cada partição horizontal e a carga média que cada partição horizontal irá encontrar.It distributes the data across the shards in a way that achieves a balance between the size of each shard and the average load that each shard will encounter. A lógica de fragmentação calcula a partição horizontal para armazenar um item com base num hash de um ou mais atributos dos dados.The sharding logic computes the shard to store an item in based on a hash of one or more attributes of the data. A função de hash escolhida deve distribuir os dados uniformemente pelas partições horizontais, possivelmente, introduzindo alguns elementos aleatórios no cálculo.The chosen hashing function should distribute data evenly across the shards, possibly by introducing some random element into the computation. A figura seguinte ilustra a fragmentação dos dados de inquilino com base num hash dos IDs de inquilino.The next figure illustrates sharding tenant data based on a hash of tenant IDs.

Figura 3 – Fragmentação dos dados de inquilino com base num hash dos IDs de inquilino

Para compreender a vantagem da estratégia de Hash sobre as outras estratégias de fragmentação, considere como uma aplicação multi-inquilino que inscreve novos inquilinos pode atribuir sequencialmente os inquilinos a partições horizontais no arquivo de dados.To understand the advantage of the Hash strategy over other sharding strategies, consider how a multi-tenant application that enrolls new tenants sequentially might assign the tenants to shards in the data store. Quando utilizar a Estratégia de intervalo, os dados dos inquilinos 1 a n serão armazenados na partição horizontal A, os dados dos inquilinos n + 1 a m serão armazenados na partição horizontal B e assim sucessivamente.When using the Range strategy, the data for tenants 1 to n will all be stored in shard A, the data for tenants n+1 to m will all be stored in shard B, and so on. Se os inquilinos mais recentemente registados também forem mais ativos, a maioria das atividades de dados ocorrerá num pequeno número de partições horizontais, o que poderá provocar hotspots.If the most recently registered tenants are also the most active, most data activity will occur in a small number of shards, which could cause hotspots. Em contrapartida, a Estratégia de hash atribui os inquilinos a partições horizontais com base num hash do seu ID de inquilino,In contrast, the Hash strategy allocates tenants to shards based on a hash of their tenant ID. o que significa que é mais provável que os inquilinos sequenciais sejam atribuídos a partições horizontais diferentes, que irão distribuir a carga entre si.This means that sequential tenants are most likely to be allocated to different shards, which will distribute the load across them. A figura anterior mostra esta situação para os inquilinos 55 e 56.The previous figure shows this for tenants 55 and 56.

As três estratégias de fragmentação têm as seguintes vantagens e considerações:The three sharding strategies have the following advantages and considerations:

  • Pesquisa.Lookup. Esta estratégia oferece mais controlo sobre como as partições horizontais são configuradas e utilizadas.This offers more control over the way that shards are configured and used. A utilização de partições horizontais virtuais reduz o impacto ao reequilibrar os dados, porque as novas partições físicas podem ser adicionadas para repartir a carga de trabalho.Using virtual shards reduces the impact when rebalancing data because new physical partitions can be added to even out the workload. O mapeamento entre uma partição horizontal virtual e as partições físicas que implementam as partições horizontais pode ser modificado sem afetar o código de aplicação que utiliza uma chave de partição horizontal para armazenar e obter dados.The mapping between a virtual shard and the physical partitions that implement the shard can be modified without affecting application code that uses a shard key to store and retrieve data. A procura de localizações de partições horizontais pode implicar um custo adicional.Looking up shard locations can impose an additional overhead.

  • Intervalo.Range. Esta estratégia é fácil de implementar e funciona bem com consultas de intervalo porque, muitas vezes, podem obter vários itens de dados de uma única partição horizontal numa única operação.This is easy to implement and works well with range queries because they can often fetch multiple data items from a single shard in a single operation. Esta estratégia proporciona uma gestão de dados mais fácil.This strategy offers easier data management. Por exemplo, se os utilizadores na mesma região estiverem na mesma partição horizontal, poderão ser agendadas atualizações em cada fuso horário com base no padrão da procura e da carga local.For example, if users in the same region are in the same shard, updates can be scheduled in each time zone based on the local load and demand pattern. No entanto, esta estratégia não proporciona um balanceamento ideal entre partições horizontais.However, this strategy doesn't provide optimal balancing between shards. Reequilibrar as partições horizontais é difícil e poderá não resolver o problema da carga desigual se a maioria das atividades for para as chaves de partições horizontais adjacentes.Rebalancing shards is difficult and might not resolve the problem of uneven load if the majority of activity is for adjacent shard keys.

  • Hash.Hash. Esta estratégia oferece uma melhor oportunidade para obter uma distribuição mais uniforme da carga e dos dados.This strategy offers a better chance of more even data and load distribution. O encaminhamento de pedidos pode ser conseguido diretamente através da função de hash.Request routing can be accomplished directly by using the hash function. Não é necessário manter um mapa.There's no need to maintain a map. Tenha em atenção que calcular o hash pode implicar um custo adicional.Note that computing the hash might impose an additional overhead. Além disso, reequilibrar as partições horizontais é difícil.Also, rebalancing shards is difficult.

Os sistemas de fragmentação mais comuns implementam uma das abordagens descritas acima, mas também deve considerar os requisitos comerciais das suas aplicações e os seus padrões de utilização de dados.Most common sharding systems implement one of the approaches described above, but you should also consider the business requirements of your applications and their patterns of data usage. Por exemplo, numa aplicação multi-inquilino:For example, in a multi-tenant application:

  • Pode fragmentar os dados com base na carga de trabalho.You can shard data based on workload. Pode segregar os dados dos inquilinos altamente voláteis em partições horizontais separadas.You could segregate the data for highly volatile tenants in separate shards. Como resultado, a velocidade do acesso aos dados dos outros inquilinos pode ser melhorada.The speed of data access for other tenants might be improved as a result.

  • Pode fragmentar os dados com base na localização dos inquilinos.You can shard data based on the location of tenants. Pode colocar os dados dos inquilinos numa região geográfica específica offline para fins de cópia de segurança e de manutenção fora das horas de ponta nessa região, enquanto os dados dos inquilinos noutras regiões permanecem online e acessíveis durante o horário comercial.You can take the data for tenants in a specific geographic region offline for backup and maintenance during off-peak hours in that region, while the data for tenants in other regions remains online and accessible during their business hours.

  • Pode atribuir aos inquilinos de alto valor as suas próprias partições horizontais privadas de elevado desempenho e de carga leve, enquanto que os inquilinos de valor inferior podem partilhar partições horizontais mais compactas e mais solicitadas.High-value tenants could be assigned their own private, high performing, lightly loaded shards, whereas lower-value tenants might be expected to share more densely-packed, busy shards.

  • Os dados para os inquilinos que precisam de um elevado grau de isolamento e de privacidade podem ser armazenados num servidor completamente separado.The data for tenants that need a high degree of data isolation and privacy can be stored on a completely separate server.

Operações de movimento de dados e de dimensionamentoScaling and data movement operations

Cada uma das estratégias de fragmentação implica diferentes capacidades e níveis de complexidade para gerir a redução horizontal, o aumento horizontal, o movimento de dados e a manutenção do estado.Each of the sharding strategies implies different capabilities and levels of complexity for managing scale in, scale out, data movement, and maintaining state.

A Estratégia de pesquisa permite que as operações de movimento de dados e de dimensionamento sejam realizadas ao nível do utilizador, online ou offline.The Lookup strategy permits scaling and data movement operations to be carried out at the user level, either online or offline. A técnica consiste em suspender algumas ou todas as atividades do utilizador (talvez fora das horas de ponta), mover os dados para a nova partição virtual ou partição horizontal física, alterar os mapeamentos, invalidar ou atualizar qualquer cache que contenha estes dados e, em seguida, permitir que a atividade do utilizador seja retomada.The technique is to suspend some or all user activity (perhaps during off-peak periods), move the data to the new virtual partition or physical shard, change the mappings, invalidate or refresh any caches that hold this data, and then allow user activity to resume. Muitas vezes, este tipo de operação pode ser gerido centralmente.Often this type of operation can be centrally managed. A Estratégia de pesquisa requer um estado altamente compatível com a colocação em cache e com as réplicas.The Lookup strategy requires state to be highly cacheable and replica friendly.

A Estratégia de intervalo impõe algumas limitações nas operações de movimento de dados e dimensionamento, que têm, normalmente, de ser executadas quando uma parte ou todo o arquivo de dados está offline porque os dados têm de ser divididos e intercalados entre as partições horizontais.The Range strategy imposes some limitations on scaling and data movement operations, which must typically be carried out when a part or all of the data store is offline because the data must be split and merged across the shards. Mover os dados para reequilibrar as partições horizontais poderá não resolver o problema da carga desigual se a maioria da atividade for para as chaves de partições horizontais adjacentes ou identificadores de dados que estão dentro do mesmo intervalo.Moving the data to rebalance shards might not resolve the problem of uneven load if the majority of activity is for adjacent shard keys or data identifiers that are within the same range. A Estratégia de intervalo pode igualmente precisar que algum estado seja mantido para mapear intervalos para as partições físicas.The Range strategy might also require some state to be maintained in order to map ranges to the physical partitions.

A Estratégia de hash faz com que as operações de movimento de dados e dimensionamento sejam mais complexas porque as chaves de partição são hashes de chaves de partições horizontais ou identificadores de dados.The Hash strategy makes scaling and data movement operations more complex because the partition keys are hashes of the shard keys or data identifiers. A nova localização de cada partição horizontal tem de ser determinada a partir da função de hash ou da função modificada para proporcionar os mapeamentos corretos.The new location of each shard must be determined from the hash function, or the function modified to provide the correct mappings. No entanto, a Estratégia de hash não requer a manutenção do estado.However, the Hash strategy doesn't require maintenance of state.

Problemas e consideraçõesIssues and considerations

Na altura de decidir como implementar este padrão, considere os seguintes pontos:Consider the following points when deciding how to implement this pattern:

  • A fragmentação complementa outras formas de criação de partições, tais como a criação de partições verticais e a criação de partições funcionais.Sharding is complementary to other forms of partitioning, such as vertical partitioning and functional partitioning. Por exemplo, uma única partição horizontal pode conter entidades que tenham sido particionadas verticalmente e uma partição funcional pode ser implementada como várias partições horizontais.For example, a single shard can contain entities that have been partitioned vertically, and a functional partition can be implemented as multiple shards. Para obter mais informações sobre a criação de partições, veja as Orientações sobre a Criação de Partições de Dados.For more information about partitioning, see the Data Partitioning Guidance.

  • Mantenha as partições horizontais equilibradas para que todas processem um volume semelhante de E/S.Keep shards balanced so they all handle a similar volume of I/O. Como os dados são inseridos e eliminados, é preciso reequilibrar periodicamente as partições horizontais para garantir uma distribuição uniforme e para reduzir a possibilidade de hotspots.As data is inserted and deleted, it's necessary to periodically rebalance the shards to guarantee an even distribution and to reduce the chance of hotspots. O reequilíbrio pode ser uma operação dispendiosa.Rebalancing can be an expensive operation. Para reduzir a necessidade de reequilíbrio, planeie o crescimento ao garantir que cada partição horizontal contém espaço livre suficiente para processar o volume de alterações esperado.To reduce the necessity of rebalancing, plan for growth by ensuring that each shard contains sufficient free space to handle the expected volume of changes. Também deve desenvolver estratégias e scripts que possa utilizar para reequilibrar rapidamente as partições horizontais, se for preciso.You should also develop strategies and scripts you can use to quickly rebalance shards if this becomes necessary.

  • Utilize dados estáveis para a chave de partição horizontal.Use stable data for the shard key. Se a chave de partição horizontal for alterada, o item de dados correspondente poderá ter de ser movido entre partições horizontais, aumentando a quantidade de trabalho realizado pela operações de atualização.If the shard key changes, the corresponding data item might have to move between shards, increasing the amount of work performed by update operations. Por este motivo, evite basear a chave de partição horizontal em informações potencialmente voláteis.For this reason, avoid basing the shard key on potentially volatile information. Em vez disso, procure atributos que sejam invariáveis ou que formem naturalmente uma chave.Instead, look for attributes that are invariant or that naturally form a key.

  • Garanta que as chaves de partições horizontais são exclusivas.Ensure that shard keys are unique. Por exemplo, evite utilizar campos que incrementam automaticamente como a chave de partição horizontal.For example, avoid using autoincrementing fields as the shard key. Em alguns sistemas, os campos incrementados automaticamente não podem ser coordenados entre partições horizontais, o que possivelmente pode resultar em itens em partições horizontais diferentes com a mesma chave de partição horizontal.Is some systems, autoincremented fields can't be coordinated across shards, possibly resulting in items in different shards having the same shard key.

    Os valores incrementados automaticamente noutros campos que não são as chaves de partições horizontais também podem causar problemas.Autoincremented values in other fields that are not shard keys can also cause problems. Por exemplo, se utilizar campos incrementados automaticamente para gerar IDs exclusivos, significa que dois itens diferentes localizados em partições horizontais diferentes poderão ser atribuídos ao mesmo ID.For example, if you use autoincremented fields to generate unique IDs, then two different items located in different shards might be assigned the same ID.

  • Pode não ser possível estruturar uma chave de partição horizontal que satisfaça os requisitos de cada consulta possível relativamente aos dados.It might not be possible to design a shard key that matches the requirements of every possible query against the data. Coloque os dados em partições horizontais para suportar as consultas mais frequentemente realizadas e, se for necessário, crie tabelas de índice secundárias para suportar consultas que obtêm dados através de critérios com base em atributos que não fazem parte da chave de partição horizontal.Shard the data to support the most frequently performed queries, and if necessary create secondary index tables to support queries that retrieve data using criteria based on attributes that aren't part of the shard key. Para obter mais informações, veja o Padrão de Tabela de Índice.For more information, see the Index Table pattern.

  • As consultas que apenas acedem a uma partição horizontal única são mais eficientes do que as que obtêm dados de várias partições horizontais. Por isso, evite implementar um sistema de fragmentação que resulte em aplicações a executar grandes números de consultas que associem dados retidos em partições horizontais diferentes.Queries that access only a single shard are more efficient than those that retrieve data from multiple shards, so avoid implementing a sharding system that results in applications performing large numbers of queries that join data held in different shards. Lembre-se de que uma partição horizontal única pode conter os dados de vários tipos de entidades.Remember that a single shard can contain the data for multiple types of entities. Considere desnormalizar os dados para manter entidades relacionadas que normalmente são consultadas em conjunto (por exemplo, os detalhes de clientes e as encomendas que realizaram) na mesma partição horizontal para reduzir o número de leituras separadas que uma aplicação realiza.Consider denormalizing your data to keep related entities that are commonly queried together (such as the details of customers and the orders that they have placed) in the same shard to reduce the number of separate reads that an application performs.

    Se uma entidade numa partição horizontal mencionar uma entidade armazenada noutra partição horizontal, inclua a chave de partição horizontal da segunda entidade como parte do esquema da primeira entidade.If an entity in one shard references an entity stored in another shard, include the shard key for the second entity as part of the schema for the first entity. Deste modo, pode ajudar a melhorar o desempenho das consultas que mencionam dados relacionados entre as partições horizontais.This can help to improve the performance of queries that reference related data across shards.

  • Se uma aplicação tiver de executar consultas que obtêm dados de várias partições horizontais, poderá ser possível obter estes dados através da utilização de tarefas paralelas.If an application must perform queries that retrieve data from multiple shards, it might be possible to fetch this data by using parallel tasks. Os exemplos incluem consultas de distribuição ramificada, onde os dados de várias partições horizontais são obtidos em paralelo e, em seguida, agregados num único resultado.Examples include fan-out queries, where data from multiple shards is retrieved in parallel and then aggregated into a single result. No entanto, esta abordagem inevitavelmente adiciona alguma complexidade à lógica de acesso aos dados de uma solução.However, this approach inevitably adds some complexity to the data access logic of a solution.

  • Para muitas aplicações, a criação de um grande número de partições horizontais pequenas pode ser mais eficiente do que ter um pequeno número de partições horizontais grandes porque podem oferecer maiores oportunidades de balanceamento de carga.For many applications, creating a larger number of small shards can be more efficient than having a small number of large shards because they can offer increased opportunities for load balancing. Tal também pode ser útil caso preveja a necessidade de migrar partições horizontais de uma localização física para outra.This can also be useful if you anticipate the need to migrate shards from one physical location to another. Mover uma partição horizontal pequena é mais rápido do que mover uma grande.Moving a small shard is quicker than moving a large one.

  • Garanta que os recursos disponíveis para cada nó de armazenamento de partição horizontal são suficientes para processar os requisitos de escalabilidade em termos de tamanho de dados e débito.Make sure the resources available to each shard storage node are sufficient to handle the scalability requirements in terms of data size and throughput. Para obter mais informações, veja a secção “Conceber Partições para Escalabilidade” em Orientações sobre a Criação de Partições de Dados.For more information, see the section “Designing Partitions for Scalability” in the Data Partitioning Guidance.

  • Considere replicar os dados de referência para todas as partições horizontais.Consider replicating reference data to all shards. Se uma operação que obtém dados a partir de uma partição horizontal também mencionar dados estáticos ou de movimento lento como parte da mesma consulta, adicione estes dados à partição horizontal.If an operation that retrieves data from a shard also references static or slow-moving data as part of the same query, add this data to the shard. A aplicação pode, em seguida, obter todos os dados para a consulta facilmente, sem ter de realizar um percurso de ida e volta adicional para um arquivo de dados separado.The application can then fetch all of the data for the query easily, without having to make an additional round trip to a separate data store.

    Se os dados de referência contidos em várias partições horizontais forem alterados, o sistema terá de sincronizar estas alterações em todas as partições horizontais.If reference data held in multiple shards changes, the system must synchronize these changes across all shards. O sistema pode encontrar um certo grau de inconsistência enquanto esta sincronização ocorre.The system can experience a degree of inconsistency while this synchronization occurs. Se o fizer, deve conceber as suas aplicações para que sejam capazes de a processar.If you do this, you should design your applications to be able to handle it.

  • Pode ser difícil manter a integridade referencial e a consistência entre as partições horizontais, pelo que deve minimizar as operações que afetam os dados de várias partições horizontais.It can be difficult to maintain referential integrity and consistency between shards, so you should minimize operations that affect data in multiple shards. Se uma aplicação tiver de modificar os dados em partições horizontais, avalie se a consistência de dados completa é realmente necessária.If an application must modify data across shards, evaluate whether complete data consistency is actually required. Em vez disso, uma abordagem comum na cloud é implementar a consistência eventual.Instead, a common approach in the cloud is to implement eventual consistency. Os dados em cada partição são atualizados em separado e a lógica da aplicação tem de ser responsável por garantir que todas as atualizações são concluídas com êxito, bem como processar as inconsistências que podem surgir da consulta de dados enquanto uma operação eventualmente consistente está em execução.The data in each partition is updated separately, and the application logic must take responsibility for ensuring that the updates all complete successfully, as well as handling the inconsistencies that can arise from querying data while an eventually consistent operation is running. Para obter mais informações sobre a implementação de consistência eventual, veja o Data Consistency Primer (Manual Básico sobre a Consistência dos Dados).For more information about implementing eventual consistency, see the Data Consistency Primer.

  • A configuração e a gestão de um grande número de partições horizontais podem ser um desafio.Configuring and managing a large number of shards can be a challenge. As tarefas como a monitorização, a cópia de segurança, a verificação de consistência e o registo ou a auditoria têm de ser realizadas em várias partições horizontais e servidores, possivelmente contidas em várias localizações.Tasks such as monitoring, backing up, checking for consistency, and logging or auditing must be accomplished on multiple shards and servers, possibly held in multiple locations. É provável que estas tarefas sejam implementadas com scripts ou outras soluções de automatização, mas podem não eliminar completamente os requisitos administrativos adicionais.These tasks are likely to be implemented using scripts or other automation solutions, but that might not completely eliminate the additional administrative requirements.

  • As partições horizontais podem ser geolocalizadas para que os dados que contêm estejam próximos das instâncias da aplicação que a utiliza.Shards can be geolocated so that the data that they contain is close to the instances of an application that use it. Esta abordagem pode melhorar significativamente o desempenho, mas requer considerações adicionais para as tarefas que têm de aceder a várias partições horizontais em diferentes localizações.This approach can considerably improve performance, but requires additional consideration for tasks that must access multiple shards in different locations.

Quando utilizar este padrãoWhen to use this pattern

Utilize este padrão quando for provável que um arquivo de dados tenha de dimensionar para além dos recursos disponíveis para um nó de armazenamento único ou para melhorar o desempenho ao reduzir a disputa num arquivo de dados.Use this pattern when a data store is likely to need to scale beyond the resources available to a single storage node, or to improve performance by reducing contention in a data store.

Nota

O foco principal da fragmentação é melhorar o desempenho e a escalabilidade de um sistema, mas como um subproduto, também pode melhorar a disponibilidade, devido à forma como os dados são divididos em partições separadas.The primary focus of sharding is to improve the performance and scalability of a system, but as a by-product it can also improve availability due to how the data is divided into separate partitions. Uma falha numa partição não impede necessariamente uma aplicação de aceder aos dados contidos noutras partições e um operador pode realizar a manutenção ou a recuperação de uma ou mais partições sem tornar todos os dados de uma aplicação inacessíveis.A failure in one partition doesn't necessarily prevent an application from accessing data held in other partitions, and an operator can perform maintenance or recovery of one or more partitions without making the entire data for an application inaccessible. Para obter mais informações, veja as Orientações sobre a Criação de Partições de Dados.For more information, see the Data Partitioning Guidance.

ExemploExample

O exemplo seguinte em C# utiliza um conjunto de bases de dados do SQL Server que funcionam como partições horizontais.The following example in C# uses a set of SQL Server databases acting as shards. Cada base de dados contém um subconjunto de dados utilizados por uma aplicação.Each database holds a subset of the data used by an application. A aplicação obtém dados que são distribuídos por partições horizontais através da própria lógica de fragmentação (este é um exemplo de uma consulta de distribuição ramificada).The application retrieves data that's distributed across the shards using its own sharding logic (this is an example of a fan-out query). Os detalhes dos dados que estão localizados em cada partição horizontal são devolvidos por um método denominado GetShards.The details of the data that's located in each shard is returned by a method called GetShards. Este método devolve uma lista enumerável de objetos ShardInformation, onde o tipo ShardInformation contém um identificador para cada partição horizontal e a cadeia de ligação do SQL Server que uma aplicação deve utilizar para se ligar à partição horizontal (as cadeias de ligação não são apresentadas no exemplo de código).This method returns an enumerable list of ShardInformation objects, where the ShardInformation type contains an identifier for each shard and the SQL Server connection string that an application should use to connect to the shard (the connection strings aren't shown in the code example).

private IEnumerable<ShardInformation> GetShards()
{
  // This retrieves the connection information from a shard store
  // (commonly a root database).
  return new[]
  {
    new ShardInformation
    {
      Id = 1,
      ConnectionString = ...
    },
    new ShardInformation
    {
      Id = 2,
      ConnectionString = ...
    }
  };
}

O código abaixo mostra como a aplicação utiliza a lista de objetos ShardInformation para executar uma consulta que obtém dados de cada partição horizontal em paralelo.The code below shows how the application uses the list of ShardInformation objects to perform a query that fetches data from each shard in parallel. Não são apresentados os detalhes da consulta, mas neste exemplo, os dados que são obtidos contêm uma cadeia que poderá conter informações como o nome de um cliente se as partições horizontais contiverem os detalhes dos clientes.The details of the query aren't shown, but in this example the data that's retrieved contains a string that could hold information such as the name of a customer if the shards contain the details of customers. Os resultados são agregados numa coleção ConcurrentBag para processamento por parte da aplicação.The results are aggregated into a ConcurrentBag collection for processing by the application.

// Retrieve the shards as a ShardInformation[] instance.
var shards = GetShards();

var results = new ConcurrentBag<string>();

// Execute the query against each shard in the shard list.
// This list would typically be retrieved from configuration
// or from a root/master shard store.
Parallel.ForEach(shards, shard =>
{
  // NOTE: Transient fault handling isn't included,
  // but should be incorporated when used in a real world application.
  using (var con = new SqlConnection(shard.ConnectionString))
  {
    con.Open();
    var cmd = new SqlCommand("SELECT ... FROM ...", con);

    Trace.TraceInformation("Executing command against shard: {0}", shard.Id);

    var reader = cmd.ExecuteReader();
    // Read the results in to a thread-safe data structure.
    while (reader.Read())
    {
      results.Add(reader.GetString(0));
    }
  }
});

Trace.TraceInformation("Fanout query complete - Record Count: {0}",
                        results.Count);

Os padrões e orientações que se seguem também podem ser relevantes ao implementar este padrão:The following patterns and guidance might also be relevant when implementing this pattern:

  • Manual Básico de Consistência de Dados.Data Consistency Primer. Poderá ser necessário manter a consistência dos dados distribuídos por diferentes partições horizontais.It might be necessary to maintain consistency for data distributed across different shards. Resume os problemas referentes à conservação da consistência dos dados distribuídos e descreve os benefícios e os compromissos dos diferentes modelos de consistência.Summarizes the issues surrounding maintaining consistency over distributed data, and describes the benefits and tradeoffs of different consistency models.
  • Orientações sobre a Criação de Partições de Dados.Data Partitioning Guidance. A fragmentação de um arquivo de dados pode acarretar uma série de outros problemas.Sharding a data store can introduce a range of additional issues. Descreve estes problemas relativos à criação de partições dos arquivos de dados na cloud para melhorar a escalabilidade, reduzir a disputa e otimizar o desempenho.Describes these issues in relation to partitioning data stores in the cloud to improve scalability, reduce contention, and optimize performance.
  • Padrão de Tabela de Índice.Index Table pattern. Por vezes, não é possível suportar totalmente as consultas apenas através da conceção da chave de partição horizontal.Sometimes it isn't possible to completely support queries just through the design of the shard key. Permite que uma aplicação obtenha rapidamente os dados de um arquivo de dados grande ao especificar uma chave que não seja a chave de partição horizontal.Enables an application to quickly retrieve data from a large data store by specifying a key other than the shard key.
  • Padrão de Vista Materializada.Materialized View pattern. Para manter o desempenho de algumas operações de consulta, é útil criar vistas materializadas que agregam e resumem os dados, especialmente se estes dados de resumos forem baseados nas informações que são distribuídas pelas partições horizontais.To maintain the performance of some query operations, it's useful to create materialized views that aggregate and summarize data, especially if this summary data is based on information that's distributed across shards. Descreve como gerar e preencher estas vistas.Describes how to generate and populate these views.