こんにちは。運営ブログの更新が滞っている、はんドンクラブ管理人のはんです。たまには何か書こうと思い立ちました。
この記事では、はんドンクラブにおけるデータの可用性ポリシーについてまとめておこうと思います。可用性(アベイラビリティ)とは、システムを故障なく継続して動かせる能力のことです。ただ、はんドンクラブを構成するすべての要素の可用性について書くのはとても大変です。そこで今回は、特に重要なデータベースの可用性、特にバックアップのポリシーについてご紹介したいと思います。
はんドンクラブの利用サービス
はんドンクラブでは、サービス開始当初から、「私の家にサーバを設置する構成(オンプレ構成)は取らない」というポリシーを貫いています。様々な理由がありますが、一番の理由はセキュリティです。オンプレ構成の場合、データ漏洩リスクとして「私の家に強盗が入る」「私の家に来た友人が不正を働きデータを盗む*1」ことを考慮しなくてはならず、設計や運用の負担になることが予想されます。
もちろん、可用性の向上という観点でも、クラウドサービスを使う利点はあります。残念なことに私はデータセンターには住んでおりませんので、家庭向けインターネットアクセス回線や家庭向け商用電源の可用性を考慮しなくてはなりません。面倒すぎます。
さて、前置きが長くなりました。利用しているクラウドサービスの可用性について考えたいと思います。はんドンクラブでは主に以下のサービスを利用しています。
- さくらインターネット(さくらVPS)
- GMO(Conoha)
- SendGrid
- CloudFlare
このうち、データが保管されており、データという観点で可用性を考慮する必要があるサービスはさくらインターネットとGMOの2つです。いずれも日本国内に設置されたサーバのみを利用しており、十分な可用性が担保されていると認識しています。そのため、そもそもこれらのサービスを利用している時点で、不意の故障に起因する可用性の低下について神経質に考える必要はないというのが実情です。 ここで、不意の故障とは、電源喪失やネットワーク切断などインフラ面の故障を指しています。
さくらのVPSの特長|VPS(仮想専用サーバー)はさくらインターネット
とはいえ、これはあくまで設備故障に起因する可用性の話です。私のオペレーションミス、ソフトウェアのバグに起因したデータロストなど、ソフトウェア的なリスクは考慮すべきです。このリスク軽減のためには「定時の自動バックアップ」が有効です。以後はデータのバックアップについて考えていこうと思います。
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東京リージョンがすべて故障した場合
- 大規模災害等で東京中のインフラが壊滅状態の場合
- 復旧目標: 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分以内に気づけるようになっているので、仕事中など即時対応できる状況であれば誤差の範囲です。