Pesquisa de site

Como dimensionar seu servidor Mastodon


Os autores selecionaram a The Apache Software Foundation e o Free and Open Source Fund para receber doações como parte do programa Write for DOnations.

Introdução

Mastodon é uma rede social auto-hospedada de código aberto. O Mastodon é federado, o que significa que múltiplas instâncias do Mastodon podem interoperar, permitindo que usuários de diferentes servidores se comuniquem entre si para criar uma rede chamada fediverse. O fediverse é uma rede de servidores interligados, que se comunicam entre si por meio do protocolo ActivityPub.

À medida que a comunidade Mastodon cresce exponencialmente, também aumenta a carga nos servidores. No ano passado, vários incidentes de queda de servidores Mastodon ocorreram devido ao pico de atividade do usuário. Para evitar que o servidor Mastodon fique inativo durante o fluxo de usuários, ele precisa ser dimensionado.

Para entender como escalar um Mastodonte, você precisa entender do que é feito o Mastodonte. Um servidor Mastodon consiste em cinco componentes principais: serviço Web, serviço StreamingAPI, serviço Sidekiq, Redis e PostgreSQL.

Opcionalmente, o armazenamento de objetos pode melhorar drasticamente o desempenho de arquivos de mídia estáticos e diminuir a carga no serviço Web. Embora não aumente o desempenho, o ElasticSearch também pode permitir a pesquisa de texto completo e o LibreTranslate pode permitir que seu servidor traduza mensagens automaticamente, tornando seu servidor um pouco mais agradável.

Observação: os serviços Mastodon se comunicam apenas por meio de armazenamento de dados (Redis e PostgreSQL). Isso proporciona grande flexibilidade para configurações distribuídas, mas a simples distribuição de componentes em várias máquinas sem uma configuração adequada não proporcionará o aumento de desempenho desejado.

Neste tutorial, você aprenderá sobre diferentes técnicas de escalonamento para seu servidor Mastodon:

  • Aumentando os recursos do banco de dados e as conexões disponíveis
  • Dividindo filas do Sidekiq em vários processos
  • Configurando threads e recursos para cada fila do Sidekiq
  • Adicionando armazenamento de objetos para descarregar serviço da Web
  • Aumentando threads e processos de serviço da Web

Se você está planejando dimensionar seu servidor Mastodon para atender à capacidade de alguns usuários ativos, recomendamos ler todo o artigo e dimensionar cada componente. Por outro lado, se você pretende dimensionar um componente específico, sinta-se à vontade para pular para a seção do componente correspondente. A regra geral é manter sua carga média em cerca de 60-70% em cada máquina executando componentes do Mastodon. Às vezes, uma configuração de serviço inadequada pode resultar em baixo desempenho e também em uma carga média baixa. Cada seção abaixo contém sintomas para detectar tais casos.

Nota: Este artigo contém exemplos destinados a servidores Mastodon executados em serviços systemd (como Mastodon Droplet 1-Click). Se você tiver outro tipo de configuração do Mastodon (Docker, K8s, etc.), considere usar os métodos de configuração correspondentes.

Melhorando o desempenho do banco de dados

PostgreSQL é a principal fonte de verdade para o seu servidor Mastodon. Ele contém credenciais de todos os usuários, toots, boosts, relações de usuário e assim por diante. É da mais alta prioridade manter o banco de dados protegido e com backup.

O Mastodon usa uma quantidade imensa de conexões com o banco de dados. Os sintomas de falta de conexão incluem baixo desempenho do Sidekiq, horas de latência nas atualizações de feed, lentidão geral e até mesmo todo o servidor ficando inacessível.

Nesta seção, você calculará o número de conexões necessárias para seu servidor e configurará o banco de dados de acordo. Sem recursos extras, ele salvará seu servidor da falta de conexão, o que afeta o desempenho de todos os serviços Mastodon.

Informação: O número de conexões necessárias para o seu servidor Mastodon NUNCA deve exceder a variável max_connections do seu PostgreSQL. Além disso, max_connections deve ser o mais baixo possível para evitar contenção do banco de dados.

Para calcular o número total de conexões necessárias para o seu servidor Mastodon, você precisa calcular o número de conexões exigidas por cada componente:

  • Para cada instância de serviço da Web, as conexões necessárias são MAX_THREADS multiplicadas por WEB_CONCURRENCY.
  • Para cada instância de StreamingAPI, as conexões necessárias são STREAMING_CLUSTER_NUM multiplicadas por DB_POOL.
  • Para cada instância do Sidekiq, as conexões necessárias são iguais a DB_POOL.

Informação: Todas as variáveis acima podem ser encontradas nos ambientes do componente correspondente. Mais adiante neste artigo, você trabalhará com todas as variáveis listadas aqui.

Some todos esses números e adicione 20 conexões extras para manutenção. Este é o seu valor para max_connections.

