A replicação do MongoDB (cópia) define o combate real e sua análise de princípio-04

Conjunto de réplicas do MongoDB

Arquitetura do Conjunto de Réplicas

Em um ambiente de produção, não é recomendado usar um servidor MongoDB independente. As razões são as seguintes:
       A versão autônoma do MongoDB não pode garantir a confiabilidade. Uma vez que o processo falhe ou o servidor caia, o negócio ficará diretamente indisponível.
        Assim que o disco no servidor for danificado, os dados serão perdidos diretamente e não haverá cópia disponível no momento. 
O conjunto de replicação Mongodb (conjunto de replicação) consiste em um grupo de instâncias Mongod (processos), incluindo um nó primário e vários nós secundários. Todos os dados do driver Mongodb (cliente) são gravados no primário e o secundário sincroniza os dados gravados do Primário. Para manter todos os membros no conjunto de réplicas armazenando o mesmo conjunto de dados, é fornecida alta disponibilidade de dados. Os conjuntos de réplica fornecem redundância e alta disponibilidade e são a base para todas as implantações de produção. Sua realidade depende da funcionalidade de dois aspectos:
       1. Quando os dados são gravados, eles são rapidamente copiados para outro nó independente
       2. Quando o nó que recebe a gravação falha, um novo nó de substituição é eleito automaticamente
Ao atingir alta disponibilidade, o conjunto de réplicas realiza várias outras funções adicionais:
Distribuição de dados : copia dados de uma região para outra, reduzindo a latência de leitura em outra região
Separação de leitura e gravação : Diferentes tipos de pressão são executados em diferentes nós
Recuperação de desastre fora do local : alterne rapidamente para fora do local quando o data center falhar
Modo de conjunto de réplicas de três nós
Uma arquitetura de conjunto de réplicas comum consiste em 3 nós membros, dos quais existem vários modos diferentes.
Modo PSS (modo oficial recomendado)
O modo PSS consiste em um nó primário e dois nós de espera, ou seja, Primário+Secundário+Secundário.

Este modo sempre fornece duas cópias completas do conjunto de dados. Se o nó primário não estiver disponível, o conjunto de réplicas escolhe o nó de espera como o nó primário
Clique e continue a operação normal. O antigo nó primário junta-se novamente ao conjunto de réplicas quando ele se torna disponível.

Modo PSA
O modo PSA consiste em um nó mestre, um nó standby e um nó arbitrador, ou seja,
Primário+Secundário+Árbitro

Entre eles, os nós do Árbitro não armazenam cópias de dados, nem fornecem operações de leitura e gravação de negócios. A falha do nó do árbitro não afeta
afetam negócios, apenas votos eleitorais. Este modo fornece apenas uma cópia completa dos dados e, se o nó primário não estiver disponível, o
O conjunto selecionará o nó de espera como o nó principal

Configuração típica do ambiente de conjunto de réplicas de três nós
        Mesmo que haja apenas um servidor por enquanto, inicie o conjunto de réplicas no modo de nó único
        Conjunto de replicação de inicialização de várias instâncias de máquina única
        Conjunto de réplicas de início de nó único
Considerações sobre o conjunto de réplicas
        Sobre hardware:
                Como os nós normais do conjunto de réplicas podem se tornar nós principais, seu status é o mesmo, portanto, a configuração de hardware deve ser consistente;
                Para garantir que os nós não caiam ao mesmo tempo, o hardware usado por cada nó deve ser independente.
        Sobre o software:
                A versão do software de cada nó no conjunto de réplicas deve ser consistente para evitar problemas imprevisíveis.
                Adicionar nós não aumentará o desempenho de gravação do sistema
preparação ambiental
        Instale o MongoDB e configure as variáveis ​​de ambiente
        Verifique se há mais de 10 GB de espaço no disco rígido
Preparar arquivos de configuração
        Cada processo mongod de um conjunto de réplicas deve residir em um servidor diferente. Agora estamos executando 3 processos em uma máquina, então temos que configurar cada um deles: Portas diferentes (28017/28018/28019) Diretórios de dados diferentes
