Menu Docs
Página inicial do Docs
/
Manual do MongoDB
/ /

Escritas locais distribuídas para volumes de trabalho somente de inserção

Nesta página

  • Cenário
  • Procedimento

A fragmentação com reconhecimento de tags do MongoDB permite que os administradores controlem a distribuição de dados em um cluster fragmentado definindo intervalos da chave de shard e marcando-os em um ou mais shards.

Este tutorial usa Zonas junto com um sistema de cluster fragmentado de vários centros de dados e lógica do lado do aplicativo para suportar gravações locais distribuídas, bem como alta disponibilidade de gravação no caso de uma eleição de conjunto de réplicas ou falha do centro de dados.

Ao definir as zonas e as faixas de zonas antes de fragmentar uma collection vazia ou não existente, a operação de collection de shards cria chunks para as faixas de zonas definidas, bem como quaisquer chunks adicionais para cobrir todo a faixa dos valores da chave de shard e executa uma distribuição inicial de shards com base nas faixas de zonas. Essa criação e distribuição inicial de chunks permite uma configuração mais rápida da fragmentação por zonas. Após a distribuição inicial, o balancer gerenciará a distribuição de chunks dali para a frente.

Consulte Predefinir zonas e faixas de zona para uma collection vazia ou inexistente para obter um exemplo.

Importante

Os conceitos discutidos neste tutorial exigem uma arquitetura de implantação específica, bem como uma lógica no nível do aplicativo.

Esses conceitos exigem familiaridade com os clusters fragmentados do MongoDB, os conjuntos de réplicas e o comportamento geral das zonas.

This tutorial assumes an insert-only or insert-intensive workload. Os conceitos e estratégias discutidos neste tutorial não são adequados para casos de uso que exigem leituras ou atualizações rápidas.

Considere um aplicativo de inserção intensiva, onde as leituras são pouco frequentes e de baixa prioridade em comparação com as gravações. A aplicação grava documento em uma collection fragmentada e requer tempo de atividade quase constante do reconhecimento de data center para suportar seus SLAs ou SLOs.

O seguinte representa uma visão parcial do formato do documento que a aplicação grava no reconhecimento de data center:

{
"_id" : ObjectId("56f08c447fe58b2e96f595fa"),
"message_id" : 329620,
"datacenter" : "alfa",
"userid" : 123,
...
}
{
"_id" : ObjectId("56f08c447fe58b2e96f595fb"),
"message_id" : 578494,
"datacenter" : "bravo",
"userid" : 456,
...
}
{
"_id" : ObjectId("56f08c447fe58b2e96f595fc"),
"message_id" : 689979,
"datacenter" : "bravo",
"userid" : 789,
...
}

A coleção usa o índice composto { datacenter : 1, userid : 1 } como chave de fragmento.

O campo datacenter em cada documento permite criar um intervalo de tags em cada valor de centro de dados distinto. Sem o campo datacenter , não seria possível associar um documento a um centro de dados específico.

O campo userid fornece um componente de alta cardinalidade e baixa frequência para a chave de shard relativa a datacenter.

Consulte Escolher uma chave de shard para obter instruções mais gerais sobre como selecionar uma chave de shard.

A implantação consiste em dois centros de dados, alfa e bravo. Existem dois fragmentos, shard0000 e shard0001. Cada shard é um conjunto de réplicas com três membros. shard0000 tem dois membros em alfa e um membro prioritário 0 em bravo. shard0001 tem dois membros em bravo e um membro prioritário 0 em alfa.

Diagrama da arquitetura de cluster fragmentado para alta disponibilidade

Este aplicativo requer uma tag por datacenter. Cada fragmento tem uma tag atribuída a ele com base no datacenter que contém a maioria dos membros do conjunto de réplicas. Existem dois intervalos de tags, um para cada centro de dados.

alfa Centro de dados

Marque shards com a maioria dos membros neste datacenter como alfa .

Crie um intervalo de tags com:

  • um limite inferior de { "datacenter" : "alfa", "userid" : MinKey },

  • um limite superior de { "datacenter" : "alfa", "userid" : MaxKey } e

  • a marcação alfa

bravo Centro de dados

Marque shards com a maioria dos membros neste datacenter como bravo .

Crie um intervalo de tags com:

  • um limite inferior de { "datacenter" : "bravo", "userid" : MinKey },

  • um limite superior de { "datacenter" : "bravo", "userid" : MaxKey } e

  • a marcação bravo

Observação

Os valores MinKey e MaxKey são valores especiais reservados para comparações