Informações: configurar corretamente o banco de dados é sua principal prioridade no dimensionamento do Mastodon, mas para determinar o número max_connections, você precisa saber primeiro como dimensionará outros serviços. Depois de criar um plano sobre como escalar outros serviços (que você encontrará nas próximas seções), você pode retornar aqui para terminar de calcular max_connections.

Agora que você sabe que existe um valor para max_connections, você o usará para configurar seu banco de dados.

Uma boa forma de gerar configuração é utilizar um serviço chamado PGTune. Ao abrir a página do PGTune você será saudado com campos de configuração que deverá preencher:

  • Versão do banco de dados: Especifique aqui a versão do PostgreSQL que seu servidor Mastodon utiliza. Você pode encontrá-lo usando este comando na máquina que executa o PostgreSQL:
pg_config --version

  • Tipo de SO: Sistema operacional da máquina que executa o PostgreSQL.
  • Tipo de banco de dados: tipo de carga de trabalho que seu PostgreSQL executará. No caso do Mastodon, escolha Sistema de Processamento de Transações Online (OLTP no futuro), pois o Mastodon cria toneladas de conexões.
  • Memória total (RAM): quantidade de memória que o PostgreSQL usará. Tente alocar até metade da memória física de uma máquina, mas se outros serviços estiverem rodando na mesma máquina – certifique-se de não exceder o total de RAM. Por exemplo, em uma máquina com 8 GB de RAM e apenas PostgreSQL, especificamos 4 GB no PGTune.
  • Número de CPUs: Quantidade de núcleos de CPU que o PostgreSQL utilizará. Como o OLTP está vinculado à CPU, é altamente recomendável definir esse número tão alto quanto o número de threads de CPU que sua máquina suporta.
  • Número de conexões: max_connections vai aqui.
  • Armazenamento de dados: Tipo de dispositivo de armazenamento de dados na máquina que executa o PostgreSQL.

Por exemplo, esta é a aparência da configuração em uma máquina com 8 GB de RAM, 8 threads e 420 max_connections:

Após clicar em Gerar você receberá parâmetros de configuração que deverão ser adicionados ao seu arquivo postgresl.conf.

Na máquina que executa o PostgreSQL, abra postgresql.conf:

sudo nano /etc/postgresql/major version of your PostgreSQL/main/postgresql.conf

Por exemplo, se você estiver executando o PostgreSQL versão 15.x, a localização deste arquivo seria /etc/postgresql/15/main/postgresql.conf.

A seguir, para cada parâmetro gerado pelo PGTune, você irá procurar pelo mesmo parâmetro em seu postgresql.conf e alterar seu valor. Use Ctrl+W para pesquisar em nano e Esc+/ em vi/vim. Se algum parâmetro não existir em seu postgresql.conf você pode criá-lo em qualquer lugar do arquivo.

Por fim, reinicie o serviço PostgreSQL para aplicar as alterações:

sudo service postgressql restart

Agora você sabe como configurar seu PostgreSQL para melhor desempenho do Mastodon e como aplicar a nova configuração. Na próxima seção, você encontrará valores exatos para todas as variáveis necessárias para calcular max_connections.

Aperfeiçoando filas do Sidekiq

Sidekiq é um agendador e trabalhador de tarefas Ruby. Ele é responsável por executar trabalhos em segundo plano, como propagar postagens entre servidores, gerar visualizações de links, processar curtidas e assim por diante.

Sidekiq usa Redis como gerenciador de filas para trabalhos e PostgreSQL para salvar resultados de trabalhos. Se vários servidores estiverem conectados (os usuários seguem pessoas de outros servidores), muitos trabalhos serão criados para propagar os dados necessários de um servidor para outro.

Os sintomas de gargalo do Sidekiq incluem longa latência nas atualizações de feed, filas do Sidekiq entupidas e carga persistente do banco de dados.

Nesta seção, você aproximará o tamanho das filas do Sidekiq necessárias para o seu servidor, bem como o número de máquinas físicas necessárias para executá-las.

Mastodon tem várias filas para Sidekiq. No entanto, alguns deles consomem mais recursos e carregam totalmente a CPU, enquanto outros mal infligem qualquer porcentagem da carga. A tabela abaixo contém a descrição de todas as filas necessárias para o Mastodon, bem como sua prioridade de recursos. As filas de alta prioridade utilizarão mais CPU em comparação com as de baixa prioridade:

 

default

Prioridade: mais alta

Função: Lida com todas as tarefas que afetam os usuários locais.

 

ingress

Prioridade: Alta

Função: Lida com atividades remotas recebidas. Prioridade mais baixa do que a fila padrão para que os usuários locais ainda vejam suas postagens quando o servidor estiver sobrecarregado. Lembre-se de que a fila de ingress consome muita CPU.

 

push

Prioridade: Médio

Função: Entrega cargas úteis para outros servidores.

 

pull

Prioridade: Médio

Função: Lida com tarefas como manipulação de importações, backups, resolução de threads, exclusão de usuários e encaminhamento de respostas.

 

mailers

