はんドンクラブ 運営ブログ

Mastodonインスタンス「handon.club」の運営ブログです。コラムなど,Mastodonに関する一般的な記事も投稿予定です。

3.2.0アップデートに伴うトゥートの公開範囲の表示方法変更について

こんばんは。アップデートの度に記事を書くのが面倒になって辞めてしまった,はんドンクラブ管理人のはんです。

はんドンクラブでは先ほど3.2.0rc1にアップデートをしましたが,はんドンクラブ独自仕様に関わる重要な仕様変更が行われましたので,この記事にてみなさんに周知したいと思います。

変更の理由は,本家のソースコードで行われた変更に起因するものです。この変更が従来のはんドンクラブ独自仕様と干渉するような内容でして,独自仕様を変更する必要が発生しました。

変更内容

Webにおけるタイムライン上のトゥートの公開範囲に関わる表記が変更となります。具体的には,非収載トゥートおよびフォロワー限定トゥートの表記方法(識別方法)が変更になります。右肩に鍵マークが付くようになります。

なお,クライアントを利用する場合には影響ありません。

非収載トゥート

  • Before(これまで)

f:id:highemerly:20200716232821p:plain
これまで・非収載

  • After(これから)

f:id:highemerly:20200716233636p:plain
これから・非収載

フォロワー限定トゥート

  • Before(これまで)

f:id:highemerly:20200716232850p:plain
これまで・フォロワー限定

  • After(これから)

f:id:highemerly:20200716233713p:plain
これから・フォロワー限定トゥート

変更の経緯

もともと,Mastodonでは,タイムライン上で公開トゥートと非収載トゥートの区別が付きませんでした。そこではんドンクラブは,独自仕様として「ブーストボタンに斜線を付与することで非収載トゥートであることを明示する」こととしていました。しかし,この点には問題がありました。それは,本来非収載トゥートはブースト出来るのにもかかわらず,あたかもブーストできないかのような印象を与えていたことです。

一方最近,本家ソースコードにおいて,トゥートの公開範囲を明示するような修正がマージされました。本家でも公開トゥートと非収載トゥートの区別が付くようになったのです。

github.com

そのためはんドンクラブでは,非収載トゥートのブーストボタンに斜線を付与する独自の変更を辞めました。前述の通り,非収載トゥートはブースト可能であるので,わざわざわかりづらい表示をする必要はないと判断したためです。ただ,フォロワー限定トゥートにブーストボタンが表示されるようになったので,そこには独自仕様として斜線を付与してみました(このコミットによりブースト可否がボタンの濃淡だけで表現されるようになったため,その分かりづらさを解消するためです)。

おまけ

関連するコミットをプルリクしてマージされました。

github.com

データの可用性・バックアップポリシーについて

こんにちは。運営ブログの更新が滞っている、はんドンクラブ管理人のはんです。たまには何か書こうと思い立ちました。

この記事では、はんドンクラブにおけるデータの可用性ポリシーについてまとめておこうと思います。可用性(アベイラビリティ)とは、システムを故障なく継続して動かせる能力のことです。ただ、はんドンクラブを構成するすべての要素の可用性について書くのはとても大変です。そこで今回は、特に重要なデータベースの可用性、特にバックアップのポリシーについてご紹介したいと思います。

はんドンクラブの利用サービス

はんドンクラブでは、サービス開始当初から、「私の家にサーバを設置する構成(オンプレ構成)は取らない」というポリシーを貫いています。様々な理由がありますが、一番の理由はセキュリティです。オンプレ構成の場合、データ漏洩リスクとして「私の家に強盗が入る」「私の家に来た友人が不正を働きデータを盗む*1」ことを考慮しなくてはならず、設計や運用の負担になることが予想されます。

もちろん、可用性の向上という観点でも、クラウドサービスを使う利点はあります。残念なことに私はデータセンターには住んでおりませんので、家庭向けインターネットアクセス回線や家庭向け商用電源の可用性を考慮しなくてはなりません。面倒すぎます。

さて、前置きが長くなりました。利用しているクラウドサービスの可用性について考えたいと思います。はんドンクラブでは主に以下のサービスを利用しています。

このうち、データが保管されており、データという観点で可用性を考慮する必要があるサービスはさくらインターネットGMOの2つです。いずれも日本国内に設置されたサーバのみを利用しており、十分な可用性が担保されていると認識しています。そのため、そもそもこれらのサービスを利用している時点で、不意の故障に起因する可用性の低下について神経質に考える必要はないというのが実情です。 ここで、不意の故障とは、電源喪失やネットワーク切断などインフラ面の故障を指しています。

