Ruby multi-CPU threading

Olá, como mencionei em posts anteriores, estou fazendo testes de migração do meu Drupal para o Discourse para ter todas as soluções implementadas antes de desativar o site antigo para migrar os dados de produção com seus ~2 milhões de posts. O que aprendi é que em um VPS razoavelmente rápido com 3 núcleos de vCPU, o processo de importação leva uma eternidade, algo em torno de 48 horas. E então, provavelmente terei que fazer mais alguma limpeza com tarefas rake e/ou rails c, e para qualquer coisa que exija um rake posts:rebake levará mais 20 horas aproximadamente.

Eu não entendo realmente os fundamentos da toolchain Ruby. Mas se eu adicionar mais núcleos de CPU ao trabalho, isso reduzirá significativamente o tempo que qualquer um desses processos leva para ser concluído? Por exemplo, um comando bundle ou um comando rake será capaz de dividir seu trabalho entre as CPUs disponíveis, ou os núcleos adicionais são principalmente úteis para executar múltiplos processos simultâneos quando vários usuários estão acessando o site?

1 curtida

Estou fora do tópico, mas quando estava trabalhando em uma migração de fórum com o mesmo número de posts, modifiquei o script de importação para importar apenas 1/100 ou 1/1000 de tópicos e posts.

É uma maneira mais rápida de ver se sua importação é confiável e se ajustes ou depuração são necessários.

3 curtidas

@Canapin Na verdade, muito obrigado por mencionar isso, eu gostaria muito de saber como você fez. Eu queria fazer a mesma coisa, mas desisti da ideia porque assumi que encontraria inconsistências no banco de dados com uma importação parcial. Então, acabei criando um fórum de teste Drupal esquelético para testar. Mas eu preferiria testar uma cópia do banco de dados de produção.

Minha principal preocupação é a eventual migração final de produção; terei que tirar o fórum antigo do ar ou pelo menos torná-lo somente leitura, e isso parece ser pelo menos 48 horas de inatividade no melhor dos casos, a menos que dobrar os núcleos de CPU corte o tempo pela metade?

1 curtida

As tarefas que levam muito tempo para restaurar são, de fato, multithread. Uma ressalva é que 2x as CPUs quase nunca resultam em 2x o desempenho.

Outro ponto é que, geralmente, as tarefas para rake posts:rebake e o trabalho pesado do próprio fórum para recuperar e otimizar o conteúdo podem acontecer com o fórum ativo. Isso pode reduzir o tempo que você precisa ter o fórum offline ou somente leitura e ser capaz de oferecer uma experiência um tanto degradada.

Minha recomendação seria: primeiro, teste. Faça a migração, veja quanto tempo leva e como o fórum fica sem todas as rebakes. Se for tempo suficiente, planeje o fim da migração para o horário de menor tráfego do seu fórum, dessa forma você ganha cerca de 4 a 10 horas de migração sem que muitas pessoas reclamem.

3 curtidas

Excelente, obrigado por confirmar isso, eu estava pensando sobre essa opção também.

Infelizmente, eu não anotei isso e esqueci… Mas se você entende de programação, não deve ser muito difícil.
Talvez eu tenha ajustado os valores de BATCH_SIZE e offset, entre outras coisas, para alterar o loop e fazer com que ele pule lotes de posts ou algo assim…

Não posso tentar novamente agora porque não tenho nenhum fórum para importar no momento, mas farei um tutorial rápido da próxima vez porque acho que é bastante útil.

1 curtida

Quero mencionar duas coisas.

  • Sim, as CPUs importam, então basta obter um VPS maior e executar várias instâncias do sidekiq para refazer e processar imagens, isso será mais rápido.
  • Quando sua importação estiver totalmente concluída, é sempre uma boa ideia fazer um backup/restauração, isso lhe dará um melhor desempenho do banco de dados.

Essas duas juntas: obtenha um VPS grande para a importação e, quando terminar, mova-o para um VPS de produção menor (usando backup e restauração).

Geralmente, uma importação não exigirá que você refaça as postagens depois.

3 curtidas

Muito obrigado Richard pela resposta. Então, qual(is) destes?

  • UNICORN_WORKERS
  • UNICORN_SIDEKIQS
  • DISCOURSE_SIDEKIQ_WORKERS

