Direkt zum Inhalt
MP-Development Code, Bikes and more

Mastodon skalieren

Gespeichert von Michael am
sidekiq

Ich habe ja nun schon einige Zeit eine Mastodon Instanz am laufen und bisher hat die mit der Standard Installation auch gut funktioniert. Das hat sich die Tage aber geändert. In einer meiner eingebundenen Relays hat sich ein anderes Relay registriert, dass Unmengen an toots aus Australien und Neuseeland in die förderierte Timeline spült. Die Warteschlangen für ingress(900 Queues) und pull(+8000 Queues) waren voll und Sidekiq kam nicht mehr hinterher. Zeit sich mal das Finetuning von Mastodon anzuschauen.

Standartinstallation

Im Prinzip läuft Mastodon bei mit mir der Standard docker-compose.yml aus dem github Repository, glaube zumindest das ich da nicht Großartig was dran geändert habe. Diese Config sieht jedenfalls nur einen Sidekiq Container mit den Standardeinstellungen von 5 Queues vor und das ist der Flaschenhals. Das funktioniert nur so lange gut, solange man eine kleine Instanz betreibt auf der nicht die Welt los ist.

Wächst die Instanz aber muss man da früher oder später nachsteuern. Vielleicht mal kurz zur Erklärung wie das Ganze mit Sidekiq funktioniert. Jede Aktion auf Mastodon führt zu einem Queue Eintrag in Sidekiq, d.h. wenn man einen Toot absetzt wird der unter Umständen auch raus in die Welt geschickt, kommt immer darauf an ob der Verfasser auch Follower hat, oder ihr Relays angebunden habt. Je mehr Follower oder Relays, umso mehr Queues. Das gilt natürlich auch für alles was rein kommt.

Skalierung

Wir müssen also Mastodon bzw. Sidekiq dazu bewegen mehr Queues verarbeiten zu können und die Doku dazu gibt auch einige Anhaltspunkte und man kann die Anzahl der Worker oder Threads mit -c erhöhen. Die magische Zahl hierbei ist aber auch wieder auf max 25 beschränkt, wie man aus einigen Internetkommentaren entnehmen kann. Also brauchen wir auch mehr Sidekiq Prozesse um mehr Queues verarbeiten zu können. Und das wiederum heißt mehr Sidekiq Container.

Datenbank

Als erstes müssen wir dafür die max_connections der DB anspassen. Die sollten immer mindestens so hoch sein wie die maximale Anzahl der Queues. Das bewerkstelligt man mit einer kleinen Anpassung in im DB Service in der docker-compose.yml. Es empfiehlt sich auch sich die Werte für memory, number of threads und connectin pool size der DB anzusehen und gegebenenfalls zu erhöhen.

command: postgres -c 'max_connections=200'

Und jetzt brauchen wir noch mehrere Sidekiq Container die sich um die Queues kümmern. Mit -q können wir dabei angeben für welche Queues der Container zuständig sein soll. Ich habe mich dabei an die Lösung von nora.codes gehalten, Thomas Leiter verfolgt eine etwas andere Strategie in seinem Blog falls wer auf der Suche nach einer Lösung für systemd ist.

docker-compose Services

Ich hab die Sidekiq Services mal nach den Queues benannt für die sie zuständig sind, wie schon erwähnt kann man die mit -q angeben. Den Standard Sidekiq Service kann man dann einfach löschen. Wichtig ist noch das man die Environment Variable DB_POOL mit angibt, die immer so groß sein muss wie die Anzahl der Threads mit -c. Bei mir sieht das jetzt so aus. Die wichtigsten Queues sind default, push und pull, deswegen kommen die mehrmals vor.

 

  sidekiq-default-push-pull:
    image: tootsuite/mastodon
    restart: always
    env_file: .env.production
    command: bundle exec sidekiq -c 25 -q default -q push -q pull
    environment:
      DB_POOL: 25
    depends_on:
      - db
      - redis
    networks:
      - external_network
      - internal_network
    volumes:
      - ./public/system:/mastodon/public/system

  sidekiq-default-pull-push:
    image: tootsuite/mastodon
    restart: always
    env_file: .env.production
    command: bundle exec sidekiq -c 25 -q default -q pull -q push
    environment:
      DB_POOL: 25
    depends_on:
      - db
      - redis
    networks:
      - external_network
      - internal_network
    volumes:
      - ./public/system:/mastodon/public/system


  sidekiq-pull-default-push:
    image: tootsuite/mastodon
    restart: always
    env_file: .env.production
    command: bundle exec sidekiq -c 25 -q pull -q default -q push
    environment:
      DB_POOL: 25
    depends_on:
      - db
      - redis
    networks:
      - external_network
      - internal_network
    volumes:
      - ./public/system:/mastodon/public/system


  sidekiq-push-default-pull:
    image: tootsuite/mastodon
    restart: always
    env_file: .env.production
    command: bundle exec sidekiq -c 25 -q push -q default -q pull
    environment:
      DB_POOL: 25
    depends_on:
      - db
      - redis
    networks:
      - external_network
      - internal_network
    volumes:
      - ./public/system:/mastodon/public/system


  sidekiq-ingress-push:
    image: tootsuite/mastodon
    restart: always
    env_file: .env.production
    command: bundle exec sidekiq -c 25 -q ingress -q push
    environment:
      DB_POOL: 25
    depends_on:
      - db
      - redis
    networks:
      - external_network
      - internal_network
    volumes:
      - ./public/system:/mastodon/public/system


  sidekiq-push-scheduler:
    image: tootsuite/mastodon
    restart: always
    env_file: .env.production
    command: bundle exec sidekiq -c 5 -q push -q scheduler
    environment:
      DB_POOL: 5
    depends_on:
      - db
      - redis
    networks:
      - external_network
      - internal_network
    volumes:
      - ./public/system:/mastodon/public/system


  sidekiq-push-mailers:
    image: tootsuite/mastodon
    restart: always
    env_file: .env.production
    command: bundle exec sidekiq -c 5 -q push -q mailers
    environment:
      DB_POOL: 5
    depends_on:
      - db
      - redis
    networks:
      - external_network
      - internal_network
    volumes:
      - ./public/system:/mastodon/public/system

 

Damit habe ich jetzt 7 Sidekiq Prozesse mit insgesamt 135 Threads und noch Platz um z.B. Puma(web) mit WEB_CONCURRENCY und MAX_THREADS bei Bedarf auch noch ein wenig zu optimieren.

Die laufenden Prozesse in Sidekiq sehen dann so aus

Nicht vergessen die Container einmal zu stoppen und wieder neu zu starten damit das alles läuft. Den alten Sidekiq Container löschen wir gleichzeitig.

docker-compose stop
docker-compose up -d --remove-orphans

Die aufgelaufen Queues wurden danach bei mir in ca. 3 Minuten abgearbeitet und seitdem ist Ruhe.

Hier nochmal die Links

https://nora.codes/post/scaling-mastodon-in-the-face-of-an-exodus/

https://thomas-leister.de/en/scaling-up-mastodon/

Neuen Kommentar hinzufügen

CAPTCHA
Diese Sicherheitsfrage überprüft, ob Sie ein menschlicher Besucher sind und verhindert automatisches Spamming.
Blog-Tags