Há muitos fatores que estão limitando o desempenho das exportações.
- O tamanho dos dados é relativamente grande em comparação com a memória disponível:~2 TB vs. ~5 GB de cache WiredTiger (se definido como padrão). Ou seja:
- Todo o cache do WiredTiger só pode conter na melhor das hipóteses ~0,22% da coleção, na realidade, é muito provável que seja muito menos do que isso, pois o cache conteria dados de outras coleções e índices.
- Isso significa que o WiredTiger precisa buscar do disco com muita frequência, enquanto remove o conteúdo atual do cache. Se o conjunto de réplicas estiver sendo usado ativamente, isso significaria remover dados "sujos" do cache e mantê-los no disco, o que levaria tempo.
- Observe que os documentos dentro do cache do WiredTiger não são compactados.
- A coleção contém documentos grandes, dos quais você precisa apenas de uma parte. Isso significa que é necessário tempo extra para processar os documentos.
- A coleção é compactada com zlib, o que significa que um tempo extra deve ser usado para descompactar os documentos.
- O readPreference é
secondaryPreferred
, o que significa que ele tentará ler de um secundário. Se o conjunto de réplicas estiver sendo gravado ativamente, as operações de aplicação de oplog no secundário bloquearão os leitores. Isso aumentará ainda mais o atraso.
Uma possível melhoria é que, se esta for uma operação que você faz com frequência, crie um índice nos campos relevantes e exporte-o usando um consulta coberta poderia melhorar o desempenho, pois o índice seria menor do que os documentos completos.
Editar:executando
mongoexport
em paralelo pode ser útil neste caso: Além das informações adicionais fornecidas, executei um teste que parece aliviar um pouco esse problema.
Parece que executar
mongoexport
em paralelo, onde cada mongoexport
manipular um subconjunto da coleção pode acelerar a exportação. Para fazer isso, divida o
_id
namespace correspondente ao número de mongoexport
processo que você planeja executar. Por exemplo, se eu tiver 200.000 documentos, começando com
_id:0
para _id:199,999
e usando 2 mongoexport
processos:mongoexport -q '{"_id":{"$gte":0, "$lt":100000}}' -d test -c test > out1.json &
mongoexport -q '{"_id":{"$gte":100000, "$lt":200000}}' -d test -c test > out2.json &
onde no exemplo acima, os dois
mongoexport
processos estão cada um lidando com metade da coleção. Testando esse fluxo de trabalho com 1 processo, 2 processos, 4 processos e 8 processos, chego aos seguintes horários:
Usando 1 processo:
real 0m32.720s
user 0m33.900s
sys 0m0.540s
2 processos:
real 0m16.528s
user 0m17.068s
sys 0m0.300s
4 processos:
real 0m8.441s
user 0m8.644s
sys 0m0.140s
8 processos:
real 0m5.069s
user 0m4.520s
sys 0m0.364s
Dependendo dos recursos disponíveis, executando 8
mongoexport
processos em paralelo parece acelerar o processo por um fator de ~6. Isso foi testado em uma máquina com 8 núcleos. Observação :a resposta de halfer é semelhante em ideia, embora esta resposta basicamente tente ver se há algum benefício em chamar
mongoexport
em paralelo.