Prioridade: baixa

Função: Entrega e-mails.

 

scheduler

Prioridade: mais baixa

Função: gerencia tarefas agendadas, como atualização de hashtags de tendências e limpeza de registros.

Aviso: a fila do agendador nunca deve ser escalonada em vários processos. Apenas 1 processo executando o scheduler deve existir para o seu servidor Mastodon.

A tabela acima irá ajudá-lo a alocar máquinas adequadamente, mas e quanto à configuração das próprias filas? As filas são limitadas em quantos usuários ativos elas podem atender efetivamente e esse limite está correlacionado ao número de threads que uma determinada fila possui. Quanto mais threads são alocados, mais usuários ativos determinadas filas podem manipular. O tipo de fila também afeta esse limite, algumas filas requerem menos threads para atender a mesma quantidade de usuários em comparação com outras filas. Essa relação multidimensional é descrita no gráfico abaixo.

O eixo X indica o número esperado de usuários ativos que o Mastodon atenderá, enquanto o eixo Y indica o número estimado de threads necessários para cada fila atender a quantidade correspondente de usuários ativos:

Dependendo da sua comunidade de servidores, as filas push ou pull podem ter prioridades diferentes. Se sua comunidade estiver altamente interligada com outras federações, dê prioridade à fila push. Caso contrário, se o seu servidor for específico para algum interesse, você pode esperar muita atividade local e dar prioridade ao pull.

Observação: servidores diferentes têm padrões de uso e distribuição de carga diferentes. Tente prever o padrão de uso do seu servidor analisando a probabilidade de os usuários do seu servidor aumentarem ou gostarem de usuários de outros servidores.

Por exemplo, se o seu servidor cobrir um tópico científico específico, os usuários do seu servidor se comunicarão principalmente entre si. Por outro lado, se o seu servidor for um blog político pessoal, os usuários do seu servidor terão maior probabilidade de impulsionar outros políticos. Como administrador do Mastodon, você precisará monitorar a carga de seus próprios servidores e dimensionar os componentes de acordo.

A última observação importante sobre as filas do Sidekiq é o fato de que cerca de 10 a 15 threads do Sidekiq requerem 1 GB de RAM. Isso conclui uma relação:

Aviso: O serviço Sidekiq único NÃO DEVE usar mais de 50 threads. Para atender 60 threads - execute 2 serviços com 30 threads cada.

Por exemplo, estimamos 15.000 usuários ativos que usarão principalmente apenas a federação local. De acordo com o gráfico acima precisamos:

  • padrão: cerca de 70 threads no total, 2 serviços com 35 threads cada.
  • ingress: cerca de 50 threads no total, 2 serviços com 25 threads cada.
  • pull: cerca de 40 threads no total, 1 serviço com todos os 40 threads.
  • push: cerca de 30 threads no total, 1 serviço com todos os 35 threads.
  • mailer: cerca de 20 threads no total, 1 serviço com todos os 20 threads.
  • agendador: 5 threads no total, 1 serviço com todos os 5 threads.

Lembre-se de que nossos usuários não usam muito federações externas, então demos prioridade à fila pull em vez de push.

Como a fila scheduler é a fila de prioridade mais baixa, podemos executá-la junto com a fila default, isso não afetará a fila default em todos. Juntos, eles requerem 70 + 5=75 threads que correspondem a aproximadamente 8 GB de RAM. Como é apenas uma fila pesada, podemos usar uma única máquina de 4 núcleos e 8 GB. ingress e mailer são filas de alta e baixa prioridade, o que significa que exigirão menos recursos de CPU em comparação com uma única fila default, mas ainda assim use uma máquina de 4 núcleos. A quantidade total de threads para eles é 25 + 20=45, o que equivale a aproximadamente 6 GB de RAM. As filas pull e push são prioridades médias, tornando-as um pouco mais intensas em termos de CPU em comparação com ingress e mailer, então usaremos 4 núcleos novamente. A quantidade de threads é 40 + 30=70 o que corresponde a 8GB de RAM.

Resumindo, se pretendemos atender 15.000 usuários ativos, para configuração do Sidekiq precisaremos no total de 3 máquinas:

  • Uma máquina 4c/8GB para atender 2 serviços da fila default com 35 threads cada e 1 serviço da fila scheduler com 5 threads.
  • Uma máquina 4c/8GB para atender 1 serviço de fila ingress com 50 threads e 1 serviço de fila mailer com 20 threads.
  • Uma máquina 4c/6GB para atender 1 serviço de fila pull com 40 threads e 1 serviço de fila push com 30 threads.

Observação: A melhor maneira de determinar o número de núcleos necessários é observar a carga média nas máquinas que executam o Sidekiq. Mais núcleos de CPU serão necessários se a carga média for superior a 80%. Se a quantidade de núcleos já for alta o suficiente (mais de 8 núcleos por exemplo) você pode tentar criar outra máquina com a mesma configuração, sem a necessidade de qualquer tipo de balanceamento de carga isso distribuirá a carga e lhe dará outra dimensão para escala. Não se esqueça de não executar a fila scheduler mais de uma vez.