Interessante, nunca tinha visto essa recomendação antes. Isso reduz a fragmentação ou algo assim?

Sim, inicialmente eu ia tentar corrigir alguns problemas de [QUOTE] e conversão de Textile para Markdown com regexp_replace() no console do Postgres e depois rebakar todas as postagens, porque os comandos rake posts:remap eram muito lentos. Mas então eu descobri que o sabor de regexp que o Postgres usa não é compatível com PCRE, e há muitas anomalias inesperadas para confiar nele. Então, vou tentar executar as postagens através do Pandoc durante o processo de importação, o que me permitirá colocar o site importado no ar em um estado apresentável e, em seguida, corrigir coisas menores como palavras-chave de emoji com rake posts:remap.

  • UNICORN_SIDEKIQS – número de processos (padrão 1)
  • DISCOURSE_SIDEKIQ_WORKERS – número de threads dentro de um processo (padrão 5)

Isso reduz a fragmentação e corrige o fato de que as estatísticas do Postgres podem ser distorcidas por causa da importação.

2 curtidas

:+1:

Eu também nunca tinha visto esse conselho. Se isso é “sempre uma boa ideia”, talvez devesse ser adicionado a Pre-launch checklist after migrating from another platform?

Acho que foi Sam ou Jeff quem me deu esse conselho há muitos anos. Não consigo mais encontrá-lo. Talvez devêssemos verificar se ainda é uma boa ideia e/ou vale a pena o esforço :wink:

1 curtida

Por acaso alguém poderia me dar dicas sobre a maneira mais rápida de reexecutar um script de importação e fazê-lo reimportar os dados? Estou tentando ajustar algumas substituições de texto no script importador e, quando não acerto, tenho que excluir o banco de dados do Discourse e executar ./launcher rebuild import, o que leva um bom tempo. Gostaria de fazer alterações no meu script importador e fazê-lo recomeçar do início novamente (estou usando um pequeno banco de dados de esqueleto de demonstração do meu site no momento, então é muito rápido executar o importador).

Hmmm. Estou testando outra importação dos dados do meu fórum de produção, desta vez em um VPS bastante poderoso com 8 núcleos virtuais e 16 GB de RAM. Defini:
UNICORN_SIDEKIQS=4
DISCOURSE_SIDEKIQ_WORKERS=20
UNICORN_WORKERS=16

Com isso, não parece estar aproveitando todos os núcleos durante a fase de import_topics:

Embora seja interessante que o gráfico de CPU tenha ficado em mais de 600% (ou seja, ~6 de 8 núcleos usados a 100%) durante a fase de user_import.

Também notei esta variável de ambiente: RUBY_GLOBAL_METHOD_CACHE_SIZE=131072 seria muito pequena?

Acho que durante o estado de criação de usuário há mais ações que são tratadas de forma assíncrona pelo Sidekiq.
Grande parte da importação, infelizmente, não se beneficiará da paralelização, você deve otimizar para a velocidade da CPU de núcleo único em vez disso.

Teoricamente, você poderia executar diferentes partes da importação de tópicos em paralelo, mas isso exigiria bastante refatoração do importador e garantir que tudo seja processado em ordem. Não vale a pena para uma tarefa única com algumas iterações.

2 curtidas

Segui uma combinação destes dois guias [1] [2] para importar com acesso a outro contêiner Docker executando uma cópia do banco de dados do fórum de origem em MySQL. Mas me ocorreu que, em vez de criar um contêiner import separado, posso simplesmente usar um único contêiner app e adicionar o mysql-dep.tempate a ele:

templates:
  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/web.template.yml"
  - "templates/web.ratelimited.template.yml"
  - "templates/web.ssl.template.yml"
  - "templates/web.letsencrypt.ssl.template.yml"
  - "templates/import/mysql-dep.template.yml"

Isso me permite ter uma instância Discourse funcionando enquanto o script de importação está em execução. Existe alguma desvantagem em abrir o fórum ao público assim que todos os usuários e categorias forem importados, e apenas informar aos usuários com um banner que levará alguns dias até que esteja totalmente preenchido? Estou pensando que, no mínimo, eu poderia abri-lo após a importação de todos os tópicos e postagens, mas antes da importação das mensagens privadas, já que a importação das mensagens privadas por si só levará cerca de 24 horas.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.