O que acontece se houver muitas inserções no MongoDB? Como garantir que todos os dados sejam armazenados?

24

Eu uso o MongoDB para armazenar valores medidos periodicamente. A cada ~ 100 ms, um monte de valores é inserido como documento. Funciona bem, mas estou preocupado com problemas de desempenho. (Eu uso inserções seguras, parece que no PyMongo esse é o padrão.)

O que acontece se houver mais inserções por segundo do que o mongod é capaz de salvar no disco rígido? Haverá algum aviso ou simplesmente falhará silenciosamente?

Existe algum método para monitorar a carga de gravação? Eu encontrei apenas o db.serverStatus().writeBacksQueuedque sempre é definido como falso quando eu o chamo. Como eu pude testar a quantidade de dados que tenho para inserir para preencher a fila de gravação?

mongostatexibe bloqueios. É com isso que eu deveria me preocupar?

insert  query update delete getmore command flushes mapped  vsize    res faults  locked db idx miss %     qr|qw   ar|aw  netIn netOut  conn repl       time 
  *117     *0     *0     *0       0     2|0       0  17.4g  35.3g  3.76g      0     .:6.5%          0       0|0     0|0   124b     6k     2  SLV   09:58:10 
  *111     *0     *0     *0       0     2|0       0  17.4g  35.3g  3.76g      0     .:0.8%          0       0|0     0|0   124b     6k     2  SLV   09:58:11 
  *111     *0     *0     *0       0     2|0       0  17.4g  35.3g  3.76g      0     .:4.2%          0       0|0     0|0   124b     6k     2  SLV   09:58:1

Preciso me preocupar com bloqueios de gravação? O que acontece com uma inserção durante um período de tempo bloqueado de gravação? É colocado na fila e armazenado mais tarde?

Estou pensando em uma instalação simples de replicação usando um mestre e um escravo. A sincronização inicial ou um processo de ressincronização bloqueia os bancos de dados?

(Estou usando a versão 2.4.3.)

Atualização: acho que parcialmente respondi à minha própria pergunta. Consegui obter até 12.000 inserções por segundo usando um loop while simples, inserindo um pequeno documento de teste. Mas qr | qw ainda mostra que há a fila de leitura e gravação ainda está vazia:

insert  query update delete getmore command flushes mapped  vsize    res faults       locked db idx miss %     qr|qw   ar|aw  netIn netOut  conn repl       time 
 11234     *0      2     *0    1563     1|0       1  21.9g  44.3g  1.22g      0    testdb:58.9%          0       1|0     1|1   797k   980k     6  PRI   10:26:32 
 12768     *0      2     *0    1284     1|0       0  21.9g  44.3g  1.22g      0    testdb:58.0%          0       0|0     0|1   881k     1m     6  PRI   10:26:33 
 12839     *0      2     *0    1231     1|0       0  21.9g  44.3g  1.22g      0    testdb:60.3%          0       0|0     0|1   883k     1m     6  PRI   10:26:34 
 12701     *0      2     *0     910     1|0       0  21.9g  44.3g  1.22g      0    testdb:61.8%          0       0|0     0|1   858k     1m     6  PRI   10:26:35 
 12241     *0      2     *0    1206     1|0       0  21.9g  44.3g  1.22g      0    testdb:56.7%          0       0|0     0|0   843k     1m     6  PRI   10:26:36 
 11581     *0      2     *0    1406     1|0       0  21.9g  44.3g  1.22g      0    testdb:61.8%          0       0|0     0|1   811k     1m     6  PRI   10:26:37 
  8719     *0      2     *0    1210     1|0       0  21.9g  44.3g  1.22g      0    testdb:43.8%          0       0|0     0|1   618k   762k     6  PRI   10:26:38 
 11429     *0      2     *0    1469     1|0       0  21.9g  44.3g  1.22g      0    testdb:60.6%          0       0|0     0|1   804k   993k     6  PRI   10:26:39 
 12779     *0      2     *0    1092     1|0       0  21.9g  44.3g  1.22g      0    testdb:60.2%          0       1|0     0|1   872k     1m     6  PRI   10:26:40 
 12757     *0      2     *0     436     1|0       0  21.9g  44.3g  1.22g      0    testdb:59.7%          0       0|0     0|1   838k   432k     6  PRI   10:26:41 

Suponho que isso significa que apenas as inserções não causarão muitos problemas: "As filas tenderão a aumentar se você estiver executando muitas operações de gravação ao lado de outras operações pesadas de gravação, como remoções a grande distância". (encontrado aqui )

Minha pergunta em aberto: O que acontece com meus dados se a fila de gravação aumentar em longo prazo?

lumbric
fonte

Respostas:

25