Dimensionando o Sidekiq

Para utilizar totalmente os recursos de hardware, o Sidekiq precisa ser configurado com a quantidade adequada de threads e dimensionado no nível do processo. Nesta seção, você descobrirá como definir exatamente o número de threads para filas do Sidekiq e também como executar várias filas na mesma máquina usando modelos de serviço.

Observação: os exemplos abaixo podem ser incorporados nos campos ExecStart do serviço systemd ou command do Docker. Caso você esteja usando o Docker, lembre-se de reconstruir seus contêineres após fazer alterações nos arquivos do Docker.

Aumentando o número de threads usados por um único processo Sidekiq

Um serviço é um recurso que o systemd pode gerenciar, registrar, reiniciar automaticamente e assim por diante. Agrupar um executável no serviço é uma das maneiras mais fáceis de implantar um aplicativo. O serviço Systemd é a maneira mais comum de executar filas do Sidekiq. A localização do serviço Sidekiq depende do tipo de instalação do Mastodon. Por exemplo, se você estiver usando o Mastodon Droplet 1-Click, poderá encontrar o arquivo do serviço Sidekiq neste local:

cat /etc/systemd/system/mastodon-sidekiq.service

Vamos dar uma olhada rápida na parte superior do arquivo de serviço:

[Unit]
Description=mastodon-sidekiq
After=network.target

[Service]
Type=simple
User=mastodon
WorkingDirectory=/home/mastodon/live
Environment="RAILS_ENV=production"
Environment="DB_POOL=25"
Environment="MALLOC_ARENA_MAX=2"
Environment="LD_PRELOAD=libjemalloc.so"
ExecStart=/home/mastodon/.rbenv/shims/bundle exec sidekiq -c 25
...

[Install]
WantedBy=multi-user.target

Nossa atenção deve recair sobre dois campos específicos: ExecStart e Environment. ExecStart define o ponto inicial do serviço que é executado quando o serviço é iniciado ou reiniciado. Environment define variáveis de ambiente que são passadas para ExecStart.

Para dimensionar um único processo do Sidekiq, você deve aumentar o número de threads que o Sidekiq usará. Este número é controlado pelo parâmetro -c no campo ExecStart. Não se esqueça de manter a variável de ambiente DB_POOL sincronizada com o parâmetro -c. Como exemplo, vamos aumentar o número de threads para 45. Você alterará os valores dos parâmetros -c e também do DB_POOL:

[Unit]
Description=mastodon-sidekiq
After=network.target

[Service]
Type=simple
User=mastodon
WorkingDirectory=/home/mastodon/live
Environment="RAILS_ENV=production"
Environment="DB_POOL=40"
Environment="MALLOC_ARENA_MAX=2"
Environment="LD_PRELOAD=libjemalloc.so"
ExecStart=/home/mastodon/.rbenv/shims/bundle exec sidekiq -c 40
...

[Install]
WantedBy=multi-user.target

Informação: O ambiente DB_POOL deve sempre ter os mesmos valores do parâmetro -c (40 no exemplo acima). Menor irá introduzir problemas de desempenho do Sidekiq e maior irá introduzir uma carga extra no banco de dados.

Depois de fazer qualquer alteração no arquivo de serviço, recarregue os arquivos da unidade e reinicie o serviço Sidekiq:

sudo systemctl daemon-reload
sudo systemctl restart mastodon-sidekiq.service

Ao aplicar as alterações desta seção, você aumentou a quantidade de threads que o Sidekiq usa, tornando-o capaz de atender mais usuários.

Especificando uma fila específica para uma única instância do Sidekiq

Vamos começar analisando o arquivo de serviço Sidekiq padrão. Se você estiver usando o Mastodon Droplet 1-Click, poderá encontrar o arquivo de serviço Sidekiq neste local:

cat /etc/systemd/system/mastodon-sidekiq.service

Como você sabe, o Mastodon divide os dados do Sidekiq em várias filas. Por padrão, não há fila especificada explicitamente no arquivo de serviço.

[Unit]
Description=mastodon-sidekiq
After=network.target

[Service]
Type=simple
User=mastodon
WorkingDirectory=/home/mastodon/live
Environment="RAILS_ENV=production"
Environment="DB_POOL=25"
Environment="MALLOC_ARENA_MAX=2"
Environment="LD_PRELOAD=libjemalloc.so"
ExecStart=/home/mastodon/.rbenv/shims/bundle exec sidekiq -c 25
...

[Install]
WantedBy=multi-user.target

Nenhuma fila explícita implica que o Sidekiq atenderá todas as filas com algumas prioridades padrão. Como até mesmo uma única fila do Sidekiq consome muitos recursos, executar todas as filas em uma única instância do Sidekiq não é o ideal. O que você deseja alcançar é dividir as filas do Sidekiq em várias instâncias do Sidekiq. Isso permitirá que você especifique o número exato de threads para cada fila e também permitirá que você execute filas diferentes em várias máquinas. Esperançosamente, substituir o comportamento padrão do Sidekiq requer apenas a adição de um parâmetro -q ao campo ExecStart.