mkdir ‐p /data/db{1,2,3}
Diferentes caminhos de arquivo de log (por exemplo: /data/db1/mongod.log)
Crie um arquivo de configuração /data/db1/mongod.conf com o seguinte conteúdo:
systemLog:
  destination: file
  path: /data/db1/mongod.log # log path
  logAppend: true
storage:
  dbPath: /data/db1 # data directory
net:
  bindIp: 0.0.0.0
  port: 28017 # port
replication:
  replSetName: rs0
processManagement:
  fork: true
Consulte a configuração acima para modificar a porta e o caminho e configure db2 e db3 sucessivamente. Observe que deve estar no formato yaml
Inicie o processo do MongoDB
mongod ‐f /data/db1/mongod.conf
mongod ‐f /data/db2/mongod.conf
mongod ‐f /data/db3/mongod.conf
Nota: Se o SELinux estiver ativado, pode impedir que o processo acima seja iniciado. Para simplificar, desative o SELinux
# 永久关闭,将SELINUX=enforcing改为SELINUX=disabled,设置后需要重启才能生效
 vim /etc/selinux/config
# 查看SELINUX
 /usr/sbin/sestatus ‐v
Configurar conjunto de réplicas
O conjunto de réplicas é inicializado por meio do comando replSetInitiate ou rs.initiate() do shell mongo. Após a inicialização, cada membro começa a enviar mensagens de pulsação e inicia uma operação de eleição do Priamry. O nó que foi votado pela "maioria" dos membros será tornam-se primários e os nós
Método 1
# mongo ‐‐port 28017
# 初始化复制集
> rs.initiate()
# 将其余成员添加到复制集
> rs.add("192.168.65.174:28018")
> rs.add("192.168.65.174:28019")
Método 2
# mongo ‐‐port 28017
 # 初始化复制集
 > rs.initiate({
     _id: "rs0",
     members: [{
             _id: 0,
             host: "192.168.65.174:28017"
         },{
             _id: 1,
             host: "192.168.65.174:28018"
         },{
             _id: 2,
             host: "192.168.65.174:28019"
     }]
 })
verificar
Nó primário do MongoDB para gravações
# mongo ‐‐port 28017
rs0:PRIMARY> db.user.insert([{name:"fox"},{name:"monkey"}])
MongoDB lê do nó
# mongo ‐‐port 28018
# 指定从节点可读
rs0:SECONDARY> rs.secondaryOk()
rs0:SECONDARY> db.user.find()
Consulta de status do conjunto de réplicas
Visualize o status geral do conjunto de réplicas:
rs.status()
Você pode visualizar o status atual de cada membro, incluindo se está íntegro, se está em sincronização total, informações de pulsação, informações de sincronização incremental, informações de eleição, hora da última pulsação, etc.
A coluna de membros reflete o status de todos os membros do conjunto de réplicas, principalmente da seguinte forma:
saúde: Se o membro está saudável ou não, detectado pelo heartbeat. state/stateStr: o estado do membro, PRIMARY significa o nó primário e SECONDARY significa o nó de espera, se o nó sair
Se houver uma falha, algum outro status pode aparecer, como RECUPERAÇÃO.
uptime: O tempo de atividade do membro.
optime/optimeDate: A hora do último oplog síncrono do membro.
optimeDurable/optimeDurableDate: A hora do último oplog síncrono do membro.
pingMs: O atraso do ping entre o membro e o nó atual.
syncingTo: a fonte de sincronização do membro.

Veja as funções atuais do nó:

db.isMaster()
Além das informações da função do nó atual, é uma informação mais simplificada e também retorna a lista de membros de todo o conjunto de réplicas, quem é o primário real, informações de configuração relacionadas ao protocolo etc., e o Driver enviará este comando ao conectar-se ao conjunto de réplicas pela primeira vez.

 Comandos do Conjunto de Réplicas do Mongo Shell

comando

descrever

rs . adicionar()

Adicionar novos nós

rs.ad dArb ()

Adicionar um

rs.conf()

Retorne as informações de configuração do conjunto de réplicas

rs.fr eeze ()

Impedir que o nó atual seja eleito como o nó mestre por um período de tempo

rs.ajuda()

 Ajuda de comando de retorno para conjunto de réplicas