さくらのVPSの特長|VPS(仮想専用サーバー)はさくらインターネット

オブジェクトストレージ|VPSならConoHa

とはいえ、これはあくまで設備故障に起因する可用性の話です。私のオペレーションミス、ソフトウェアのバグに起因したデータロストなど、ソフトウェア的なリスクは考慮すべきです。このリスク軽減のためには「定時の自動バックアップ」が有効です。以後はデータのバックアップについて考えていこうと思います。

Mastodonの主なデータ

そもそもMastodonで記録されるデータは、その保存先によって、以下4つに分類されます。

保存先 データの内容
PostgreSQL トゥート、フォロー関係、個人設定など
オブジェクトストレージ メディアファイル、アイコン画像など
redis キャッシュ(各個人のタイムラインなど)
Elasticsearch 検索インデックス

当然、すべてのバックアップを取得しておくのが望ましいです。しかし、当然それなりの費用がかかります。そこで、はんドンクラブでは、redisとElasticsearchについてはバックアップの取得は不要だと判断し、一旦考慮の対象から除外しています。理由は、万が一の故障が発生しても、再生成可能なデータが多いからです。

redisの中の最も重要なデータの一つである各ユーザのタイムラインは、いざとなれば以下コマンドで再生成できます。

$ RAILS_ENV=production bundle exec bin/tootctl feeds build

なお、redisには、タイムライン以外の情報も含まれています。しかしながら、それはあくまでキャッシュデータです。大半はPostgreSQLのデータから復旧可能ですし、そうでない情報もあくまで処理速度向上などにしか用いられません。

ElasticSearchについても同様です。PostgreSQLのデータさえ残っていれば、以下コマンドで復旧できます(ものすごく時間かかりますが・・・)。

$ RAILS_ENV=production bundle exec bin/tootctl search deploy

ここまでの説明で、PostgreSQLとオブジェクトストレージのデータバックアップが可用性担保に重要であることをご理解頂けたと思います。次は、これら重要なデータのバックアップについて考えたいと思います。

バックアップルール

PostgreSQL

2020年6月現在、以下のルールで運用しています。

  • 1日2回のフルバックアップを自動で取得する。
    • 2回のうち1回は、データベースサーバのローカルに保管する。
    • 2回のうちもう1回は、地理的に離れた別サーバへ保管する。
    • 自動バックアップは5世代分(=約3日間分)保管し、その後は自動で削除する。
  • ソフトウェアアップデートの際にDBマイグレーションが走る場合は、フルバックアップを手動で取得する。

特に、「地理的に離れた」サーバへの保管については、さくらインターネット自体の故障リスクを考慮しない場合は不要なはずです。これは、仮にディスクの枯渇を考慮*2しても、同じロケーションの別サーバに保存さえしておけば、可用性が担保できるはずだからです。冒頭に言ったことと矛盾していますね。

このリスクを考慮しているのは、PostgreSQLのデータが大変重要であるためです。このデータが吹き飛べば、サービス継続はほぼ不可能です。そのため、さくらインターネット側の故障や、大規模な自然災害が起きた場合でも迅速にデータを復旧できるようにするための工夫をしています。具体的には、現在PostgreSQLが設置されているのは東京都内ですので、毎日大阪府内へのバックアップデータ転送を行なっています。

オブジェクトストレージ

2020年6月現在、特段バックアップをしていません。メディアファイルのバックアップは非常に費用がかかるためです。

しかし、アカウントのアイコン、カスタム絵文字など、特にサービス継続に重要なメディアファイルについては、自動バックアップできる仕組みを整えようと考えています。そのために、現在、OpenStack Swiftの仕様を頑張って調査しています。そのうちバックアップできるようにしたいです。

復旧のポリシー

データの可用性を担保するためには、バックアップだけ取っていればいいというわけではありません。有事の際、迅速かつ確実な復旧を行う必要があります。インフラエンジニアあるあるですが、「バックアップを取っていたつもりだったが実は取れていなかった」という事態はなんとしてでも避けなくてはなりません。

そこで、PostgreSQLのバックアップデータについては、過去1度、バックアップデータからの復旧訓練を実施しています。その際には、手順の確認に加え、全データが復旧できたことを確認しました。

