MongoDB e conjuntos de dados que não se encaixam na RAM, não importa o quanto você empurre

12

Isso é muito dependente do sistema, mas as chances são quase certas de que vamos passar por cima de alguns penhascos arbitrários e entrar no Real Trouble. Estou curioso para saber que tipo de regra geral existe para uma boa RAM em relação ao espaço em disco. Estamos planejando nossa próxima rodada de sistemas e precisamos fazer algumas escolhas em relação a RAM, SSDs e quanto de cada um dos novos nós obterá.

Mas agora, para alguns detalhes de desempenho!

Durante o fluxo de trabalho normal de uma única execução de projeto, o MongoDB é atingido com uma porcentagem muito alta de gravações (70-80%). Quando o segundo estágio do pipeline de processamento é atingido, ele é extremamente alto, pois precisa desduplicar os registros identificados na primeira metade do processamento. Este é o fluxo de trabalho para o qual "manter seu conjunto de trabalho na RAM" é feito e estamos projetando em torno dessa suposição.

Todo o conjunto de dados é continuamente atingido com consultas aleatórias de fontes derivadas do usuário final; embora a frequência seja irregular, o tamanho é geralmente muito pequeno (grupos de 10 documentos). Como isso é voltado para o usuário, as respostas precisam estar abaixo do limite "entediado" de 3 segundos. É muito menos provável que esse padrão de acesso esteja no cache, portanto, é muito provável que ele acarrete hits de disco.

Um fluxo de trabalho de processamento secundário é uma leitura alta de execuções de processamento anteriores que podem durar dias, semanas ou até meses e é executado com pouca frequência, mas ainda precisa ser zippy. Até 100% dos documentos na execução do processamento anterior serão acessados. Nenhuma quantidade de cache-warming pode ajudar com isso, eu suspeito.

O tamanho dos documentos finais varia muito, mas o tamanho mediano é de cerca de 8K.

A parte de leitura alta do processamento normal do projeto sugere strongmente o uso de réplicas para ajudar a distribuir o tráfego de leitura. Eu li em outro lugar que uma RAM de 1:10 para HD-GB é uma boa regra prática para lentidão Como estamos pensando seriamente em usar SSDs muito mais rápidos, eu gostaria de saber se existe uma regra prática semelhante para discos rápidos.

Sei que estamos usando o Mongo de uma maneira em que o cache realmente não vai voar, e é por isso que estou procurando maneiras de projetar um sistema que possa sobreviver a esse uso. O conjunto de dados inteiro provavelmente terá a maior parte de uma TB dentro de meio ano e continuará crescendo.

    
por sysadmin1138 16.07.2012 / 13:32

3 respostas

5

Isso vai ser um monte de pequenos pontos. Infelizmente, não há uma resposta única para a sua pergunta.

O MongoDB permite que o kernel do sistema operacional manipule o gerenciamento de memória. Além de jogar o máximo possível de RAM no problema, existem apenas algumas coisas que podem ser feitas para 'gerenciar ativamente' seu Conjunto de Trabalho.

A única coisa que você pode fazer para otimizar as gravações é primeiro consultar esse registro (fazer uma leitura), para que fique na memória de trabalho. Isso evitará os problemas de desempenho associados ao bloqueio global do processo (que deve se tornar per-db em v2.2)

Não existe uma regra rígida para relação RAM vs SSD, mas acho que as IOPS brutas de SSDs devem permitir que você use uma proporção muito menor. Fora do topo da minha cabeça, 1: 3 é provavelmente o menor que você quer ir. Mas, considerando os custos mais altos e as capacidades mais baixas, é provável que você precise manter esse índice baixo de qualquer maneira.

Com relação às fases de 'gravação versus leitura', estou lendo corretamente que, uma vez que um registro é gravado, ele raramente é atualizado ("alterado")? Se for esse o caso, pode valer a pena hospedar dois clusters; o cluster de gravação normal e o cluster otimizado para leitura para dados "antigos" que não foram modificados em [período de tempo X] . Eu definitivamente habilitaria leitura de escravo neste cluster. (Pessoalmente, eu gerenciaria isso incluindo um valor modificado de data nos documentos de objeto do banco de dados.)

Se você tiver a capacidade de fazer um teste de carga antes de entrar no Prod, o perf monitore o inferno fora disso. O MongoDB foi escrito com a suposição de que muitas vezes seria implantado em VMs (seus sistemas de referência estão no EC2), portanto, não tenha medo de compartilhar com as VMs.

    
por 16.07.2012 / 14:20
13

Pretende-se isto como uma adenda às outras respostas publicadas aqui, que discute muitos dos elementos relevantes a serem considerados aqui. No entanto, há outro fator frequentemente negligenciado quando se trata de utilização eficiente de RAM em um sistema de tipo de acesso aleatório - readahead.