Por exemplo, vamos fazer o Sidekiq servir apenas a fila ingress:

[Unit]
Description=mastodon-sidekiq
After=network.target

[Service]
Type=simple
User=mastodon
WorkingDirectory=/home/mastodon/live
Environment="RAILS_ENV=production"
Environment="DB_POOL=25"
Environment="MALLOC_ARENA_MAX=2"
Environment="LD_PRELOAD=libjemalloc.so"
ExecStart=/home/mastodon/.rbenv/shims/bundle exec sidekiq -c 25 -q ingress
...

[Install]
WantedBy=multi-user.target

Ao especificar -q ingress você diz ao Sidekiq para servir apenas a fila ingress e nada mais.

Aviso: O exemplo acima fará com que todas as filas, exceto ingress, não sejam processadas, o que significa que o Mastodon não funcionará corretamente. Certifique-se de cobrir todas as filas pelo menos uma vez. A próxima seção contém orientações sobre como executar várias instâncias do serviço Sidekiq em uma única máquina.

Fazer com que o serviço Sidekiq processe apenas uma única fila tem várias vantagens: é mais fácil processar logs para uma fila específica, oferece gerenciamento por fila e controle de thread e permite configuração distribuída executando filas diferentes em máquinas diferentes. No geral, é considerada a principal prática no dimensionamento de filas do Sidekiq. Porém, nem sempre é eficiente atribuir todos os recursos de hardware a uma única fila, por isso na próxima seção você aprenderá como executar múltiplas filas separadamente, mas em uma única máquina

Usando modelos para executar várias instâncias do Sidekiq em uma única máquina

Executar apenas uma única instância do Sidekiq é menos eficiente. Para dimensionar ainda mais o Sidekiq, você pode executar várias instâncias do Sidekiq simultaneamente. Como o serviço systemd é a forma mais comum de executar o Sidekiq, você aprenderá como criar um modelo de serviço para simplificar a execução de várias instâncias do Sidekiq em uma única máquina.

O modelo de serviço nos permite criar vários serviços a partir de um único arquivo de serviço.

Primeiro, vamos criar uma cópia do nosso arquivo de serviço Sidekiq existente:

cp /etc/systemd/system/mastodon-sidekiq.service /etc/systemd/system/mastodon-sidekiq-template.service

Isso criará um novo arquivo chamado mastodon-sidekiq-template.service que é uma cópia do serviço Sidekiq existente. Você modificará esta cópia para convertê-la em um modelo. Um modelo é definido por especificadores de modelo. Neste artigo você usará dois especificadores específicos: %i e %j.

  • %i é o nome da instância. Para serviços instanciados, esta é a string entre o primeiro caractere “@” e o sufixo de tipo.
  • %j é o componente final do prefixo. Esta é a string entre o último “-” e o final do nome do prefixo.

Parece confuso? Vamos pular para a parte prática para entender melhor.

Primeiramente, abra seu novo arquivo de serviço para editá-lo:

sudo nano /etc/systemd/system/mastodon-sidekiq-template.service

Agora, altere alguns valores no arquivo de serviço para especificadores de modelo:

  • O campo de descrição deve conter o especificador %j para facilitar o rastreamento e manutenção do serviço.
  • A variável de ambiente DB_POOL deve ser igual ao especificador %i.
  • O parâmetro -c no ExecStart deve ser igual a %i
  • O parâmetro -q no ExecStart deve ser igual a %j
[Unit]
Description=mastodon-sidekiq-%j-queue
After=network.target

[Service]
...
Environment="DB_POOL=%i"
Environment="MALLOC_ARENA_MAX=2"
Environment="LD_PRELOAD=libjemalloc.so"
ExecStart=/home/mastodon/.rbenv/shims/bundle exec sidekiq -c %i -q %j
...
[Install]
WantedBy=multi-user.target

Como você pode imaginar, o especificador %i conterá o número de threads do Sidekiq e o especificador %j conterá o nome da fila do Sidekiq.

Então, como você pode definir essas variáveis? Os especificadores são substituídos por seções específicas do arquivo de serviço.

Vamos usar este modelo para criar arquivos de serviço para as configurações desejadas do Sidekiq.

Primeiro, copie o modelo para especificar as filas que deseja executar nesta máquina. Por exemplo, para executar filas default e scheduler:

cp /etc/systemd/system/mastodon-sidekiq-template.service /etc/systemd/system/mastodon-sidekiq-default@.service
cp /etc/systemd/system/mastodon-sidekiq-template.service /etc/systemd/system/mastodon-sidekiq-scheduler@.service

Para o nome da fila, você pode usar default, ingress, push, pull, mailers, agendador.