また、故障を発見してから復旧作業が完了するまでの目標時間とその方法は、以下のとおり定めてあります。

  • ソフトウェア不具合やDB不整合などDBのデータのみ故障した場合
    • 復旧目標: 20分
    • 最新のバックアップを挿入することで復旧
  • ディスク枯渇などでDBサーバ自体が故障した場合
    • 復旧目標: 2時間
    • 新たにサーバを立ち上げることで復旧
  • DBサーバを含むさくらVPS東京リージョンがすべて故障した場合
    • 仮復旧目標: 2時間、復旧目標: 3日
    • 一旦開発系として利用しているAWSを利用して仮復旧させ、その後別のクラウドサービスを用いて本格復旧
  • 大規模災害等で東京中のインフラが壊滅状態の場合
    • 復旧目標: 3日
    • 大阪に設置されているクラウドサービスで復旧

勘の良い方はお分かりかと思いますが、復旧目標が「2時間」に設定されているのは、総務省総合通信局への四半期報告を行わなくていいようにするためです*3*4。とはいえ、個人の運営サービスである以上、すべてのパターンの故障時に2時間以内の復旧ができるようにすることは考えていません。それはやりすぎです。

今後の課題

PostgreSQLのデータ肥大化に伴い、フルバックアップを取得することが負荷に繋がっている可能性があります。現在は pg_dump コマンドでのバックアップ取得をしていますが、実際はほぼ参照されない古いデータも総なめしてしまいます。つまり、PostgreSQL最適化の仕組みであるキャッシュを壊滅させているのではないかと思っています。

PostgreSQLアンチパターン:運用DBのpg_dump - Qiita

しかし、正確な影響の度合いはまだできていません。そもそも、ホットバックアップの場合、よく知られた代替手段は存在しないと思ってます(常時レプリケーションを行い、レプリケーション先でバックアップを取得すればいいのでしょうが、費用がかかりすぎます)。影響度合いと手間・費用を天秤にかけて、継続検討していきたいです。

  • オブジェクトストレージのバックアップ

本文中でも述べた話です。

ConohaのオブジェクトストレージはOpenStack Swiftに準拠しています。OpenStackを触らなくなってもう3年、、ほぼ知識がない技術領域です。その特性や仕様をきちんと理解した上で、バックアップの必要性有無については継続検討します。

  • redis

本文中でredisはバックアップ不要だと言いましたが、実際にはバックアップしたいデータも含まれています。特に、応答しなかったリモートサーバ一覧のキャッシュは、サービスの安定運用に必要なものです。優先度は低いですが、余裕ができれば考えていきたいです。

おわりに

長文となりましたが、はんドンクラブにおける可用性設計について、私の備忘録を兼ねてまとめてみました。

大事なことは、コスト・影響度合い・発生確率を考慮したリスクマネジメントをすることだと思っています。何がなんでも考慮していては、どこかに無理が生じ、実運用に支障をきたすことが考えられるためです。

また、バックアップを取っているだけでは不十分で、どういう時にどのバックアップをどのタイミングで復旧させるのか、あらかじめ決めておき訓練しておくことも大事だと思います。このあたりは引き続き検討し、改善に努めたいと思います。

*1:そんな友人はいないと思っていますが、リスクマネジメントとして考慮しなくてはならないという意味で記載しています。

*2:ディスクの枯渇が起こらないよう5分間隔で監視しており、そのリスクがある場合には管理人と副管理人の2人に警報が飛ぶ仕組みになっています。そのため、枯渇は起きるリスクは実際には低いです。

*3:はんドンクラブでは、近畿総合通信局に、個人の届出電気通信事業者として届出を行なっています。

*4:実際には私が故障に気づくまでの時間を含んで、ユーザへの影響時間が2時間以内である必要があります。しかし、原則5分以内に気づけるようになっているので、仕事中など即時対応できる状況であれば誤差の範囲です。

2019年はんドンクラブ運営の振り返りと年末のご挨拶

こんにちは。はんドンクラブ管理人のはんです。年末の挨拶に代えて,今年のはんドンクラブの振り返り記事を書かせていただきます。今年も1年間,皆様のおかげで無事に運営できました。本当にありがとうございました。

振り返り

コミュニティに関する所感

繰り返しとなりますが,SNSサービスの管理人としては,フォロー/フォロワー関係やオフ会など,はんドンクラブやFediverseで形成されたコミュニティについては関知しないことにしています。ただし,私個人の観測範囲(死語)における感じたことだけまとめておきたいと思います。

まず,2019年も何人かのユーザが登録してくれました。定着した方もいるようです。新たなユーザに登録して頂けるのは,管理人としてとても嬉しいことです。はんドンクラブは招待制として運用していますが,これは元々スパム防止の目的で導入した制度であり,新規登録ユーザを制限するためではありません。そのため,招待したい人が居れば遠慮無く招待していただけると嬉しいです。