Com base nas tags e intervalos de tags configurados, mongos roteia documentos com datacenter : alfa para o datacenter alfa e documentos com datacenter : bravo para o datacenter bravo .

Se um documento inserido ou atualizado corresponder a um intervalo de tags configurado, ele só poderá ser gravado em um fragmento com a tag relacionada.

O MongoDB pode escrever documentos que não correspondem a uma faixa de tags configurada a nenhum shard no cluster.

Observação

O comportamento descrito acima exige que o cluster esteja em um estado estável, sem partes que violem uma faixa de tags configurada. Consulte a seção a seguir nobalanceador para obter mais informações.

O balancer migra os chunks marcados para o shard apropriado. Até a migração, os shards podem conter chunks que violam faixas de tags e tags configuradas. Após a conclusão do balanceamento, os shards devem conter apenas chunks cujos intervalos não violem as tags e intervalos de tags atribuídos.

Adicionar ou remover tags ou intervalos de tags pode resultar em migrações de chunks. Dependendo do tamanho do conjunto de dados e do número de blocos que uma faixa de tags afeta, essas migrações podem afetar o desempenho do cluster. Considere executar seu balancer durante períodos agendados específicos. Consulte Agendamento da janela de balanceamento para obter um tutorial sobre como definir uma janela de agendamento.

Por padrão, o aplicativo grava no centro de dados mais próximo. Se o reconhecimento de data center local estiver inativo ou se as gravações nesse reconhecimento de data center não forem reconhecidas dentro de um período definido, a aplicação mudará para o outro reconhecimento de data center disponível alterando o valor do campo datacenter antes de tentar gravar o documento no banco de dados.

O aplicativo suporta tempos limite de gravação. O aplicativo usa o Write Concern para definir um tempo limite para cada operação de gravação.

Se o aplicativo encontrar um erro de gravação ou tempo limite, ele modificará o campo datacenter em cada documento e executará a gravação. Isso roteia o documento para o outro datacenter. Se ambos os data centers estiverem inativos, as gravações não poderão ser bem-sucedidas. Consulte Resolver falha de gravação.

O aplicativo verifica periodicamente a conectividade com quaisquer centros de dados marcados como "inativos". Se a conectividade for restaurada, o aplicativo poderá continuar executando operações normais de gravação.

Dada a lógica de comutação, bem como de quaisquer balanceadores de carga ou mecanismos semelhantes em vigor para lidar com o tráfego do cliente entre os centros de dados, o aplicativo não pode prever em qual dos dois centros de dados um determinado documento foi gravado. Para garantir que nenhum documento seja perdido como parte das operações de leitura, o aplicativo deve executar consultas de transmissão não incluindo o campo datacenter como parte de qualquer consulta.

O aplicativo realiza leituras usando uma preferência de leitura de nearest para reduzir a latência.

É possível que uma operação de gravação seja bem-sucedida apesar de um erro de tempo limite relatado. O aplicativo responde ao erro tentando reescrever o documento no outro datacenter - isso pode resultar na duplicação de um documento em ambos os datacenters. O aplicativo resolve duplicatas como parte da lógica de leitura .

O aplicativo tem lógica para trocar de datacenter se uma ou mais gravações falharem ou se as gravações não forem confirmadas dentro de um período de tempo definido. O aplicativo modifica o campo datacenter com base na marcação do datacenter de destino para direcionar o documento para esse datacenter.

Por exemplo, um aplicativo que tenta gravar no centro de dados alfa pode seguir este procedimento geral:

  1. Tentar escrever documento, especificando datacenter : alfa .

  2. Em caso de erro ou tempo limite de gravação, registre alfa como momentaneamente inativo.

  3. Tente escrever o mesmo documento, modificando datacenter : bravo .

  4. Em caso de erro ou tempo limite de gravação, registre bravo como momentaneamente inativo.

  5. Se alfa e bravo estiverem inativos, registre e relate erros.

Consulte Resolver falha de gravação.

Você deve estar conectado a um mongos associado ao cluster fragmentado de destino para prosseguir. Você não pode criar tags conectando-se diretamente a um membro do conjunto de réplicas de shard .

1

Marque cada fragmento no centro de dados alfa com a marcação alfa .

sh.addShardTag("shard0000", "alfa")

Marque cada fragmento no centro de dados bravo com a marcação bravo .

sh.addShardTag("shard0001", "bravo")

Você pode revisar as marcações atribuídas a qualquer fragmento específico executando sh.status().

2

Defina a faixa do banco de dados alfa e associe-a à marcação alfa usando o método sh.addTagRange() . Esse método requer:

  • O namespace completo da coleção de destino.

  • O limite inferior inclusivo do intervalo.

  • O limite superior exclusivo do intervalo.

  • O nome da marcação.