rs. iniciar ()

Inicializar um novo conjunto de réplicas

rs.printReplicationInfo ( )

Retorna um relatório de status da replicação da perspectiva do nó mestre

rs.printSeconda ryReplicationInfo ()

Retorna um relatório de status de replicação da perspectiva do nó escravo

rs. reconfigurar ()

Atualize a configuração para o conjunto de réplicas reaplicando

rs.re mover ()

Remover um nó de um conjunto de réplicas

rs . secundárioOk ( )

Define o nó escravo para ser legível para a conexão atual

rs.st atus ()

Retorna informações de status do conjunto de réplicas.

rs. stepdown ()

Deixe o primário atual se tornar um nó escravo e acionar a eleição

rs. sincronizarDe ()

Defina o nó do qual o nó do conjunto de réplicas sincroniza os dados, o que substituirá a  lógica de seleção padrão

 Método de conexão do conjunto de réplicas

 

Método 2 (altamente recomendado) : Conecte-se ao MongoDB por meio de um Uri altamente disponível. Quando o primário falha, o driver do MongoDB pode detectar e rotear automaticamente o tráfego para o novo nó primário

 configuração do conjunto de réplicas da operação springboot

spring:
  data:
  mongodb:
  uri:
mongodb://yanqiuxiang:[email protected]:192.168.30.130:192.168.30.130:28019/test?authSource=admin&replicaSet=rs0
Funções de membros do conjunto de réplicas
Existem vários nós no conjunto de réplicas e cada nó tem responsabilidades diferentes. Antes de examinar as funções dos membros, entenda dois atributos importantes:
Atributo 1: Prioridade = 0
Quando Prioridade é igual a 0, não pode ser eleito mestre pelo conjunto de réplicas , quanto maior o valor de Prioridade, maior a probabilidade de ser eleito mestre. Normalmente, esse recurso pode ser usado para implantar conjuntos de réplicas em salas de computadores. Supondo que a sala de computadores A e a sala de computadores B sejam usadas, uma vez que o negócio principal está mais próximo da sala de computadores A, você pode definir a Prioridade do membro do conjunto de replicação da sala de computadores B como 0, de modo que o nó mestre deve ser um membro de sala de informática A.
Atributo 2: Voto = 0
Ele não pode participar da votação da eleição, e a Prioridade deste nó também deve ser 0 neste momento, ou seja, não pode ser eleito mestre. Como existem no máximo 7 membros votantes em um conjunto de réplicas, os membros extras devem definir o valor do atributo vote para 0, ou seja, esses membros não poderão participar da votação.
função de membro
        Primário: o nó primário, que recebe todas as solicitações de gravação e, em seguida, sincroniza a modificação com todos os nós de espera. Um conjunto de réplicas pode ter apenas um nó mestre. Quando o nó mestre "travar", outros nós reelegerão um nó mestre.
        Secundário: O nó de espera mantém o mesmo conjunto de dados do nó primário. Quando o nó mestre "trava", ele participa da eleição do nó mestre. Dividido nos três tipos diferentes a seguir: Oculto = falso: nó normal somente leitura, se pode ser selecionado como o nó principal e se pode votar depende do valor de Prioridade e Voto;
        Hidden = true: Nó oculto, invisível para o cliente, pode participar da eleição, mas a Prioridade deve ser 0 , ou seja, não pode ser promovido a mestre. Como os nós ocultos não aceitam acesso comercial, algumas tarefas de backup de dados e computação off-line podem ser executadas por meio de nós ocultos, o que não afetará todo o conjunto de replicação.
        Atrasado: Os nós atrasados ​​devem ter as características de nós ocultos e Priority0 ao mesmo tempo e serão atrasados ​​por um determinado período de tempo (
Decisão de configuração de SlaveDelay) replica incrementos de upstream, geralmente usados ​​em cenários de reversão rápida.
        Árbitro: o nó de arbitragem, que é usado apenas para participar da votação eleitoral, não carrega nenhum dado em si e serve apenas como função de votação. Por exemplo, se você implantar um conjunto de réplicas com 2 nós, 1 primário e 1 secundário, se algum nó ficar inativo, o conjunto de réplicas não poderá fornecer serviços (o primário não pode ser selecionado), então você pode adicionar um nó Arbiter para o conjunto de réplicas, mesmo se um nó estiver inativo, o Primário ainda poderá ser selecionado. O próprio árbitro não armazena dados e é um serviço muito leve. Quando o número de membros do conjunto de réplicas é par, é melhor adicionar nós de árbitro ㇐ para melhorar a disponibilidade do conjunto de réplicas

 

Configurar nós ocultos

Em muitos casos, definir os nós como nós ocultos é usado para ajudar os membros atrasados . Se nós só precisamos
Para evitar que esse nó se torne o nó mestre, podemos alcançá-lo por meio de prioridade 0 membro .
cfg = rs.conf()
cfg.members[1].priority = 0
cfg.members[1].hidden = true
rs.reconfig(cfg)
Uma vez definida, a prioridade do nó escravo será alterada para 0 para evitar que ele seja promovido a nó mestre, além de ser invisível para o aplicativo. Executar db.isMaster() em outros nós não mostrará nós ocultos.
Configurar nós de atraso
Quando configuramos um nó atrasado, o processo de replicação e o oplog do nó serão atrasados. O conjunto de dados no nó atrasado será posterior ao conjunto de dados no nó primário no conjunto de réplicas. Por exemplo, agora são 09:52, se o nó de atraso for atrasado em 1 hora, não haverá operações após 08:52 no conjunto de dados do nó de atraso.
cfg = rs.conf()
cfg.members[1].priority = 0
cfg.members[1].hidden = true
#延迟1分钟
cfg.members[1].slaveDelay = 60
rs.reconfig(cfg)
Ver atraso de replicação
Se você deseja visualizar o oplog do nó atual, pode usar o comando rs.printReplicationInfo()

Isso descreve claramente o tamanho do oplog, o tempo de geração do primeiro oplog e do último oplog, e o comprimento do log do início ao fim refere-se a uma janela de replicação (diferença de tempo). Normalmente, quando o tamanho do oplog permanece constante, quanto mais frequente a operação de gravação de negócios, menor será a janela de replicação. Execute o comando rs.printSecondaryReplicationInfo() no nó para listar os atrasos de sincronização de todos os membros do nó em espera

Adicionar nó de votação

