Open7

Misskey鯖を立てた時にやったこと

chilitreatchilitreat

基本的にはこの手順に沿って準備していく
https://misskey-hub.net/docs/install.html

動作環境はDockerでもよかったが、今回Oracle Cloud Infrastructureの VM.Standard.E2.1.Micro (AMD) (メモリ 1G) インスタンスで動かしたかったため、少しでもパフォーマンスオーバーヘッドの少なそうな Systemd の方を選択した

chilitreatchilitreat

オブジェクトストレージの設定

https://hide.ac/articles/csERs-7SU

こちらを参考にさせていただきました。

DBのバックアップ

DBのバックアップもこちらを参考にさせていただきました。

https://hide.ac/articles/E2Ea3cauk

misskey のDB (postgresql) の定期バックアップも同じオブジェクトストレージ上で管理したかったため、ディレクトリ構成だけ変更

/
- backup/  # DB周りのバックアップ系
- storage/    # misskeyでアップロードされたファイル類

今思うとバケット単位で可視性設定しているので、メディア系とバックアップ系を1つのバケットに格納せずバケット分けてもよかったかも(公開されて困るものは無いはずなので良いか

chilitreatchilitreat

インスタンス、ミドルウェア監視の設定

Mackerel を使った。
現在フリープランで運用していますが、個人的に使う分には十分すぎる機能。

https://ja.mackerel.io/pricing

Mackerel Agentのインストール

Hosts > 新規ホストの登録から、Ubuntu用のセットアップスクリプトをコピペして実行

ドキュメントにも同様のコマンドの記載があるのですが、新規ホストの登録からコピペした方にはAPIキーが最初からセットされてるのでこっちの方が手軽で良い
https://mackerel.io/ja/docs/entry/howto/install-agent/deb

メトリクス監視

エージェントをインストールしただけでロードアベレージやCPU使用率、メモリ使用率などメジャーどころは取れるのでOK

https://mackerel.io/ja/docs/entry/spec/metrics

Misskeyでは、キャッシュにredis, データベースにpostgresqlを使っているので、これらのミドルウェアのメトリクスも見れるようにします

プラグインを有効化してエージェントの再起動
https://mackerel.io/ja/docs/entry/howto/mackerel-agent-plugins

最初からコメントアウトされた状態で postgresql とredis用のプラグインのコマンドが用意されているので、コメントをアウトを外して認証情報を追加した

$ vi /etc/mackerel-agent/mackerel-agent.conf

...
# Plugin for PostgreSQL
#   Appropriate previlege settings required.
#   By default, the plugin accesses PostgreSQL on localhost.
[plugin.metrics.postgres]
command = "mackerel-plugin-postgres -user=<ユーザー名> -password=<パスワード> -database=mk1"

# Plugin for Redis
#   By default, the plugin accesses Redis on localhost.
#   Currently AUTH password has not been supported yet.
[plugin.metrics.redis]
command = "mackerel-plugin-redis"
...

保存したら、 sudo systemctl status mackerel-agent でエージェントの再起動

再起動したら、実際にカスタムメトリクスが送信されているか確認する。


postgresqlのカスタムメトリクス


redisのカスタムメトリクス

通知

通知先をDiscordに設定しています、Slack互換のWebhookURLをDiscordが生成してくれるので、これを MackerelのSlack通知URLに貼り付ければ動きます。

https://discord.com/developers/docs/resources/webhook#execute-slackcompatible-webhook


実際のアラートはこんな感じ

最低限のアラート設定だけ突っ込んでます

chilitreatchilitreat

misskeyをアップデートする

これでアップデートする

https://misskey-hub.net/docs/install/bash.html#_4-アップデートする

アップデートスクリプトをダウンロードしてきて、実行する

wget https://raw.githubusercontent.com/joinmisskey/bash-install/main/update.ubuntu.sh -O update.sh

sudo bash update.sh

実行すると、コードをクローンしてきて、ビルドし直すみたい。

アプデ中はダウンタイムが発生するので注意(自分の場合は5分ぐらいかかった)

chilitreatchilitreat

メモリ使用率が高い対策

メモリ 1Gのマシンで動かしているとメモリ使用率が高い時の動作が怪しくなることがちょくちょくあった。

というのをMisskeyで呟いたら、ありがたい情報を得た

https://misskey.chilitreat.dev/notes/9iie6lvsx4

ちょうど、Ubuntu22.04で動かしていたのでとりあえずやってみる

# インストール
sudo apt install libjemalloc2

この後に、各種サービスの再起動を求められたので何も考えずにmisskey含み複数サービスの再起動をした

sudo systemctl edit をしたら nanoが起動したのでvimに変更した

sudo update-alternatives --config editor
sudo systemctl edit misskey.chilitreat.dev

以下を追加して保存

[Service]
Environment="LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libjemalloc.so.2"

sudo systemctl restart misskey.chilitreat.dev

結果

16:00ちょい前の再起動によってSwap使用量は減った(これはlibjemalloc2インストール時の再起動)
16:10前後の再起動がlibjemalloc2へ設定変更した時の再起動

ちょっと様子見してSwapが上がり続けなければヨシ!

https://github.com/misskey-dev/misskey/issues/10984#issuecomment-1672495555

chilitreatchilitreat

OCIのStorageの無料枠(20GB)に達してしまい、画像のアップロードが失敗するようになった

このブラーがかかった画像がアップロードに失敗してる画像群

サーバーのjournal見てみると、こんなエラーが出ていたので気づいた

ERR  1        [drive register]        Upload Failed: key = storage/thumbnail-2ea772e5-f058-43f9-be0d-e0f822d1987e.webp, filename = casmarket-14-poster-wide>
StorageLimitExceeded: Storage limit exceeded for tenancy during upload
    at throwDefaultError (/home/misskey/misskey/node_modules/.pnpm/@smithy+smithy-client@2.1.5/node_modules/@smithy/smithy-client/dist-cjs/default-error-ha>
    at /home/misskey/misskey/node_modules/.pnpm/@smithy+smithy-client@2.1.5/node_modules/@smithy/smithy-client/dist-cjs/default-error-handler.js:18:39
    at de_PutObjectCommandError (/home/misskey/misskey/node_modules/.pnpm/@aws-sdk+client-s3@3.412.0/node_modules/@aws-sdk/client-s3/dist-cjs/protocols/Aws>
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async /home/misskey/misskey/node_modules/.pnpm/@smithy+middleware-serde@2.0.8/node_modules/@smithy/middleware-serde/dist-cjs/deserializerMiddleware.>
    at async /home/misskey/misskey/node_modules/.pnpm/@aws-sdk+middleware-signing@3.410.0/node_modules/@aws-sdk/middleware-signing/dist-cjs/awsAuthMiddlewa>
    at async /home/misskey/misskey/node_modules/.pnpm/@smithy+middleware-retry@2.0.11/node_modules/@smithy/middleware-retry/dist-cjs/retryMiddleware.js:27:>
    at async /home/misskey/misskey/node_modules/.pnpm/@aws-sdk+middleware-flexible-checksums@3.410.0/node_modules/@aws-sdk/middleware-flexible-checksums/di>
    at async /home/misskey/misskey/node_modules/.pnpm/@aws-sdk+middleware-logger@3.410.0/node_modules/@aws-sdk/middleware-logger/dist-cjs/loggerMiddleware.>
    at async Promise.all (index 0)
    at async Upload.__uploadUsingPut (/home/misskey/misskey/node_modules/.pnpm/@aws-sdk+lib-storage@3.412.0_@aws-sdk+client-s3@3.412.0/node_modules/@aws-sd>
    at async Upload.__doConcurrentUpload (/home/misskey/misskey/node_modules/.pnpm/@aws-sdk+lib-storage@3.412.0_@aws-sdk+client-s3@3.412.0/node_modules/@aw>
    at async Promise.all (index 0)
    at async Upload.__doMultipartUpload (/home/misskey/misskey/node_modules/.pnpm/@aws-sdk+lib-storage@3.412.0_@aws-sdk+client-s3@3.412.0/node_modules/@aws>
    at async Upload.done (/home/misskey/misskey/node_modules/.pnpm/@aws-sdk+lib-storage@3.412.0_@aws-sdk+client-s3@3.412.0/node_modules/@aws-sdk/lib-storag>
    at async DriveService1.upload (file:///home/misskey/misskey/packages/backend/built/core/DriveService.js:332:9)
    at async Promise.all (index 1)
    at async DriveService1.save (file:///home/misskey/misskey/packages/backend/built/core/DriveService.js:168:13)
    at async DriveService1.addFile (file:///home/misskey/misskey/packages/backend/built/core/DriveService.js:506:20)
    at async DriveService1.uploadFromUrl (file:///home/misskey/misskey/packages/backend/built/core/DriveService.js:691:31)
    at async ApImageService.createImage (file:///home/misskey/misskey/packages/backend/built/core/activitypub/models/ApImageService.js:66:22)
    at async ApImageService.resolveImage (file:///home/misskey/misskey/packages/backend/built/core/activitypub/models/ApImageService.js:94:16)
    at async Promise.all (index 0)
    at async ApNoteService.createNote (file:///home/misskey/misskey/packages/backend/built/core/activitypub/models/ApNoteService.js:159:23)
    at async ApNoteService.resolveNote (file:///home/misskey/misskey/packages/backend/built/core/activitypub/models/ApNoteService.js:302:20)
    at async ApNoteService.createNote (file:///home/misskey/misskey/packages/backend/built/core/activitypub/models/ApNoteService.js:164:40)
    at async ApNoteService.resolveNote (file:///home/misskey/misskey/packages/backend/built/core/activitypub/models/ApNoteService.js:302:20)
    at async ApNoteService.createNote (file:///home/misskey/misskey/packages/backend/built/core/activitypub/models/ApNoteService.js:164:40)
    at async ApNoteService.resolveNote (file:///home/misskey/misskey/packages/backend/built/core/activitypub/models/ApNoteService.js:302:20)
    at async ApNoteService.createNote (file:///home/misskey/misskey/packages/backend/built/core/activitypub/models/ApNoteService.js:164:40)
    at async ApNoteService.resolveNote (file:///home/misskey/misskey/packages/backend/built/core/activitypub/models/ApNoteService.js:302:20)
    at async ApNoteService.createNote (file:///home/misskey/misskey/packages/backend/built/core/activitypub/models/ApNoteService.js:164:40)
    at async ApNoteService.resolveNote (file:///home/misskey/misskey/packages/backend/built/core/activitypub/models/ApNoteService.js:302:20)
    at async ApNoteService.createNote (file:///home/misskey/misskey/packages/backend/built/core/activitypub/models/ApNoteService.js:164:40)
    at async ApNoteService.resolveNote (file:///home/misskey/misskey/packages/backend/built/core/activitypub/models/ApNoteService.js:302:20)
    at async ApNoteService.createNote (file:///home/misskey/misskey/packages/backend/built/core/activitypub/models/ApNoteService.js:164:40)
    at async ApNoteService.resolveNote (file:///home/misskey/misskey/packages/backend/built/core/activitypub/models/ApNoteService.js:302:20)
    at async ApNoteService.createNote (file:///home/misskey/misskey/packages/backend/built/core/activitypub/models/ApNoteService.js:164:40)
    at async ApNoteService.resolveNote (file:///home/misskey/misskey/packages/backend/built/core/activitypub/models/ApNoteService.js:302:20)
    at async tryResolveNote (file:///home/misskey/misskey/packages/backend/built/core/activitypub/models/ApNoteService.js:184:33)
    at async Promise.all (index 0)
    at async ApNoteService.createNote (file:///home/misskey/misskey/packages/backend/built/core/activitypub/models/ApNoteService.js:202:29)
    at async ApNoteService.resolveNote (file:///home/misskey/misskey/packages/backend/built/core/activitypub/models/ApNoteService.js:302:20)
    at async Promise.all (index 0)
    at async ApPersonService.updateFeatured (file:///home/misskey/misskey/packages/backend/built/core/activitypub/models/ApPersonService.js:494:31)
    at async ApPersonService.createPerson (file:///home/misskey/misskey/packages/backend/built/core/activitypub/models/ApPersonService.js:328:9)
    at async ApPersonService.resolvePerson (file:///home/misskey/misskey/packages/backend/built/core/activitypub/models/ApPersonService.js:464:16)
    at async Promise.all (index 24)
    at async ApAudienceService.parseAudience (file:///home/misskey/misskey/packages/backend/built/core/activitypub/ApAudienceService.js:32:33)
    at async ApNoteService.createNote (file:///home/misskey/misskey/packages/backend/built/core/activitypub/models/ApNoteService.js:143:30)
    at async ApInboxService.createNote (file:///home/misskey/misskey/packages/backend/built/core/activitypub/ApInboxService.js:353:13) {
  '$fault': 'client',
  '$metadata': {
    httpStatusCode: 400,
    requestId: 'nrt-1:VSfBvWBB4DyvWHnpS9vNzziCTb8n3RPBpr_PDH8K6qyzg1lTOIdHPm4tsaKzibiB',
    extendedRequestId: undefined,
    cfId: undefined,
    attempts: 1,
    totalRetryDelay: 0
  },

対策

OCIのプランを無料から有料プランにアップグレードした。
一旦回避できたが他に良い感じの方法ないか検討中