Você deve ter notado que não especificou nada após o símbolo @. Isso porque você especificará esse parâmetro ao habilitar o serviço em si. Agora, para habilitar novos serviços, vamos usar 20 threads para a fila padrão e 5 para a fila do agendador:

sudo systemctl enable mastodon-sidekiq-default@20.service
sudo systemctl enable mastodon-sidekiq-scheduler@5.service

Finalmente, depois de habilitar seus novos serviços, você pode executar todos eles de uma vez usando o seguinte comando:

sudo systemctl start mastodon-sidekiq*

Neste ponto, você criou com sucesso um arquivo de serviço de modelo e o usou para executar vários serviços do Sidekiq com diferentes filas e threads.

Alterando a configuração de serviços de modelo em execução

Se você deseja, por exemplo, alterar o número de threads de 20 para 40 para seu serviço default modelado, você deve primeiro desabilitar o serviço existente :

sudo systemctl stop    mastodon-sidekiq-default.service
sudo systemctl disable mastodon-sidekiq-default@20.service

Observe como você especifica apenas o número de threads para o comando disable e não stop.

Depois de desabilitar o antigo serviço push, você pode criar um novo serviço com 40 threads em vez de 20:

sudo systemctl enable mastodon-sidekiq-default@40.service
sudo systemctl start  mastodon-sidekiq-default.service

Neste ponto, você alterou com sucesso o número de threads do seu serviço systemd existente.

Executando vários serviços da mesma fila do Sidekiq

Como você sabe, uma única instância do Sidekiq não deve ter mais de 50 threads. A execução de 60 threads de alguma fila requer dividi-la em 2 serviços de 30 threads cada.

Para conseguir isso, você precisa copiar o modelo várias vezes com a mesma fila, mas com a adição de um índice. Um índice é simplesmente um número que distinguirá cada arquivo de serviço. Copie o modelo inicial várias vezes, mas aumente o índice sempre que a mesma fila se repetir. Por exemplo, para criar 2 arquivos de serviço da fila default:

cp /etc/systemd/system/mastodon-sidekiq-template.service /etc/systemd/system/mastodon-sidekiq-1-default@.service
cp /etc/systemd/system/mastodon-sidekiq-template.service /etc/systemd/system/mastodon-sidekiq-2-default@.service

Aviso: NÃO anexe índice após o nome de uma fila como este: /etc/systemd/system/mastodon-sidekiq-default-2@service. Isso fará com que o modelo trate 2 como o nome da fila, o que inevitavelmente fará com que ela falhe. Insira o índice apenas ANTES do nome de uma fila.

Agora, vamos habilitá-los com 40 threads para a primeira instância da fila default e 60 threads para a segunda instância:

sudo systemctl enable mastodon-sidekiq-1-default@40.service
sudo systemctl enable mastodon-sidekiq-2-default@60.service

Finalmente, depois de habilitar seus serviços, você pode executá-los todos usando o seguinte comando:

sudo systemctl start mastodon-sidekiq*

Neste ponto, você criou com êxito várias instâncias da mesma fila, permitindo dividir adequadamente grandes quantidades de threads.

Você aprendeu várias abordagens para configurar os serviços Sidekiq. Em algumas situações, um único serviço padrão é suficiente, outras exigirão vários serviços em uma única máquina e algumas até exigirão vários serviços da mesma fila em várias máquinas. Tudo depende do número de usuários ativos que você deseja oferecer suporte.

Adicionando armazenamento de objetos

O armazenamento de objetos, ou simplesmente bucket, permite armazenar arquivos de mídia carregados pelos usuários do seu servidor. Isso inclui fotos, vídeos, gifs, arquivos de áudio e assim por diante.

Passar do sistema de arquivos para o armazenamento de objetos ajuda a aumentar a velocidade e a capacidade de armazenamento, mas, mais importante, reduz a carga dos serviços Mastodon. Além disso, a maioria dos armazenamentos de objetos fornecidos em nuvem também fornece CDN, que entregará arquivos de mídia aos usuários com muito mais rapidez.

Observação: Mastodon usa interface compatível com S3, o que significa que seu provedor de armazenamento de objetos deve oferecer suporte à interface S3 e fornecer mapeamento para credenciais de armazenamento S3.

Se você acidentalmente perdeu a configuração do armazenamento de objetos durante a inicialização do Mastodon, poderá adicionar variáveis necessárias diretamente à configuração das máquinas que executam o serviço Web, uma vez que o armazenamento de objetos é usado apenas pelo serviço Web.

Aviso: Ao alterar o armazenamento de objetos, você perderá todos os arquivos de mídia existentes em seu servidor.

Na(s) máquina(s) executando o serviço Web, abra .env.production em seu editor de texto preferido, se você estiver usando o Mastodon Droplet 1-Click env.production está localizado em /home/mastodon/live:

sudo nano .env.production