sh.addTagRange(
"<database>.<collection>",
{ "datacenter" : "alfa", "userid" : MinKey },
{ "datacenter" : "alfa", "userid" : MaxKey },
"alfa"
)

Defina a faixa do banco de dados bravo e associe-a à marcação bravo usando o método sh.addTagRange() . Esse método requer:

  • O namespace completo da coleção de destino.

  • O limite inferior inclusivo do intervalo.

  • O limite superior exclusivo do intervalo.

  • O nome da marcação.

sh.addTagRange(
"<database>.<collection>",
{ "datacenter" : "bravo", "userid" : MinKey },
{ "datacenter" : "bravo", "userid" : MaxKey },
"bravo"
)

Os valores MinKey e MaxKey são valores especiais reservados para comparações. MinKey sempre se compara como menor do que todos os outros valores possíveis, enquanto MaxKey sempre se compara como maior do que todos os outros valores possíveis. Os intervalos configurados capturam cada usuário para cada datacenter.

3

Na próxima vez que o balanceador for executado, ele migrará os dados entre os fragmentos respeitando as zonas configuradas.

Quando o balanceamento terminar, os fragmentos marcados como alfa devem conter documentos apenas com datacenter : alfa, enquanto os fragmentos marcados como bravo devem conter apenas documentos com datacenter : bravo.

Você pode revisar a distribuição de chunk executando sh.status().

Quando o centro de dados padrão do aplicativo está inativo ou inacessível, o aplicativo altera o campo datacenter para o outro centro de dados.

Por exemplo, o aplicativo tenta gravar o seguinte documento no centro de dados alfa por padrão:

{
"_id" : ObjectId("56f08c447fe58b2e96f595fa"),
"message_id" : 329620,
"datacenter" : "alfa",
"userid" : 123,
...
}

Se a aplicação receber um erro na tentativa de gravação ou se o reconhecimento de gravação demorar muito, a aplicação registrará o centro de dados como indisponível e alterará o campo datacenter para ponto para o centro de dados bravo .

{
"_id" : ObjectId("56f08c457fe58b2e96f595fb"),
"message_id" : 329620,
"datacenter" : "bravo",
"userid" : 123,
...
}

O aplicativo verifica periodicamente o centro de dados alfa para conectividade. Se o centro de dados estiver acessível novamente, o aplicativo poderá retomar as gravações normais.

Observação

É possível que a gravação original em datacenter : alfa tenha sido bem-sucedida, especialmente se o erro estiver relacionado a um tempo limite. Em caso afirmativo, o documento com message_id : 329620 agora pode ser duplicado em ambos os centros de dados. Os aplicativos devem resolver duplicatas como parte das operações de leitura.

A lógica de comutação do aplicativo permite a possível duplicação de documentos. Ao realizar leituras, o aplicativo resolve quaisquer documentos duplicados na camada do aplicativo.

A consulta a seguir pesquisa documentos em que userid é 123. Observe que, embora userid faça parte da chave de shard, a query não inclui o campo datacenter e, portanto, não executa uma operação de leitura direcionada.

db.collection.find( { "userid" : 123 } )

Os resultados mostram que o documento com message_id de 329620 foi inserido no MongoDB duas vezes, provavelmente como resultado de um reconhecimento de gravação atrasado.

{
"_id" : ObjectId("56f08c447fe58b2e96f595fa"),
"message_id" : 329620
"datacenter" : "alfa",
"userid" : 123,
data : {...}
}
{
"_id" : ObjectId("56f08c457fe58b2e96f595fb"),
"message_id" : 329620
"datacenter" : "bravo",
"userid" : 123,
...
}

O aplicativo pode ignorar as duplicatas, pegando um dos dois documentos, ou pode tentar cortar as duplicatas até que reste apenas um único documento.

Um método para cortar duplicatas é usar o método ObjectId.getTimestamp() para extrair o carimbo de data/hora do campo _id . O aplicativo pode então manter o primeiro documento inserido ou o último documento inserido. Isso pressupõe que o campo _id usa o MongoDB ObjectId().

Por exemplo, usar getTimestamp() no documento com ObjectId("56f08c447fe58b2e96f595fa") retorna:

ISODate("2016-03-22T00:05:24Z")

O uso getTimestamp() no documento com ObjectId("56f08c457fe58b2e96f595fb") retorna:

ISODate("2016-03-22T00:05:25Z")
← Segmentação de dados por aplicativo ou consumidor