优化托管在 DigitalOcean 的 Mastodon

DigitalOcean 的 Marketplace 提供 Mastodon 的 Droplet。使用基础配置的服务器,每月费用为 6 美元。但是使用 Ruby 开发的 Mastodon 是吃内存的大户,基础配置的 1G 内存根本不够用,需要手动优化才能正常访问网站。

注意

本文命令除非特别注明,皆在 root 权限下运行。

创建 SWAP

DigitalOcean 的 Droplet 默认是不开启 SWAP 的,需按照此教程开启系统 SWAP。此处为系统创建一个 2G 的交换空间:

bashfallocate -l 2G /swap
chmod 600 /swap
mkswap /swap
swapon /swap
echo '/swap none swap sw 0 0' | tee -a /etc/fstab

禁用 unattended-upgrades 服务

Droplet 实例启动后,CPU 占用马上就 100% 了。用 top 命令一查,发现一个叫 unattended-upgrades 进程丧心病狂地跑满了 CPU。禁用该服务:

bashsystemctl stop unattended-upgrades
systemctl disable unattended-upgrades

限制 Journal 日志大小

使用 journalctl --disk-usage 命令查看日志使用的硬盘空间。系统长期运行时,Journal 日志日积月累会占用硬盘空间大小非常可观。可以按时间或大小保留 Journal 日志。下面命令让日志最多保留 7 天、占用 100 MB 空间:

bashjournalctl --vacuum-time=7d
journalctl --vacuum-size=100M

也可以开启日志的持久化限制。编辑配置文件 /etc/systemd/journald.conf,开启如下任一配置即可:

iniMaxRetentionSec=7day
SystemMaxUse=100M

重启 journal 服务使配置生效:

bashsystemctl restart systemd-journald

Ruby 使用 Jemalloc 内存分配器

Ruby 进程是占用内存的大头。Jemalloc 是一款通用的内存分配器,支持对包括 Ruby 在内的多种语言进行内存使用的优化。

bashapt install libjemalloc-dev
su - mastodon
RUBY_CONFIGURE_OPTS=--with-jemalloc rbenv install 2.6.6
rbenv global 2.6.6
ruby -r rbconfig -e "puts RbConfig::CONFIG['MAINLIBS']"

如果终端返回字符串中包含 -ljemalloc 则表示安装成功。

修改 Worker 进程数量

Mastodon 有三种进程:

可以将 Web 进程减少到一个,线程数控制在 10 个以内;Streaming 进程减少到一个;Sidekiq 进程减少到四个。

首先,打开并修改配置文件:

bashsu - mastodon
cd /home/mastodon/live
nano .env.production

在配置文件中添加如下内容:

iniWEB_CONCURRENCY=1
MAX_THREADS=10
STREAMING_CLUSTER_NUM=1

然后,打开 Sidekiq 服务配置文件:

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

将文件中的 bundle exec sidekiq -c 25 修改为 bundle exec sidekiq -c 4,保存后退出编辑。运行命令重新载入 systemd 配置:

bashsystemctl daemon-reload

重启服务

修改完毕后,重启服务使配置生效:

bashsystemctl restart mastodon-sidekiq
systemctl restart mastodon-streaming
systemctl restart mastodon-web
systemctl restart postgresql

释放硬盘空间

定期清理缓存和媒体文件,可以有效地减缓硬盘空间的消耗速度。创建 /home/mastodon/mastodon-clear.sh 脚本,内容如下:

bash#!/usr/bin/env bash
export PATH="/home/mastodon/.rbenv/bin:$PATH"
eval "$(rbenv init -)"
/home/mastodon/live/bin/tootctl statuses remove
/home/mastodon/live/bin/tootctl preview_cards remove
/home/mastodon/live/bin/tootctl media remove --days=7
/home/mastodon/live/bin/tootctl media remove-orphans
/home/mastodon/live/bin/tootctl cache clear

其中 --day=7 参数表示删除 7 天以前的站外媒体文件,可以修改为其他天数。然后通过 systemd 定时运行该脚本。

创建 /etc/systemd/system/mastodon-clear.service 配置文件,内容如下:

ini[Unit]
Description=Mastodon data cleaning service

[Service]
User=mastodon
Environment="RAILS_ENV=production"
ExecStart=/bin/bash /home/mastodon/mastodon-clear.sh

创建 /etc/systemd/system/mastodon-clear.timer 配置文件,内容如下:

ini[Unit]
Description=Mastodon data cleaning timer

[Timer]
OnCalendar=*-*-* 17:00
Unit=mastodon-clear.service

[Install]
WantedBy=timers.target

其中 OnCalendar=*-*-* 17:00 表示服务器时间每天下午五点执行清理数据脚本。由于服务器默认使用 UTC 时间,这个时间相当于东八区的凌晨一点,也可以修改为其他时间。

最后启动定时器:

bashsystemctl start mastodon-clear.timer
systemctl enable mastodon-clear.timer

其他

全文检索

Mastodon 使用 ElasticSearch 作为搜索引擎,需要安装插件才能支持中文搜索。ES 的内存和硬盘占用也很可观,小型实例建议不要开启。

媒体文件

用户上传的图片视频等媒体文件保存在 ~/live/public/system/ 路径下。为了节省本地硬盘空间,可以将媒体文件迁移到云存储服务器,支持 Amazon S3、Google Cloud 或 Wasabi 等。有人推荐使用 Scaleway 云存储,因为有 75G 的免费空间和每月 75G 的免费流量,但是超额仍需付费。如果对每个月流量没有把握,还是谨慎开启。详细配置可以参考这篇文章。

中继

开启中继会导致硬盘空间使用率快速上涨,需要谨慎开启。下面两个是可用的中文长毛象中继:

群组

群组是一种长毛象机器人,它会转发所有 @ 它的嘟文,相当于一个关注即可参与的公共讨论区。@[email protected] 是最常用的中文群组,也可以在 https://ovo.st/ 找到其他热门群组。