Você pode verificar as configurações atuais para readahead (no Linux) executando blockdev --report (geralmente requer privilégios sudo / root). Isso imprimirá uma tabela com uma linha para cada dispositivo de disco. A coluna RA contém o valor para readahead. Esse valor é o número de setores de 512 bytes (a menos que o tamanho do setor não seja o padrão - observe que, na hora de escrever este post, mesmo discos com tamanhos maiores são tratados como setores de 512 bytes pelo kernel) que são lidos em todos os acesso ao disco.

Você pode definir a configuração de leitura antecipada para um determinado dispositivo de disco executando:

blockdev --setra <value> <device name>

Ao usar um sistema RAID baseado em software, certifique-se de definir o readahead em cada dispositivo de disco, bem como no dispositivo que corresponde ao controlador RAID.

Por que isso é importante? Bem, readahead usa o mesmo recurso que o MongoDB está tentando usar para otimizar suas leituras de acesso seqüencial - RAM. Quando você está fazendo leituras seqüenciais em discos giratórios (ou dispositivos que se comportam como discos giratórios de qualquer maneira - EBS estou olhando para você), buscar os dados próximos na RAM pode aumentar o desempenho de forma massiva, economizar em buscas e uma configuração de leitura rápida o ambiente certo pode gerar resultados impressionantes.

Para um sistema como o MongoDB, onde seu acesso geralmente será de acesso aleatório através de um conjunto de dados, isso desperdiçará a memória que é melhor usada em outro lugar. O sistema, que como mencionado em outra parte também gerencia a memória do MongoDB, irá alocar um pedaço de memória para leitura quando solicitado e, portanto, deixará menos RAM para o MongoDB usar efetivamente.

Escolher o tamanho correto do readahead é complicado e depende do seu hardware, da configuração, do tamanho do bloco, do tamanho da faixa e dos dados em si. Se você se mover para SSDs, por exemplo, você desejará uma configuração baixa, mas o quão baixo dependerá dos dados.

Para explicar: você quer ter certeza de que o readahead é alto o suficiente para puxar um único documento completo e não ter que voltar ao disco. Vamos considerar o seu tamanho mediano de 8k - uma vez que os setores em disco são geralmente de 512 bytes, seriam necessários 16 acessos ao disco para ler em documento inteiro sem leitura antecipada. Se você tivesse uma leitura antecipada de 16 setores ou mais, você leria o documento inteiro com apenas uma viagem para o disco.

Na verdade, como os depósitos do índice MongoDB são 8k, você nunca mais desejará configurar o readahead abaixo de 16, ou serão necessários 2 acessos ao disco para ler em um intervalo do índice. Uma boa prática geral é começar com sua configuração atual, reduzir pela metade e, em seguida, reavaliar sua utilização de RAM e IO e seguir em frente a partir daí.

    
por 16.07.2012 / 17:34
3

Você deve considerar o uso de réplicas para consultas de usuários finais e ter seu fluxo de trabalho concluído em outras máquinas.

Usando sua regra geral de 1:10, você está procurando cerca de 128 GB de RAM para 1 TB de armazenamento em disco; Enquanto alguns SSDs acessíveis hoje afirmam atingir > 60K IOPS, os números do mundo real podem diferir bastante, bem como se você está usando RAID com seus SSDs ou não, e se você estiver, a placa RAID é extremamente importante bem.

No momento deste post, passar de 128GB de memória RAM DDR3 para 256GB parece ser em torno de 2000 $ extra em um servidor Intel de 1U, e isso dará uma razão de 1: 5 com 1TB de dados, o que eu sinto seria uma proporção ainda melhor. Se você precisa que sua carga de trabalho seja concluída o mais rápido possível, mais memória RAM ajudará, mas será que é realmente urgente?

Você precisará fazer também algum ajuste no sistema de arquivos, algo como "noatime, data = writeback, nobarrier" no ext4, e você pode precisar fazer alguns ajustes de configuração do kernel, bem como extrair o máximo de desempenho possível fora do seu sistema.

Se você está indo com o RAID, o RAID-10 será uma boa escolha, e com o controlador RAID adequado, haverá um grande aumento no desempenho, mas com metade do espaço disponível. Você também pode olhar para o RAID50 se quiser um aumento de desempenho decente sem reduzir seu espaço disponível. O risco de executar um RAID é que você não tem mais acesso ao TRIM em suas unidades, o que significa que de vez em quando você precisa mover seus dados, dividir o RAID, TRIM as unidades e recriar o RAID.

Por fim, você precisa decidir quanta complexidade deseja, quanto dinheiro deseja gastar e com que rapidez deseja processar sua carga de trabalho. Eu também avaliaria se o MongoDB é o banco de dados ideal para usar, pois você ainda pode usar o Mongo para consultas de usuários finais que precisam de respostas rápidas, mas usar outra coisa para processar seus dados, que não precisa estar pronta em alguns segundos e também pode permitir que você espalhe sua carga de trabalho em várias máquinas com mais facilidade.

    
por 16.07.2012 / 14:33