なお,v3.0より,「承認制」という設定ができるようになりました。今後の運用について検討中ですが,もしかしたら承認制+招待制に変更するかもしれません。その際はきちんと事前にご相談しますね。

さて,はんドンクラブ全体に話を戻します。トゥートのvisilibityを非収載や非公開に設定しているユーザが多くLTLには現れづらいものの,引き続きいろいろな方に利用していただいているようです。管理人としては嬉しい限りです。私のフォロー範囲に限っても,様々な使い方で様々な方と交流しているユーザさんが観測できています。分散SNSは,サーバ内部の交流と,それ以外のサーバとの交流,どちらも十分に楽しめるようになっています。はんドンクラブは,当然,話題や利用方法を一切制限していませんので,皆さま思い思いのMastodonを楽しんで頂いていれば幸いです。

また,Fantiaで行っているカンパについても,ご協力いただきありがとうございます。本当に助かっています。このカンパがなければ絶対に運営できていません。引き続きのご支援をいただきますようお願いします。なお,サーバ運営費用の公表も行いたいとは思っていますが,適切な方法を模索しています。もう少しお待ち頂ければ幸いです。

データで振り返る2019年

昨年から引き続き,データで振り返ってみたいと思います。

  • 基礎データ

(2019年12月31日現在)

キー
登録ユーザ数 224人
アクティブユーザ数 142人
総トゥート数 1,268,023トゥート
総通報数 297
カスタム絵文字数 731
データベース使用容量 8.8GB
メディアストレージ使用容量 85.52GB
  • トゥート数推移

f:id:highemerly:20191231141709p:plain

はんドンクラブにおける総トゥート数の推移のグラフです。参考までに,はんドンクラブで受信した,他のサーバのトゥート数も含んだ合計値も示しています(各データのオーダが異なるため,表示軸を分離している点は注意ください)。はんドンクラブでは,2018年8月のTwitter APIの利用規程変更以降,1日あたり安定して2,000トゥート〜3,000トゥートほどご利用いただいているようです。

  • ユーザ毎のトゥート数分布

f:id:highemerly:20191231143737p:plain

2019年12月31日現在の,アカウント毎のトゥート数の分布です。相変わらずロングテールですね。

  • はんドンクラブが認知している他サーバのユーザ数

2019年は,mstdn.jp・pawoo.netの運営委譲,friends.nicoの閉鎖とbest-friends.chatの開始など,国内大規模サーバ激動の年でした。その影響かどうかはわかりませんが,はんドンクラブで認知しているユーザ数は,海外サーバであるmastodon.cloudが最も多い・・・という結果になりました。昨年はpawoo.netだったのですが。

認知しているユーザ数の一覧は以下のとおりです。150人以上のサーバに絞って記載してみました。なお,あくまではんドンクラブが認知しているユーザに限ったものであり,そのサーバに属する全ユーザを補足できている訳ではない点はご注意ください。

サーバ名 アカウント数
mastodon.social 7540
pawoo.net 6571
mstdn.jp 5991
best-friends.chat 606
mastodon.art 446
mstdn.maud.io 434
knzk.me 364
misskey.io 358
mastodon.cloud 331
cybre.space 253
mstdn.guru 215
octodon.social 202
mastodon.technology 199
baraag.net 198
niu.moe 192
imastodon.net 187
mstdn.io 177
fedibird.com 164
mstdn.beer 159
mastodon.xyz 155
mamot.fr 150

故障発生状況

2019年に発生した主な故障は以下の通りです。

発生日時 復旧日時 故障内容 原因 再発防止 リンク
1/15 23:47 1/15 23:54 緊急メンテ 設定誤り 検証環境との差分があったため修正 link
7/11 21:28 7/11 21:52 TL表示遅延 tootleサーバのスタック Mastodon本体ソース修正 link
9/21 05:45 9/22 20:10 一部ユーザでTL表示が遅い Mastodon本体DB関連のバグ 影響極小化のためログ監視強化 link
11/19 15:05 11/19 19:02 特定の画像が表示されない 利用中クラウドサービスのIPアドレス変更 自動追従できるよう設定変更 link
11/27 22:46 11/27 23:34 全体的に動作が重い 大量動画投稿による負荷集中 影響極小化のためログ監視強化 link

今年も多々ご迷惑をおかけしました。いずれの故障についても再発防止または発生時の影響極小化に取り組みたいと思います。また,故障発生時の迅速な情報提供に努めるよう努力したつもりですが,なにかご意見があれば是非頂ければと思います。

特に9/21〜9/22の故障では,多くのご迷惑をおかけしたかと思います。技術的には,アップデートによりソフトウェアバグが混入してしまい,DB検索時のindexが正しく選択されないという問題でした。一定の負荷をかけないと顕在化しない問題のため,検証環境での試験段階で気づけませんでした。本件については,後でお話ししますが,副管理人として運営に協力いただいているのんさんのおかげで迅速に解決出来たと思っています。とても助かりました。なお,この問題は,結果として本家Githubでもissueとして扱われました

また,7/11の故障もよく覚えています。tootleの通知を受け取るサーバがスタックしてしまい,結果としてはんドンクラブにおいても重要なTL配送処理が全て遅延してしまった,という故障です。本件は,そもそもソフトウェア実装がいけてないのが原因の一つでしたので,修正のうえ 本家Githubのソースコードにも反映しました。実際に運営していないと分からない課題をgithubへフィードバックできたよい例かと考えています。

その他運営振り返り

  • 主なバージョンアップ/サーバ変更作業

2019年は,待望のv3.0.0がリリースされたのが最も記憶に残っているところでしょうか。その他,サーバ管理者観点では,様々なイベントがありました。主な作業履歴とバージョンアップ履歴をまとめておきます(この他にもメンテナンスやマイナーバージョンアップやを実施していますが,主要でないものは本表からは除外しました)。

日付 イベント内容 主な新機能
1/4 全文検索サーバの運用開始 全文検索
1/9 v2.7アップデート(rc1) ディレクトリ機能
3/7 利用規約の改定 -
3/30 v2.8アップデート (rc1) 投票(アンケート)機能
6/2 大規模メンテナンス(postgre 9→11 へのver. up) -
6/10 v2.9アップデート(rc1) シングルカラムUI
9/25 v3.0アップデート カスタム絵文字のカテゴリ機能など多数
  • 副管理人

9月頃より,副管理人としてのんさんに運営にご協力いただきました。主には,私が死んだときのバックアップと,技術的な困りごとの相談相手になってもらっています。とても助かっています。この場を借りて御礼申し上げます。

実はまだサーバの権限関係をきちんと委譲できていないので,これは私の正月の宿題としたいと思います。なお,2人で議論した結果,副管理人はDBへのアクセスを禁止する方向で進めたいと思っています(システム的に難しい場合,ログ監視により不正を取り締まれる状態にする方向で進めると思います)。

今後の展望

2020年以降も引き続き頑張って運営していきます。是非,安心して利用頂ければと思います。

なお,サーバについては一部増強も予定していますが,負荷を監視しつつ増強タイミングを判断したいと思います。その他,いくつか時限爆弾を持っていますので,実施しなくてはならないメンテナンスもあります。継続して安定運用に努めたいと思います。

と,いうことで。2020年も引き続きはんドンクラブをご利用頂き,盛り上げて頂けると嬉しいです! 最後になりましたが,はんドンクラブの全てのユーザと,Mastodon開発コミュニティで活動されている皆様に感謝します。おかげで2019年も楽しい1年になりました。よいお年を!

ユーザへの運営情報の配信チャネルについて

この記事について

この記事は 分散SNS Advent Calendar 2019 - Adventar の記事として 12/13(金)に公開される予定の記事でした。

※ インフルエンザの発症で長いこと寝込んでしまい,大遅刻しました。申し訳ありません。

サーバ運営の悩み

こんにちは。はんドンクラブ 管理人の @highemerly@handon.club です。はんドンクラブはあまり名の知れたサーバではありませんが,実はそこそこアクティブなMastodonサーバです。今日は,このはんドンクラブの運営において悩んでいる,運営者からユーザに対して運営情報を周知する方法(周知チャネル)についてお話できればと思います。

Mastodon前提で記載している箇所もありますが,原則他の分散SNSでも同じことが言えるかと思います(というか,"分散" SNSに限った話ではない気もしますが・・・)。

運営情報の周知チャネル

サーバの管理者であれば,サーバに関する運営情報,例えば以下のような情報をユーザへ配信したい場合があるかと思います。

  • メンテナンスの予告
  • 実施したアップデートの情報
  • 故障発生の第一報
  • 運営方針に関するヒアリング,アンケート
  • 利用規約の変更

しかし,Mastodonが元々持っている機能の範囲では,こういった情報を伝達するために用意された手段(チャネル)はありません。そのため現実的には,サーバ管理者が自分のアカウントで発言するなどの代替手段を取っている場合が多いのではないでしょうか。ただ,この代替手段について,なかなかベストな案は無いよね・・・というのが悩みであり,この記事の議論点です。

候補1: サーバ管理者のアカウントでの発言

単に管理者がトゥートするだけです。最もシンプルなチャネルであり,管理者の作業負担も少ないです。しかし,サーバにアカウントを持つ人は必ずしも管理者をフォローしているわけではありません。一定規模以上のサーバになると,必ずしもよい手段ではないように思います。

なお,候補1の派生案として,専用のハッシュタグを作り,ユーザにはそのハッシュタグの検索結果を見てもらう方法も考えられます。また,運営情報配信の専用アカウントを作り,かつ強制フォローさせるというやり方もあります。

候補2: 専用Webページ/ブログでの告知

はんドンクラブにおけるこのブログのことです。過去の履歴を追いやすい点が最大のメリットかと思います。ただ,そもそもこの専用ブログ等へユーザを誘導する必要がありますので,結局サーバ管理者のアカウントで告知するケースが多いと思われます。また,緊急周知には適さないと思われます。

候補3: 独自機能によるWebページ(投稿欄下)での表示

いくつかのMastodonサーバで導入されている独自機能で,投稿欄下に管理者からのお知らせ表示することができる機能があります。これを活用する方法です。Webを使っているユーザにはかなり確実にリーチできる一方,サードパーティクライアントしか使わないユーザには一切気づかれないという欠点があります。

候補4: メール

シンプルに,メールを送りつける方法です。ユーザはメールアドレスを登録していることから,有効な手段になるかと思います。とはいえ,実際には読まないユーザも多数いるでしょう。さらに,管理者にとってはとても手間です*1

候補のまとめ

ということでまとめるとこんな感じでしょうか。

ユーザの網羅度 作業負担 速報性 アーカイブ,検索性
1. 管理者の発言 △(管理者のフォロー要)
2. 専用ページ △(誘導要)
3. 投稿欄下 △(Webユーザのみ) ×
4. メール

特に重要なのはユーザの網羅度かと思います。なお,「メールはどうせ読まないユーザもいるので〇ではないのでは」とヤジが飛んできそうですが,一応全員に届くはずなので,比較表上は〇にしました。

ではどうするか

結局は 複数のチャネルを使って告知することでできるだけ多くのユーザに届く努力をする ことしかありません。まあ最初から分かってたことですが。

現在のはんドンクラブでは,候補1の「管理者の発言(ハッシュタグつき)」・候補2の「専用ブログ」・候補3の「投稿欄下表示」の3つのチャネルを使って周知することが多いです。実際にユーザにアンケートを取ってみたところ,どのチャネルも一定数使われているようでした。

※ そもそもこのアンケートが「管理者の発言」により開始されたものであり,そのバイアスがかかっている可能性は大いにあります。

ただ,3つのチャネルで告知するのって結構大変なんですよね。そのため,アップデートの情報や故障情報は確実に周知したいので複数チャネルを使っていますが,他の情報の場合はサボっている場合が多いです。

もし管理者の方で「もっと良い方法あるよ!」というご意見があれば,是非教えて頂けると嬉しいなーと思っています。それでは。

*1:プライバシーポリシーで予め,メールアドレスの利用目的に「運営情報の配信」を加えておかなくてはなりません

【完了】【メンテナンス】12/7 サービスの停止を伴うメンテナンスを実施します

本日以下の日程でメンテナンスを実施します。期間中は全てのサービスが利用出来ません。ご迷惑をおかけして申し訳ございませんがご協力お願いします。

13:44追記: メンテナンスは予定通り終了しました。13:30:24 〜 13:39:20 の 8分56秒間サービスが停止しました。

  • 日時: 2019/12/7(土) 13:30〜13:45
  • 影響範囲: 全サービス
  • 理由: 各種セキュリティアップデートのため

【障害発生・復旧報】サーバに接続しづらい問題が発生していました

はんドンクラブにおいて,以下の障害が発生していましたが,現在は復旧しています。ご迷惑をおかけしたことをお詫びいたします。

  • 日時: 2019年11月27日(水) 22:46 〜23:34 (JST)
  • 影響範囲: はんドンクラブの全ユーザ
  • 障害内容: レスポンスが悪いため,アクセス困難な状態になる(Web・API経由いずれも)
  • 原因:大容量動画投稿による処理遅延の発生
  • 解決方法: 自然回復

根本原因

mastodonでは,動画が投稿された際,ffmpegによる動画ファイルの再エンコードが行われます。(おそらくffmpeg側の不具合で)ffmpegがCPUリソースをほぼ100%使い果たしてしまい,結果的に他の処理ができなくなってしまいました。なお,ffmpegはwebデーモン(bundle exec puma)から呼び出されるため,今回CPUリソースをほぼ100%使い果たしてしまったのはwebサーバのみです。

根拠ですが,実はれっきとした証拠はつかめていません。客観的に見てその可能性が高いと判断した,ということになります。

その詳細を説明します。はんドンクラブにある2台のwebサーバはDNSラウンドロビンにより負荷分散されています。今回,2台のwebサーバのCPU利用率の高騰が開始した直前に,いずれのサーバにも全く同じ動画が投稿されていました。なぜ2台のwebサーバに同じ動画の投稿がリクエストされたかは分かりませんが,3rd party製クライアントで動画アップロードを試みたものの失敗したためリトライ処理が行われ,その際にたまたまDNSTTLが切れた可能性があります。この状況から,原因を推測しました。

今回の対処方法

自然回復しました。

今後の対処方針,改善点

再発防止策は現状分かっておらず,再発の可能性は十分にあります。

nginx設定の変更

根本対処にはなりませんが,今後大容量なファイルができるかぎりアップロードされないよう,リバースプロキシ(nginx)側でアップロードファイルサイズの上限を制限しました。この対処により,ffmpegに動画を渡す前にあまりに容量の大きな動画はrejectできますので,今回と同様の事象の発生確率は下げられるものと推察します。

  • Before
  client_max_body_size 80m;
  • After
  client_max_body_size 50m;

なお,念のため述べておきますが,コンフィグ中の「50MB」というのは,「アップロード時に受け付けるサイズの上限値」であり,「実際にはんドンクラブサーバに格納される場合のサイズの上限値」ではありません。ffmpeg等により再エンコード/リサイズされるため,実際には数MB程度にまで圧縮されています。

アラート発報閾値の見直し

はんドンクラブでは,prometheus+grafanaを使った常時監視を行っています。さらに,アラートが発生すると管理者全員にLINEで通知される仕組みとなっています。しかし今回は,実際にサービス影響が出始めてからGrafanaのアラート発報まで10分程度要してしまいました。一部の閾値を見直し,より早く気づけるように修正を行いました。

本件が発生した環境

対応時系列

特に意味はないかもしれませんが,今回の対応時系列を公開します。

2019年11月27日

  • 22:46:30頃 web1サーバ CPU利用率高騰開始
  • 22:46:45頃 HTTPレスポンス警戒域
  • 22:48:30頃 web2サーバ CPU利用率高騰開始
  • 22:48:59 dbサーバ pbouncer でのエラー多発( .env.production のuser名/db名設定が無効化される )
  • 22:49:04 web2サーバ rack_attack.rb での API レートリミットが多発
  • 22:49:15頃 web1サーバ CPU利用率警戒域(60%超)
  • 22:51:50頃 web2サーバ CPU利用率警戒域(60%超)
  • 22:54:01 監視サーバからのHTTPレスポンス警報が発報,管理者へLINE通知
  • 22:55:16 監視サーバからのCPU利用率警報が発報,管理者へLINE通知
  • 22:55:19 web2サーバ rack_attack.rb での API レートリミットが多発
  • 23:30頃 管理者による対応開始
  • 23:32:15頃 web1,2サーバ共にCPU利用率の低下開始
  • 23:34:35頃 HTTPレスポンス 通常値に復旧
  • 23:36:15頃 web1サーバ CPU利用率 定常レベルに改善
  • 23:38:15頃 web2サーバ CPU利用率 定常レベルに改善
  • 23:41頃 管理人により障害発生第一報の正式周知

2019年11月28日

  • 00:33頃 管理者によりあらかたの原因が発覚
  • 01:14頃 管理人により障害発生・復旧報(最終報)の正式周知

【追記あり】【障害発生・復旧報】一部画像が正常に表示されない不具合が発生していました

はんドンクラブにおいて,以下の障害が発生していましたが,現在は復旧しています。ご迷惑をおかけしたことをお詫びいたします。

  • 日時: 2019年11月19日 15:05:13 〜 2019年11月19日 19:02:19 (JST)
  • 影響範囲: はんドンクラブの全ユーザ
  • 障害内容: 特定の画像が表示されない
  • 原因:Webサーバ設定が不適切であり,利用している外部サービスのIPアドレス変更に追従できなかったため
  • 解決方法: 暫定的にはWebサーバの再起動で回復済。本格対処は11月21日までに実施予定 11月20日23:50頃に本格対処完了