Adicione as seguintes linhas em qualquer lugar ao(s) seu(s) arquivo(s) .env.production, substituindo o texto destacado por suas próprias informações. Se essas variáveis já existirem - significa que o armazenamento de objetos foi configurado durante a configuração, você ainda poderá alterá-las se os valores estiverem incorretos:

...
S3_ENABLED=true
S3_PROTOCOL=https
S3_BUCKET=your bucket name
S3_REGION=your bucket region
S3_HOSTNAME=your bucket hostname
S3_ENDPOINT=your bucket endpoint
AWS_ACCESS_KEY_ID=your bucket secret ID
AWS_SECRET_ACCESS_KEY=your bucket secret key
...

As variáveis acima representam parâmetros de conexão da interface S3. Certifique-se de usar o mapeamento S3 correto para parâmetros de conexão do seu provedor de armazenamento de objetos.

Em seguida, salve e saia do editor.

Certifique-se de reiniciar o(s) serviço(s) da Web após salvar as alterações:

sudo systemctl restart mastodon-web.service

Agora você sabe como configurar manualmente o armazenamento de objetos do Mastodon em caso de falha na configuração automática, erro humano ou instalação manual. O armazenamento de objetos ajudará a reduzir a carga em seus serviços Web Mastodon e fornecerá melhores velocidades de upload/download para arquivos de mídia em seu servidor.

Dimensionando o serviço da Web

O serviço da web é um servidor HTTPS Ruby-on-Rails que atende a UI do Mastodon e processa solicitações de usuários. A carga do serviço web é diretamente proporcional ao número de usuários ativos. Cada thread pode responder a uma única solicitação ao mesmo tempo. Se todos os threads estiverem ocupados, a próxima solicitação deverá aguardar. Se a solicitação estiver aguardando por muito tempo, ela será cancelada com um erro de tempo limite. Os gargalos do serviço Web podem ser identificados pelos longos tempos de processamento de solicitações: a página abre lentamente, as postagens estão sendo criadas com um atraso perceptível ou erros de tempo limite aparecem nos logs.

Aviso: o serviço Web aplica apenas HTTPS, o que significa que a terminação SSL não pode ser usada no balanceador de carga entre várias máquinas que hospedam os serviços Web.

Para permitir que o serviço Web processe mais usuários, é necessário aumentar a quantidade total de threads usados pelo serviço. Isso pode ser feito aumentando as variáveis de ambiente para WEB_CONCURRENCY (o número de trabalhadores) e/ou MAX_THREADS (threads por trabalhador). Cada trabalhador tem uma quantidade de MAX_THREADS de threads, então a quantidade total de threads é WEB_CONCURRENCY multiplicada por MAX_THREADS.

Aumentar MAX_THREADS tende a consumir mais CPU, enquanto aumentar WEB_CONCURRENCY tende a consumir mais RAM. A estimativa média para o Mastodon versão 4.0.2 é de 2 a 3 GB de RAM para um único trabalhador. No exemplo acima com WEB_CONCURRENCY=3 a quantidade estimada de RAM necessária é de 9 GB. Para MAX_THREADS recomendamos começar com algum valor genérico como 15 e aumentá-lo até que 70% da CPU seja usada em média. Isso significa que você precisa observar as máquinas que executam seus serviços da Web para entender se é possível extrair mais threads.

Observação: Abaixo estão os trechos demonstrados para a configuração do serviço Web do systemd. Se você estiver usando outra tecnologia para executar seu serviço Web (Docker, K8s, etc.), ajuste as variáveis WEB_CONCURRENCY e MAX_THREADS de acordo com as especificações do seu ambiente de tecnologia.

Primeiro, vamos abrir o arquivo do serviço web:

sudo nano /etc/systemd/system/mastodon-web.service

O que você verá é um arquivo systemd de serviço da Web semelhante a este:

[Unit]
Description=mastodon-web
After=network.target

[Service]
...
Environment="LD_PRELOAD=libjemalloc.so"
ExecStart=/home/mastodon/.rbenv/shims/bundle exec puma -C config/puma.rb
ExecReload=/bin/kill -SIGUSR1 $MAINPID
...
[Install]
WantedBy=multi-user.target

Agora, anexe dois campos extras com as variáveis WEB_CONCURRENCY e MAX_THREADS logo acima do campo ExecStart:

[Unit]
Description=mastodon-web
After=network.target

[Service]
...
Environment="LD_PRELOAD=libjemalloc.so"
Environment="WEB_CONCURRENCY=your concurrency value"
Environment="MAX_THREADS=your threads value"
ExecStart=/home/mastodon/.rbenv/shims/bundle exec puma -C config/puma.rb
ExecReload=/bin/kill -SIGUSR1 $MAINPID
...
[Install]
WantedBy=multi-user.target

Esses novos campos substituirão os valores padrão de WEB_CONCURRENCY e MAX_THREADS pelos seus próprios valores.

Salve e saia do editor.

Certifique-se de recarregar os arquivos da unidade e reiniciar o serviço após salvar as alterações:

sudo systemctl daemon-reload
sudo systemctl restart mastodon-web.service