# 为仲裁节点创建数据目录,存放配置数据。该目录将不保存数据集
mkdir /data/arb
# 启动仲裁节点,指定数据目录和复制集名称
mongod ‐‐port 30000 ‐‐dbpath /data/arb ‐‐replSet rs0
# 进入mongo shell,添加仲裁节点到复制集
rs.addArb("ip:30000")
Remover um nó do conjunto de réplicas
Use rs.remove() para remover nós
rs.remove("ip:port")
Remover nós por rs.reconfig()
cfg = rs.conf()
cfg.members.splice(2,1) #从2开始移除1个元素
rs.reconfig(cfg)
Alterar os nós do conjunto de réplicas
cfg = rs.conf()
cfg.members[0].host = "ip:port"
rs.reconfig(cfg)
Alta disponibilidade do conjunto de réplicas
eleição do conjunto de réplicas
A eleição do conjunto de réplicas do MongoDB é implementada usando o algoritmo Raft ( https://raft.github.io/ ) . A condição necessária para uma eleição bem-sucedida é que a maioria dos nós de votação sobrevivam . Na implementação específica, o MongoDB adiciona algumas extensões ao protocolo raft, incluindo:
Oferece suporte à replicação em cadeia chainingAllowed, ou seja, o nó de backup não apenas sincroniza dados do nó mestre, mas também seleciona um nó mais próximo a si mesmo (com o menor atraso de pulsação) para replicar dados .
Adicionado o estágio de pré-votação, ou seja, preVote, que é usado principalmente para evitar o problema de aumento do valor do termo (termo) quando a rede é particionada
Prioridade de votação de suporte . Se o nó de espera descobrir que sua prioridade é maior que a do nó primário, ele iniciará ativamente uma votação e tentará se tornar o novo nó primário
Um conjunto de réplicas pode ter até 50 membros, mas apenas 7 membros votantes. Isso ocorre porque, uma vez que muitos membros participem do processo de replicação e votação de dados, isso trará mais problemas de confiabilidade.

Membros votantes

maioria

Número de Falhas Toleradas

1

1

0

2

2

0

3

2

1

4

3

1

5

3

2

6

4

2

7

4

3

Quando o número de membros sobreviventes no conjunto de réplicas for menor que a maioria, todo o conjunto de réplicas não poderá eleger um nó primário e, neste momento, não poderá fornecer serviços de gravação, e esses nós estarão em um estado somente leitura . Além disso, se você quiser evitar o resultado de um ticket de empate, é melhor usar um número ímpar de membros do nó, como 3 ou 5. Obviamente, na implementação do conjunto de réplicas do MongoDB, foi fornecida uma solução para o problema do bilhete simples:
        Adicione uma pequena quantidade de desvio de tempo aleatório ao cronômetro de eleição, para evitar que cada nó inicie uma eleição ao mesmo tempo e melhore a taxa de sucesso.
        Use a função de árbitro, essa função não executa replicação de dados, não realiza serviços de leitura e gravação e é usada apenas para votação.
failover automático
Em um cenário de failover, nossas preocupações são:
        Como o nó de espera percebe que o nó primário falhou?
        Como reduzir o impacto do failover nos negócios?

        Um fator que afeta o mecanismo de detecção é o heartbeat. Depois que o conjunto de réplicas é estabelecido, cada nodo do membro iniciará um timer e continuará enviando heartbeats para outros membros. O parâmetro envolvido aqui é heartbeatIntervalMillis, que é o intervalo do heartbeat, e o padrão o valor é 2s. Se a pulsação for bem-sucedida, a pulsação continuará a ser enviada em uma frequência de 2s; se a pulsação falhar, a pulsação será repetida imediatamente até que seja retomada com sucesso.
        Outro fator importante é a detecção de tempo limite de eleição, uma falha de detecção de pulsação não aciona imediatamente uma reeleição. real
Além do heartbeat, os nós membros também iniciarão um timer de detecção de timeout de eleição, que é executado em um intervalo de 10s por padrão, que pode ser especificado pelo parâmetro selectionTimeoutMillis: Se a resposta de heartbeat for bem-sucedida, o último agendamento selectionTimeout será ser cancelado (garantido para não iniciar a eleição) e iniciar uma nova rodada de agendamento de tempo limite de eleição. Se a resposta de pulsação falhar por muito tempo, a tarefa selectionTimeout será acionada, fazendo com que o nó em espera inicie uma eleição e se torne o novo nó primário. Na implementação do MongoDB, o período de detecção de tempo limite de eleição é um pouco mais longo do que a configuração de selectionTimeoutMillis. Um deslocamento aleatório será adicionado a esse período, que é de cerca de 10 a 11,5 segundos. Esse design é escalonar o tempo de seleção ativa de vários nós de espera e melhorar a taxa de sucesso.
Portanto, as seguintes condições devem ser atendidas para acionar uma eleição na tarefa selectionTimeout:
(1) O nó atual é o nó de espera.
(2) O nó atual tem autoridade eleitoral.
(3) Ainda não há sucesso na pulsação com o nó mestre dentro do período de detecção.

 Avaliação de impacto nos negócios

No caso de comutação de nó ativo/em espera no conjunto de réplicas, haverá um curto período sem nó ativo e as operações de gravação de negócios não podem ser aceitas neste momento. Se a troca for causada pela falha do nó primário, todas as operações de leitura e gravação no nó expirarão. Se você usar o driver do MongoDB 3.6 e superior, poderá reduzir o impacto ativando retryWrite.
# MongoDB Drivers 启用可重试写入
mongodb://localhost/?retryWrites=true
# mongo shell
mongo ‐‐retryWrites
Se o nó mestre for forçado a desligar, todo o processo de failover será mais longo e poderá ser detectado e recuperado por outros nós após o término do timer de seleção. Essa janela de tempo geralmente é de 12 segundos. No entanto, na prática, a consideração da perda da chamada de serviço também deve incluir o monitoramento do cliente ou mongos e a percepção do papel do conjunto de réplicas (a situação real pode levar até 30 segundos ou mais).
Para negócios muito importantes, é recomendável implementar algumas estratégias de proteção no nível do negócio, como projetar um mecanismo de repetição.
Pensando: como reiniciar normalmente o conjunto de réplicas?
Se você deseja reiniciar o conjunto de réplicas sem perder dados, uma maneira mais elegante de abri-lo deve ser a seguinte:
1. Reinicie todos os nós secundários no conjunto de réplicas, um por um
2. Envie o comando rs.stepDown() para o Primário e espere que o Primário seja rebaixado para Secundário
3. Reinicie o primário rebaixado
Mecanismo de sincronização de dados do conjunto de réplicas
       Na arquitetura do conjunto de réplicas, os dados são sincronizados entre o nó primário e o nó de espera por meio do oplog . O oplog aqui é um conjunto fixo especial. Quando uma operação de gravação no nó primário é concluída, um registro correspondente será gravado no oplog set. logs, enquanto o nó de espera puxa continuamente novos logs por meio deste oplog e os reproduz localmente para obter a sincronização de dados

 o que é oplog

        MongoDB o plog é uma coleção na biblioteca Local, que é usada para salvar logs incrementais gerados por operações de gravação (semelhante ao Binlog no MySQL).
        É uma Capped Collection (coleção fixa) , ou seja, quando o valor máximo configurado for excedido, os dados históricos mais antigos serão excluídos automaticamente.O MongoDB possui uma otimização especial para exclusão de o plog para melhorar a eficiência da exclusão.
        O nó mestre gera uma nova entrada o plog e o nó escravo mantém o mesmo estado que o nó mestre copiando o o plog e aplicando-o;
ver oplog
use local
db.oplog.rs.find().sort({$natural:‐1}).pretty()
local.system.replset: usado para registrar os membros do conjunto de réplicas atual.
local.startup_log: Usado para registrar as informações do log de inicialização do banco de dados local.
local.replset.minvalid: Usado para registrar as informações de rastreamento do conjunto de réplicas, como os campos necessários para a sincronização inicial.
ts: tempo de operação, timestamp atual + contador, o contador é zerado a cada segundo
v: informações da versão do oplog
op: tipo de operação:
i: operação de inserção
u: operação de atualização
d: operação de exclusão
c: Execute comandos (como createDatabase, dropDatabase)
n: sem operação, propósito especial
ns: o conjunto para operar
o: conteúdo da operação
o2: condição de consulta da operação, apenas a operação de atualização contém este campo
O campo ts descreve o timestamp gerado pelo oplog, que pode ser chamado de optime. Optime é a chave para o nó standby realizar a sincronização de log incremental . Ele garante que o oplog esteja em ordem. Ele consiste em duas partes:
        A hora atual do sistema, ou seja, o número de segundos desde a hora do UNIX até o presente, 32 bits.
        Temporizador inteiro, diferentes valores de tempo irão zerar o contador, 32 bits
        Optime pertence ao tipo Timestamp de BSON, que geralmente é usado internamente pelo MongoDB. Como o oplog garante a ordem no nível do nó, o nó em espera pode ser puxado por votação e a tecnologia de cursor tailable será usada aqui.
Cada nodo standby mantém seu próprio offset, ou seja, o oplog do último log puxado do nodo primário, ao realizar a sincronização, ele utiliza este optime para consultar o conjunto de oplog do nodo primário. Para evitar iniciar constantemente novos links de consulta, você pode travar o cursor após iniciar a primeira consulta (configurando o cursor como ajustável). Desta forma, enquanto novos registros forem gerados no oplog, o nó standby poderá utilizar o mesmo canal de requisição para obter estes dados. O cursor tailable só pode ser habilitado quando a coleção consultada for uma coleção fixa.

O tamanho da coleção oplog
O tamanho da coleção oplog pode ser definido pelo parâmetro replicação.oplogSizeMB. Para sistemas de 64 bits,
O valor padrão de oplog é:
oplogSizeMB = min(磁盘可用空间*5%,50GB)
Para a maioria dos cenários de negócios, é difícil avaliar um oplogSize apropriado no início, felizmente
O MongoDB fornece o comando replSetResizeOplog após a versão 4.0, que pode modificar dinamicamente o oplogSize
sem reiniciar o servidor.
# 将复制集成员的oplog大小修改为60g 指定大小必须大于990M
db.adminCommand({replSetResizeOplog: 1, size: 60000})
# 查看oplog大小
use local
db.oplog.rs.stats().maxSize
idempotência
Cada registro oplog descreve uma alteração atômica de dados. Para oplog, deve-se garantir que seja idempotente . Ou seja, para o mesmo oplog, não importa quantas operações de reprodução sejam realizadas, o estado final dos dados permanecerá inalterado. O valor atual do campo x de um determinado documento é 100, e o usuário envia um {$inc: {x: 1}} para o Primário, que será convertido em uma operação {$set: {x: 101} quando gravando o oplog, de forma a garantir a idempotência.
O preço da idempotência
Para a operação de elementos simples, a conversão de $inc para $set não tem efeito e o custo de execução é semelhante, mas quando se trata de operações de elementos de array, a situação é diferente.
teste
db.coll.insert({_id:1,x:[1,2,3]})
Empurre 2 elementos no final da matriz, verifique o oplog e descubra que a operação $push foi convertida em uma operação $set (defina a matriz para especificar
elemento na posição é algum valor)
rs0:PRIMARY> db.coll.update({_id: 1}, {$push: {x: { $each: [4, 5] }}})
 WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
 rs0:PRIMARY> db.coll.find()
 { "_id" : 1, "x" : [ 1, 2, 3, 4, 5 ] }
 rs0:PRIMARY> use local
 switched to db local
 rs0:PRIMARY> db.oplog.rs.find({ns:"test.coll"}).sort({$natural:‐1}).prett
()
 {
 "op" : "u",
 "ns" : "test.coll",
 "ui" : UUID("69c871e8‐8f99‐4734‐be5f‐c9c5d8565198"),
 "o" : {
 "$v" : 1,
 "$set" : {
 "x.3" : 4,
 "x.4" : 5
 }
 },
 "o2" : {
 "_id" : 1
 },
 "ts" : Timestamp(1646223051, 1),
 "t" : NumberLong(4),
 "v" : NumberLong(2),
 "wall" : ISODate("2022‐03‐02T12:10:51.882Z")
 }
O custo de converter $push em $set com uma posição específica é semelhante, mas vamos adicionar 2 elementos ao topo do array

Pode-se constatar que ao adicionar elementos à cabeça do array , a operação $set no oplog não está mais definindo o valor de uma determinada posição no array (porque basicamente todas as posições dos elementos foram ajustadas), mas o valor final resultado da matriz $set, ou seja, o conteúdo da matriz inteira deve ser gravado no oplog. Quando a operação push especifica o parâmetro $slice ou $sort, o método de gravação oplog é o mesmo e todo o conteúdo da matriz será usado como o parâmetro de $set. Operadores de atualização como $pull e $addToSet são semelhantes. Após atualizar o array, o oplog será convertido no conteúdo final do array $set para garantir a idempotência.
A gravação do oplog é amplificada, fazendo com que a sincronização não seja atualizada - grande atualização da matriz
Quando a matriz é muito grande, uma pequena atualização na matriz pode exigir que o conteúdo de toda a matriz seja registrado no oplog. Encontrei um caso real de ambiente de produção em que o documento do usuário continha um grande campo de matriz, 1000 O tamanho total de os elementos é de cerca de 64 KB. Os elementos nesta matriz são armazenados na ordem inversa do tempo e os elementos recém-inserido serão colocados na frente da matriz.
($position: 0), então mantenha os primeiros 1000 elementos do array ($slice: 1000).
Como resultado do cenário acima, toda vez que um novo elemento é inserido no array do Primário (a requisição tem cerca de algumas centenas de bytes), o conteúdo de todo o array deve ser registrado no oplog. O Secundário puxará o oplog e reproduzi-lo durante a sincronização, e o Primário sincronizará o oplog com o Secundário. O tráfego é centenas de vezes maior do que o tráfego de rede cliente-Primário, resultando em tráfego total entre os NICs primário e de backup. Além disso, devido a a grande quantidade de oplog, o conteúdo antigo é excluído rapidamente, o que eventualmente faz com que o Secundário não consiga alcançá-lo e converta-o para o estado RECOVERING. . Ao usar arrays em documentos, você deve prestar atenção aos problemas acima para evitar o problema de que a atualização do array fará com que a sobrecarga de sincronização seja ampliada infinitamente. Ao usar matrizes, tente prestar atenção a:
        1. O número de elementos na matriz não deve ser muito grande e o tamanho total não deve ser muito grande
        2. Tente evitar atualizar o array
        3. Se você precisar atualizar, tente inserir apenas elementos no final. Lógica complexa pode ser considerada para suporte no nível de negócios

atraso de replicação
Como a coleção de oplog tem um tamanho fixo, o oplog armazenado nela pode ser liberado por novos registros a qualquer momento. Se a replicação do nó de espera não for rápida o suficiente, ela não poderá acompanhar o ritmo do nó primário, resultando em um problema de atraso de replicação . Isso não pode ser ignorado. Uma vez que o atraso do nó de espera é muito grande, haverá um risco de quebra de replicação a qualquer momento, o que significa que o optime (o registro de sincronização mais recente) do nó de espera foi ultrapassado pelo primário nó, portanto, o nó de espera não poderá continuar a sincronização de dados.
Para evitar ao máximo o risco de atraso na replicação, podemos tomar algumas medidas, como:
        Aumente o tamanho do oplog e continue monitorando a janela de replicação.
        Reduza a velocidade de gravação do nó primário por meio de alguns meios de dimensionamento.
        Otimize a rede entre os nós ativos e em espera.
        Evite usar matrizes muito grandes para campos (pode causar inchaço do oplog) .

reversão de dados
        Como o atraso na replicação é inevitável, isso significa que os dados entre os nós primário e secundário não podem ser mantidos em sincronização absoluta. Quando o nó mestre no conjunto de replicação ficar inativo, o nó em espera será reeleito como o novo nó mestre. Então, quando o nó mestre antigo se reintegrar, alguns "dados sujos de log" anteriores devem ser revertidos para garantir que o conjunto de dados seja consistente com o novo nó mestre. Quanto maior a lacuna entre os conjuntos de replicação principal e de backup, maior o risco de reversões massivas de dados.
         Para os dados de negócios gravados, se tiverem sido replicados para a maioria dos nós no conjunto de replicação, o risco de retrocesso pode ser evitado. O aplicativo pode garantir a persistência dos dados definindo um nível de gravação mais alto (writeConcern: majoritário). Os dados revertidos pelo nó mestre antigo serão gravados em um diretório de reversão separado e os dados ainda poderão ser restaurados, se necessário.
Quando ocorre um rollback, o MongoDB armazenará os dados do rollback no formato BSON na pasta rollback no caminho dbpath. O formato de nomenclatura do arquivo BSON é o seguinte: <database>.<collection>.<timestamp>.bson
mongorestore ‐‐host 192.168.30.130:27018 ‐‐db test ‐‐collection emp ‐u yanqiuxiang ‐p
yanqiuxiang
‐‐authenticationDatabase=admin rollback/emp_rollback.bson
Sincronizar seleção de fonte
O MongoDB permite a replicação através do nó standby, que ocorre nas seguintes situações:
Quando settings.chainingAllowed está ativado, o nó em espera seleciona automaticamente o nó mais próximo (com o menor atraso de comando de ping) para sincronização. A opção settings.chainingAllowed é habilitada por padrão, ou seja, por padrão, o nó standby não necessariamente escolhe o nó primário para sincronização. Este efeito colateral aumentará o atraso. Você pode desativá-lo pelas seguintes operações:
cfg = rs.config()
cfg.settings.chainingAllowed = false
rs.reconfig(cfg)
Use o comando replSetSyncFrom para alterar temporariamente a fonte de sincronização do nó atual. Por exemplo, ao inicializar a sincronização, aponte a fonte de sincronização para o nó em espera para reduzir o impacto no nó primário.
db.adminCommand( { replSetSyncFrom: "hostname:port" })

Acho que você gosta

Origin blog.csdn.net/u011134399/article/details/131270334
Recomendado
Clasificación