障害の発生メカニズム

はんドンクラブでは,メディア(トゥートに添付された画像や動画,またはアイコン画像など)は,Conohaのオブジェクトストレージに保存されています。このオブジェクトストレージ内のメディアへのアクセス用URLをWebページのドメイン(handon.club)と同一ドメイン(media.handon.club)にするため,はんドンクラブサーバ内のnginxでリバースプロキシを使っています。

media.handon.club における nginx.conf は,以下のようになっていました(一部抜粋)。

server {
  listen 443 ssl http2;
  listen [::]:443 ssl http2;
  server_name media.handon.club;
  ~~~中略~~~
  add_header Cache-Control "public, max-age=31536000, immutable";
  location / {
    proxy_pass https://object-storage.tyo2.conoha.io/v1/xxxxxxx/xxxxxxx/;
    ~~~中略~~~
  }
}

よく知られた問題として,proxy_passドメインを書いた場合,nginxの起動時にのみ名前解決が行われます。そのため,nginx起動後にDNSレコードの変更があった場合でも,OS側のTTL設定に依らず,レコード変更に追従することができません。つまり,手動でnginxを再起動するまで,永遠に古いDNSレコードが使われつづけてしまいます。

ktrysmt.github.io

今回の障害の原因については,前述のnginxの仕様により,オブジェクトストレージのグローバルIPアドレス変更に追従できなかったためです。conoha側で何らかの理由で object-storage.tyo2.conoha.ioIPアドレスが変更されましたが,はんドンクラブのnginxは古いIPアドレスへアクセスし続けてしまうため,結果としてユーザが画像を表示できない状態になっていました。

なお,古い画像には通常通りアクセスできていました。これは, media.handon.club が CDN によりキャッシュされているためです。前述の nginx.conf のとおり,一度アクセスした画像は,最大で31,536,000秒間CDNサービスのCloudflareにキャッシュされます(あれ,そういえば,Cloudflareってこのヘッダをちゃんと尊重してくれるんでしたっけ??)。そのため,キャッシュされているアイコン画像や古いトゥートに添付された画像はアクセスが出来るが,1度もアクセスがなかった画像にはアクセスができなかった・・・・ということになります。

なお管理人は,この proxy_pass の挙動について認識こそしていたものの,正しくない設定をしてしまいました。原因は,media.handon.club サーバについてはあまり深く考えずに各種設定を行っており,チェック漏れが発生したためです。要するに管理人の凡ミスです。

障害に気づくのが遅れた理由

今回の障害はユーザ申告により発覚しました。そのため,管理人が問題を把握したのは問題発生から3時間以上経過した18:30頃でした。こちらの原因について説明します。

はんドンクラブでは,media.handon.club については,1分に1回HTTPSリクエストを送ることで死活監視を行っています。そして,連続してアクセスエラーが発生すると,管理人と副管理人のLINEに通知される仕組みとなっています。そのため,サーバ障害に対しては速やかにその発生を認知出来るはずでした。

しかし,この死活監視は,常に同じエンドポイントに対して実施していました。そのため,当然CDNにキャッシュされているページに対して死活監視していたことになります。そのため,今回のように,新たにアップロードされている画像に限定して再現する障害では,アラートが上がらない状態となっていました。

今後の改善

  • nginx.conf については修正を行います。
    • 変数を介することでDNSレコードのTTLが設定出来るという(不思議な)手法があるため,これを適用します
    • 検証環境での動作確認を行う必要があるため,11/21(木)までの本番設定変更を目標に準備を進めます 適用済です
  • 死活監視方法の変更による早期障害検知は現実的ではないため,リスクを許容することとします。
    • 新しくアップロードされた画像に対するポーリング監視は,適切なエンドポイントが分からないため現実的ではありません
    • ただし,長期的には,ユーザの申告をより簡単かつ速やかに受け付けられる仕組みを検討し,リスクを軽減します

(11/20追記)以下のように設定変更しました。

server {
  listen 443 ssl http2;
  listen [::]:443 ssl http2;
  server_name media.handon.club;
  ~~~中略~~~
  add_header Cache-Control "public, max-age=31536000, immutable";

  location ~ /(.*) {
    resolver 8.8.4.4 1.0.0.1 valid=360s;
    set $container "object-storage.tyo2.conoha.io/v1/xxxxxxx/xxxxxxx";
    proxy_pass https://$container/$1$is_args$args;
    ~~~中略~~~
  }
}