Você respondeu algumas de suas próprias perguntas aqui, especificamente, você tem uma idéia decente sobre o aspecto de bloqueio de gravação da equação - 12.000 inserção / s leva a ~ 60% do bloqueio de gravação. Esse é um nível razoável para obter um desempenho consistente - você terá algumas contendas e algumas operações serão um pouco mais lentas, mas você realmente quer começar a se preocupar com cerca de 80% - como muitas coisas, quando começar a exceder 80% disponível capacidade, você começará a enfrentar problemas com muito mais frequência.

Em termos de outros gargalos, e especificamente a rapidez com que você pode gravar no disco - isso pode causar problemas, mas, para examinar as estatísticas relevantes ao longo do tempo, eu recomendaria instalar o MMS com o plugin munin-node para fornecer estatísticas de hardware e IO em além das estatísticas do MongoDB.

Quando você tem isso, as métricas que você deseja acompanhar são:

  • O tempo médio de liberação (esse é o tempo que a sincronização periódica do MongoDB para o disco está demorando)
  • Os IOStats na guia hardware (IOWait em particular)
  • Falhas na página (se o seu disco estiver ocupado com gravações e você precisar ler dados, eles competirão por um recurso escasso)

É um pouco complicado, mas aqui está uma idéia básica:

  • Quando o tempo médio de descarga começar a aumentar, fique preocupado
  • Se chegar ao intervalo de vários segundos, você provavelmente estará no limite (embora isso dependa do volume de dados gravados e da velocidade do disco)
  • Se ele se aproximar de 60 segundos, você verá um desempenho severo (o flush ocorre a cada 60 segundos, portanto, eles basicamente estariam na fila)
  • Alto IOWait também prejudicará o desempenho, especialmente se você precisar ler do disco a qualquer momento
  • Portanto, analisar os níveis de falha da página também será importante

A outra peça deste quebra-cabeça, que ainda não mencionamos, é o diário. Esses dados também persistirão no disco (por padrão, a cada 100 ms) e, portanto, serão adicionados à carga do disco, se estiver no mesmo volume. Portanto, se você estiver vendo alta utilização do disco, mover o diário para outro disco seria uma boa ideia.

Não há "números mágicos" reais para ficar abaixo, na maioria dos casos é tudo relativo; portanto, obtenha uma boa linha de base para o tráfego normal, verifique se as coisas estão tendendo e talvez teste de carga para ver quais são seus limites e quando as coisas estão comece a se degradar e você estará em boa forma.

Depois de tudo isso preâmbulo, para algumas de suas perguntas:

O que acontece se houver mais inserções por segundo do que o mongod é capaz de salvar no disco rígido? Haverá algum aviso ou simplesmente falhará silenciosamente?

Se você começar a sobrecarregar o disco nos níveis descritos acima, eventualmente tudo ficará mais lento e, em algum momento (e isso dependerá de tempos limite, quão robusto é seu hardware, como você lida com exceções) suas gravações falharão - se Se você estiver usando uma versão recente do pymongo, usará gravações seguras por padrão e elas falharão. Se você deseja ser um pouco mais paranóico, pode ocasionalmente fazer uma preocupação com a gravação de j: true, que aguardará para retornar OK até que a gravação chegue ao diário (ou seja, no disco). Obviamente, isso será mais lento que uma gravação segura normal, mas será uma indicação imediata de problemas relacionados à capacidade do disco, e você poderá usá-lo para bloquear / enfileirar outras operações e, essencialmente, atuar como um acelerador para impedir que seu banco de dados seja sobrecarregado.

Estou pensando em uma instalação simples de replicação usando um mestre e um escravo. A sincronização inicial ou um processo de ressincronização bloqueia os bancos de dados?

Acho que cobri o bloqueio geral no início, mas para responder especificamente a esta parte: Primeiro, verifique se você está usando um conjunto de réplicas , não mestre / escravo. A implementação mestre / escravo foi descontinuada e não é recomendada para uso em geral. Quanto à sincronização inicial, adicionará alguma carga ao primário em termos de leituras, mas não em termos de gravações; portanto, você deve se dar bem em termos de bloqueio.

O que acontece com meus dados se a fila de gravação aumentar a longo prazo?

Como você provavelmente pode perceber pela explicação acima, a resposta depende muito de como você escreve seu aplicativo, como você escolhe que suas gravações sejam reconhecidas e quanta capacidade você tem disponível. Você pode, essencialmente, estar tão seguro quanto desejar quando se trata de gravar em disco no MongoDB, mas há uma troca de desempenho, conforme mencionado na j:truediscussão acima.

Geralmente, você deseja descobrir o seu fator limitante - seja travamento, velocidade do disco, etc.

Uma última coisa, db.serverStatus().writeBacksQueuedna verdade , é uma métrica que nunca será zero em um ambiente fragmentado, e tem a ver com garantir que as gravações em um pedaço durante uma migração sejam tratadas adequadamente (manipuladas pelo ouvinte de write - back ). Portanto, aqui é essencialmente um arenque vermelho - nada a ver com o volume geral de gravação.

Adam C
fonte