Observação: desde 2017, o desempenho do serviço Web quase dobrou. Recomendamos fortemente que todos monitorem o uso do hardware para determinar se mais ou menos recursos devem ser alocados.

Neste ponto, você aumentou os valores padrão para configuração do serviço Web. Isso fez com que o frontend do Mastodon suportasse usuários mais ativos. Lembre-se de sempre ter uma margem extra de desempenho para garantir que seu servidor Mastodon não seja limitado por um grande fluxo de usuários.

Aumentando a taxa de transferência da StreamingAPI

StreamingAPI é um servidor NodeJS que hospeda API para atualizações em tempo real. Ele permite que os usuários recebam um fluxo de eventos diretamente do servidor. StreamingAPI é limitado pelo número de usuários que pode atender simultaneamente. O limite está vinculado à variável de ambiente STREAMING_CLUSTER_NUM.

O gargalo do StreamingAPI pode ser identificado observando os logs de serviço. Se algo como node[1201554]: ERR! erro: desculpe, muitos clientes já aparecem nos logs, isso significa que o número de usuários que usam StreamingAPI é maior do que ele pode suportar e novos usuários são desconectados automaticamente.

Dimensionar o StreamingAPI é bastante simples. Aumentar a variável de ambiente STREAMING_CLUSTER_NUM permitirá que o StreamingAPI atenda a mais usuários. Se você vir muitas mensagens de erro: desculpe, muitos clientes já em seus registros, aumente STREAMING_CLUSTER_NUM de 1,5x a 2x vezes. Por exemplo, se sua configuração atual para STREAMING_CLUSTER_NUM for 2, atualize a variável para 4

Na máquina que executa StreamingAPI, abra o arquivo de serviço StreamingAPI:

sudo nano /etc/systemd/system/mastodon-streaming.service

Edite o valor da variável STREAMING_CLUSTER_NUM:

[Unit]
Description=mastodon-streaming
After=network.target

[Service]
...
Environment="STREAMING_CLUSTER_NUM=your new value"
ExecStart=/usr/bin/node ./streaming
...

Salve o arquivo e certifique-se de recarregar os arquivos da unidade e reiniciar o serviço após salvar as alterações:

sudo systemctl daemon-reload
sudo systemctl restart mastodon-streaming.service

Além disso, por padrão, StreamingAPI não possui uma variável DB_POOL definida. Sem esta variável definida explicitamente, StreamingAPI usará 10 conexões. Aumentar explicitamente a variável DB_POOL sem aumentar a variável STREAMING_CLUSTER_NUM, mas caso queira fazer isso você pode simplesmente criar uma nova variável de ambiente em um arquivo de serviço StreamingAPI.

Na máquina que executa StreamingAPI, abra o arquivo de serviço StreamingAPI:

sudo nano /etc/systemd/system/mastodon-streaming.service

Adicione nova variável de ambiente DB_POOL:

[Unit]
Description=mastodon-streaming
After=network.target

[Service]
...
Environment="DB_POOL=your value"
Environment="STREAMING_CLUSTER_NUM=your value"
ExecStart=/usr/bin/node ./streaming
...

Salve o arquivo e certifique-se de recarregar os arquivos da unidade e reiniciar o serviço após salvar as alterações:

sudo systemctl daemon-reload
sudo systemctl restart mastodon-streaming.service

Isso substituirá o valor padrão de DB_POOL e fornecerá uma compreensão mais clara de quantas conexões de banco de dados são necessárias para sua instância de StreamingAPI.

Nota: Se você não indicar explicitamente o valor para DB_POOL, use o valor 10 como DB_POOL no cálculo de max_connections variável.

Agora você atualizou a configuração do StreamingAPI para permitir melhor rendimento. Isso ajudará sua StreamingAPI a atender mais usuários simultâneos sem falhar. Opcionalmente, você indicou explicitamente a variável de ambiente DB_POOL para otimizar sua rotina de configuração do banco de dados ou deixou-a inalterada e usou 10 como valor para DB_POOL para StreamingAPI.

Conclusão

Neste tutorial, você aprendeu como identificar e resolver gargalos no PostgreSQL, Sidekiq, serviço Web e StreamingAPI. Agora você pode configurar um novo servidor ou dimensionar seu servidor existente.

As abordagens de dimensionamento sempre podem ser melhoradas e refinadas, por exemplo, configurações complexas do Sidekiq podem ser modeladas ainda mais. O guia oficial de dimensionamento do Mastodon contém alguns pontos de vista extras sobre como dimensionar e otimizar seu servidor.

Outra ótima maneira de melhorar a experiência do usuário em seu servidor é habilitar a pesquisa de texto completo usando ElasticSearch. Isso permitirá que os usuários encontrem resultados de seus status, menções, favoritos e marcadores.

Também é possível fazer com que o Mastodon traduza toots e outras mensagens para o idioma do usuário ativando o LibreTranslate.

Artigos relacionados: