6月5日までに発生した障害について、障害の内容と再発防止策をお知らせします。
※社内サービス名などの社内用語は一般的な言葉に置き換えています。
5月30日【ユーザーフォロー】ユーザーフォローに失敗する 等
■ 障害発生時間
2018年5月30日14時30分ごろ ~ 2018年5月30日19時40分ごろ
■ 障害の発生したシステム
リレーションデータベース基盤
■ 障害の影響が波及したシステム
ユーザーフォロー基盤, 通知連携基盤
■ 障害の内容
特定のユーザーによる攻撃的なアクセス(過剰なユーザーフォロー状態の操作)によって、ユーザーフォロー基盤が利用しているリレーションデータベース基盤が過負荷状態に陥りました。
その結果、ユーザーフォロー基盤をはじめとした、リレーションデータベース基盤を利用するサービスが正常に利用できない状態になりました。
■ ユーザー影響
・ユーザーフォローの表示に関する不具合
- フォローしている数が表示されない
- フォローされている数が表示されない
- フォローユーザーの一覧が表示されない
・ユーザーフォローの新規設定/解除が行えない
■ タイムライン
・14時30分 リレーションデータベース基盤の過負荷を検知し、調査を開始しました。
・14時46分 ユーザーフォロー基盤のAPIが高負荷になっていたことから、該当APIを一時的にメンテナンス状態にし、応答を停止させました。
これによりリレーションデータベース基盤の負荷は落ち着きましたが、外部からの攻撃的なアクセスは継続していました。従って、このままメンテナンス状態を解除しても再度過負荷に陥ることが予想されたため、さらなる調査と対策の検討を進めました。
・16時45分 アクセス内容を精査した結果、ユーザーフォロー基盤のAPIのうち、一部のAPIについてはメンテナンス状態を終了させても負荷面の問題が無いと判断し、メンテナンス状態を終了させました。
・19時35分 ユーザーフォロー基盤のAPIにアクセス回数制限機能を緊急で実装しました。これにより負荷が一定以上に高まらないように制御できると判断し、ユーザーフォロー基盤全体のメンテナンス状態を終了させました。
■ 再発防止策
・ユーザーフォロー基盤にアクセス回数制限機能を追加します(実施済み)
・ユーザーフォロー基盤に、過負荷状態に耐えられるようにキャッシュを追加します。
・より多くのアクセスに耐えられるように、リレーションデータベース基盤のチューニングやアーキテクチャ変更を検討します。
2018年5月30日14時30分ごろ ~ 2018年5月30日19時40分ごろ
■ 障害の発生したシステム
リレーションデータベース基盤
■ 障害の影響が波及したシステム
ユーザーフォロー基盤, 通知連携基盤
■ 障害の内容
特定のユーザーによる攻撃的なアクセス(過剰なユーザーフォロー状態の操作)によって、ユーザーフォロー基盤が利用しているリレーションデータベース基盤が過負荷状態に陥りました。
その結果、ユーザーフォロー基盤をはじめとした、リレーションデータベース基盤を利用するサービスが正常に利用できない状態になりました。
■ ユーザー影響
・ユーザーフォローの表示に関する不具合
- フォローしている数が表示されない
- フォローされている数が表示されない
- フォローユーザーの一覧が表示されない
・ユーザーフォローの新規設定/解除が行えない
■ タイムライン
・14時30分 リレーションデータベース基盤の過負荷を検知し、調査を開始しました。
・14時46分 ユーザーフォロー基盤のAPIが高負荷になっていたことから、該当APIを一時的にメンテナンス状態にし、応答を停止させました。
これによりリレーションデータベース基盤の負荷は落ち着きましたが、外部からの攻撃的なアクセスは継続していました。従って、このままメンテナンス状態を解除しても再度過負荷に陥ることが予想されたため、さらなる調査と対策の検討を進めました。
・16時45分 アクセス内容を精査した結果、ユーザーフォロー基盤のAPIのうち、一部のAPIについてはメンテナンス状態を終了させても負荷面の問題が無いと判断し、メンテナンス状態を終了させました。
・19時35分 ユーザーフォロー基盤のAPIにアクセス回数制限機能を緊急で実装しました。これにより負荷が一定以上に高まらないように制御できると判断し、ユーザーフォロー基盤全体のメンテナンス状態を終了させました。
■ 再発防止策
・ユーザーフォロー基盤にアクセス回数制限機能を追加します(実施済み)
・ユーザーフォロー基盤に、過負荷状態に耐えられるようにキャッシュを追加します。
・より多くのアクセスに耐えられるように、リレーションデータベース基盤のチューニングやアーキテクチャ変更を検討します。
5月31日【生放送】一部の番組において、モバイルデバイスの一部での視聴、およびタイムシフト視聴ができなくなった
■ 障害発生時間
2018年5月31日21時0分ごろ ~ 2018年5月31日21時3分ごろ
■ 障害の発生したシステム
旧生放送システム ドワンゴ社内向けAPI
■ 障害の影響が波及したシステム
新配信システム、旧生放送配信システム、特殊端末向けトランスコードシステム
■ 障害の内容
ニコニコ生放送は、老朽化した生放送システムを刷新するために、新生放送システムを開発しました。旧生放送システムを保守しながら新生放送システムを開発し、徐々に移行を進めています。
旧生放送システムが提供するドワンゴ社内向けAPIのなかに、番組情報を取得するために古くから使われている番組情報取得APIがあります。
同等のAPIは新生放送システムにも実装されており、各サービスにおいて徐々に移行を進めているのですが、旧生放送システムの社内向けAPIにもまだ利用サービスがいる状態です。
旧生放送システムの社内向けAPIについて、これまでは利用する側のサービスが各自キャッシュをしていました。負荷対策という面ではそれで問題なかったのですが、生放送側にキャッシュを移設すればメンテナンスコストを集約して削減できること、またキャッシュ制御を生放送側で柔軟に行えるようになり、サービス品質の向上が見込めることから、旧生放送システムの社内向けAPIにキャッシュシステムを新設することになりました。
また、それとは別の話として、旧生放送システムの社内向けAPIでは、歴史的な理由から特殊なアクセスキーをURLに設定しないと利用できない状態になっていました。利用しづらいため、アクセスキーなしでも利用可能になるように、並行してリファクタリングを進めていました。
それぞれのアップデートが本番に反映されたのち、5月31日の19時ごろより、旧生放送システムの社内向けAPIの負荷が上昇していることが検知されました。調査したところ、上記2つのアップデートを行うチーム間で情報伝達に齟齬があり、「アクセスキーを含まない形で旧生放送システムの社内向けAPIにアクセスすると、キャッシュシステムが有効にならない」ことが判明しました。間の悪いことに、非ログイン視聴が可能な人気生放送番組が配信されていたため、常になく生放送視聴者が集まっており、このままでは過負荷によりニコニコ生放送システム全体が停止してしまうことが予想されました。
そこで、アクセスキーを含まない形でも旧生放送システムの社内向けAPIのキャッシュシステムが有効になる修正を作成し、本番に投入することにしました。ただし、旧生放送システムの社内向けAPIは無停止更新に対応していなかったため、数分程度APIの応答が応答が停止し、番組情報の編集や新規の生放送視聴開始ができなくなってしまうという問題がありました。しかし、生放送システム全体がダウンするよりは悪影響が少ないと考え、本番更新を実施しました。
その結果、旧生放送システムの社内向けAPIを本番更新している数分の間に番組情報を更新(番組の作成・開始・情報更新・終了・予約削除)を行った場合、関連システムとの連携が行われず、データに不整合が発生することになりました。
特に、該当時間中に番組を開始(作成ではない)をしていた場合、新配信システムの番組情報更新がうまく行われず、新配信システムから旧生放送配信システムへの番組開始通知が届きませんでした。
その結果、該当番組において、番組そのものは正常に配信・視聴できるものの、旧生放送配信システムを利用するタイムシフト録画などの一部生放送機能が正常に動作しない状態になってしまいました。
■ ユーザー影響
該当時間中に配信を開始した生放送番組において、旧生放送配信システムを利用する機能(タイムシフト録画や、特殊端末向けトランスコードシステムを経由した視聴(Playstation Vitaアプリでの生放送視聴など))ができない。
■ タイムライン
5月31日 19時2分 旧生放送システムの社内向けAPIの負荷が上昇していることに気づく
5月31日 19時10分 負荷上昇の原因がキャッシュシステムの不備であることが判明
5月31日 19時15分 負荷上昇を誘発している番組を発見し、今後も負荷が上昇しつづける可能性が高いことが判明
5月31日 21時0分ごろ キャッシュシステムの更新パッチを作成し、本番更新した
5月31日 21時3分ごろ キャッシュシステムの本番更新が完了した
■ 再発防止策
・ニコニコ生放送は巨大なシステムであり、複数のチームが協同して開発を行っています。意図しない副作用の発生を防ぐため、設計レビューをより綿密に開催し、チーム間の情報共有を密にするように心がけます。
・今回の障害の引き金となった旧生放送システムの社内向けAPIについて無停止更新ができるよう改修を進めるとともに、無停止更新が可能な新生放送システムへの移行を推し進めます。
2018年5月31日21時0分ごろ ~ 2018年5月31日21時3分ごろ
■ 障害の発生したシステム
旧生放送システム ドワンゴ社内向けAPI
■ 障害の影響が波及したシステム
新配信システム、旧生放送配信システム、特殊端末向けトランスコードシステム
■ 障害の内容
ニコニコ生放送は、老朽化した生放送システムを刷新するために、新生放送システムを開発しました。旧生放送システムを保守しながら新生放送システムを開発し、徐々に移行を進めています。
旧生放送システムが提供するドワンゴ社内向けAPIのなかに、番組情報を取得するために古くから使われている番組情報取得APIがあります。
同等のAPIは新生放送システムにも実装されており、各サービスにおいて徐々に移行を進めているのですが、旧生放送システムの社内向けAPIにもまだ利用サービスがいる状態です。
旧生放送システムの社内向けAPIについて、これまでは利用する側のサービスが各自キャッシュをしていました。負荷対策という面ではそれで問題なかったのですが、生放送側にキャッシュを移設すればメンテナンスコストを集約して削減できること、またキャッシュ制御を生放送側で柔軟に行えるようになり、サービス品質の向上が見込めることから、旧生放送システムの社内向けAPIにキャッシュシステムを新設することになりました。
また、それとは別の話として、旧生放送システムの社内向けAPIでは、歴史的な理由から特殊なアクセスキーをURLに設定しないと利用できない状態になっていました。利用しづらいため、アクセスキーなしでも利用可能になるように、並行してリファクタリングを進めていました。
それぞれのアップデートが本番に反映されたのち、5月31日の19時ごろより、旧生放送システムの社内向けAPIの負荷が上昇していることが検知されました。調査したところ、上記2つのアップデートを行うチーム間で情報伝達に齟齬があり、「アクセスキーを含まない形で旧生放送システムの社内向けAPIにアクセスすると、キャッシュシステムが有効にならない」ことが判明しました。間の悪いことに、非ログイン視聴が可能な人気生放送番組が配信されていたため、常になく生放送視聴者が集まっており、このままでは過負荷によりニコニコ生放送システム全体が停止してしまうことが予想されました。
そこで、アクセスキーを含まない形でも旧生放送システムの社内向けAPIのキャッシュシステムが有効になる修正を作成し、本番に投入することにしました。ただし、旧生放送システムの社内向けAPIは無停止更新に対応していなかったため、数分程度APIの応答が応答が停止し、番組情報の編集や新規の生放送視聴開始ができなくなってしまうという問題がありました。しかし、生放送システム全体がダウンするよりは悪影響が少ないと考え、本番更新を実施しました。
その結果、旧生放送システムの社内向けAPIを本番更新している数分の間に番組情報を更新(番組の作成・開始・情報更新・終了・予約削除)を行った場合、関連システムとの連携が行われず、データに不整合が発生することになりました。
特に、該当時間中に番組を開始(作成ではない)をしていた場合、新配信システムの番組情報更新がうまく行われず、新配信システムから旧生放送配信システムへの番組開始通知が届きませんでした。
その結果、該当番組において、番組そのものは正常に配信・視聴できるものの、旧生放送配信システムを利用するタイムシフト録画などの一部生放送機能が正常に動作しない状態になってしまいました。
■ ユーザー影響
該当時間中に配信を開始した生放送番組において、旧生放送配信システムを利用する機能(タイムシフト録画や、特殊端末向けトランスコードシステムを経由した視聴(Playstation Vitaアプリでの生放送視聴など))ができない。
■ タイムライン
5月31日 19時2分 旧生放送システムの社内向けAPIの負荷が上昇していることに気づく
5月31日 19時10分 負荷上昇の原因がキャッシュシステムの不備であることが判明
5月31日 19時15分 負荷上昇を誘発している番組を発見し、今後も負荷が上昇しつづける可能性が高いことが判明
5月31日 21時0分ごろ キャッシュシステムの更新パッチを作成し、本番更新した
5月31日 21時3分ごろ キャッシュシステムの本番更新が完了した
■ 再発防止策
・ニコニコ生放送は巨大なシステムであり、複数のチームが協同して開発を行っています。意図しない副作用の発生を防ぐため、設計レビューをより綿密に開催し、チーム間の情報共有を密にするように心がけます。
・今回の障害の引き金となった旧生放送システムの社内向けAPIについて無停止更新ができるよう改修を進めるとともに、無停止更新が可能な新生放送システムへの移行を推し進めます。
6月2日~6月5日【ユーザー生放送・チャンネル生放送】新規に生放送の配信ページを開くことができない。また、配信開始に失敗する。
■ 障害発生時間
2018年6月2日 21時40分頃 ~ 2018年6月2日 22時26分頃
2018年6月3日 20時00分頃 ~ 2018年6月3日 20時17分頃
2018年6月4日 20時15分頃 ~ 2018年6月4日 20時21分頃
2018年6月5日 6時10分頃 ~ 2018年6月5日 7時15分頃
2018年6月5日 20時44分頃 ~2018年6月5日 21時35分頃
■ 障害の発生したシステム
新生放送システム 番組情報データベースクラスタ
■ 障害の影響が波及したシステム
ニコニコ生放送(ユーザー生放送、チャンネル生放送)
■ 障害の内容
2018年2月、チャンネル生放送が新配信システムおよび新生放送システムに移行しました。これにともなって、チャンネル生放送の統計情報を集計するサービスも新生放送システムに移行したのですが、このサービスには番組情報データベースを過剰に利用し、データベースサーバのメモリを過剰に消費するバグがありました。複数回の修正を行い、メモリの過剰消費は止まりましたが、すでに消費されてしまったメモリは解放されず、swap使用量も危険な水準に近づいていました。
ただし、「メモリ使用量が危険域にあるとはいえ、サービス自体は正常に稼動していること」「問題を解消するにはデータベースプロセス自体を再起動する必要があること。そのためにはニコニコ生放送全体の停止メンテナンスが必要になること」「6月7日にニコニコ全体停止メンテナンスが予定されていること」から、すぐには停止メンテナンスを行わず、6月7日の全体停止メンテナンスでメモリ増設を含めた対策を行う予定でした。
6月2日 21時40分ごろ、夜間のピーク時間の負荷に耐えられず、Master(書き込み処理)を担っていたDBサーバ(DB01)がダウンしました。データベースクラスタにはフェイルオーバーが設定されていたため、Masterサーバがダウンしたのち、30秒以内に自動的にSlaveサーバ(読み出し処理用サーバ)の一台(DB02)がMasterに昇格し、システム全体としての可用性は維持されました。
ただし、Masterサーバのダウンを検知してからフェイルオーバーが完了するまでの15秒~30秒の間は、番組を作成することができませんでした。
同日22時ごろ、番組開始にともなう負荷の上昇に耐えきれず、新しくMasterの役割を担ったDBサーバ(DB02)の動作が不安定になりました。特に、該当サーバにMasterの役割が移行したあとも、Slaveとしての役割も同時に果たしつづけたため、ディスクI/Oが飽和し、読みこみ・書き込みともに非常に遅い状態が発生しました。
その結果、視聴が開始しづらく、番組を作成しづらい(非常に時間が掛かる、またはタイムアウトする)状況が発生しました。アクセスの主たる要因は生放送番組判定APIだったため、APIのキャッシュが貯まってキャッシュヒット率が上昇するつれ、時間の経過と共にデータベースへのアクセスが減少し、22時26分ごろに過負荷が解消されました。
同日深夜、同様の障害を避けるため、ダウンした旧Master機(DB01)にメモリを増設したうえでSlaveDBとしてクラスタに再参加させ、再度の障害が発生したときには旧Master機(DB01)にMasterの役割が戻るように設定を行いました。また、開発機として利用していたデータベースサーバ(DB04)にも、念のためにメモリの増設を行いました。
6月3日 20時ごろ、番組開始にともなう負荷の上昇により、新しくMasterの役割を担ったデータベースサーバ(DB02)の動作が不安定になり、応答が遅延するようになりました。ただし、サーバ自体がダウンするにはいたらず、20時17分ごろに負荷は落ち着きました。
ニコニコ生放送は、0分や30分といった区切りのよい時間から番組が放送されることが多いため、このままでは21時にまた負荷でサーバが不安定になることが予測されました。そこで、新しくMasterの役割を担ったデータベースサーバ(DB02)からSlaveの役割を外す設定変更を行いました。同時に、開発機だったサーバをSlaveとしてDBクラスタに追加し、正常なクラスタ台数に戻しました。
6月4日の15時30分ごろから、対策検討会が開かれました。その結果、データベースサーバのメモリ不足を、サービス停止なしで安全に解消する方法がないことが判明しました。できるだけ早いタイミングで停止メンテナンスを行うことが合意されましたが、同日夜にかけて多くの番組が放送される予定であること、旧Masterサーバ(DB01)がメモリ不足に陥ってから72時間以上安全にサービスを提供していた事実に鑑み、6月5日の午前6時から停止メンテナンスを実施することになりました。
このとき、少しでも停止メンテナンスの時間を短くするために、DB01にMasterの役割を戻すフェイルオーバーだけを実施することにしました。
Slaveサーバのメモリを増設し、再起動してメモリを解放する作業は、必要であればクラスタ全体を停止させずに(クラスタからSlaveサーバを1台ずつ切り離して)行うことが可能だったので、停止メンテナンス中には作業をしないことにしました。Slaveサーバの対処をいつ行うかについては、6月5日の臨時停止メンテナンス後に検討することになりました。
6月4日 20時15分ごろ、夜間ピークタイムにともなう負荷上昇により、新しくMasterの役割を担ったDBサーバ(DB02)がダウンしました。
これにより自動的に旧Master機(DB01)にフェイルオーバーが行われ、クラスタ全体が健全な状態に復帰するはずでしたが、実際はフェイルオーバーが開始されるより前に、新しくMasterの役割を担ったDBサーバ(DB02)が自動的に再起動されてしまいました。このとき、書き込み禁止モードで再起動されたため、Masterサーバへの書き込みができなくなり、番組の作成ができなくなってしまいました。この状態は、20時21分ごろに手動で書き込み禁止モードを解除するまで続きました。
6月5日の6時から6時10分に早朝に短時間の臨時停止メンテナンスを行い、Masterサーバの役割を、メモリを増設した旧Master機(DB01)に戻しました。このとき、DB02をSlaveとして再参加させるためには手動でデータの整合を取る必要があるため、この時点ではクラスタに参加させませんでした。
しかし、メンテナンス終了後も、最大1/2の確率でユーザー生放送・チャンネル生放送番組の視聴が開始できない不具合が発生しました。
調査の結果、DB02を参照している設定が一部に残っていたためであると判明したため、設定を修正し、7時15分に障害がおさまりました。
6月5日の日中、Slaveの再起動をするべきか、するとしたらどのようにするか、を検討しました。
このとき、6月7日の停止メンテナンスにおいて、メモリ追加およびストレージのグレードアップがすでに計画されていたことから、予定通り停止メンテで作業したほうがよいのではないか、という判断になりました。
6月5日の20時44分ごろ、Slaveサーバの1台(DB03)がダウンしました。これにより、番組の新規視聴が一定の確率でできなくなってしまいました。DB03を使用しないように設定を変更し、20時55分ごろに状況が収束しました。
6月6日 13時から14時ごろ
アプリケーションの定期本番更新にともない、DB01をMasterに、DB02, DB03をSlaveに利用する通常の体制に戻りました。また、この時点で、DB01からDB03がすべてメモリ増設・再起動によるメモリ開放が完了した状態になりました。
■ ユーザー影響
生放送番組を視聴開始することが(一定の確率で)できない。
番組の配信ページへのアクセスにアクセスすることが(一定の確率で)できない。
■ タイムライン
5月30日以前 チャンネル生放送統計情報収集サービスがデータベースサーバのメモリを食い潰す問題を認識し、プログラムの改修を行った。しかし、すでに食い潰されたメモリは開放されず、通常時よりメモリが少ない状態が続いていた。
6月2日 21時40分ごろ データベースクラスタのMasterサーバ(DB01)がダウンし、フェイルオーバーが完了するまでの短時間(30秒以下)、番組作成ができない状態になった。フェイルオーバーは成功し、Slaveサーバの一台(DB02)がMasterに昇格し、サービスは正常な状態に戻った。
6月2日 22時ごろ 新しくMasterとなったサーバ(DB02)も負荷に耐えきれず、応答に長い時間がかかるようになった。その結果、視聴開始失敗や番組作成の失敗が発生するようになった。
6月2日 22時26分ごろ キャッシュヒット率上昇による負荷の自然減により、状況がいったん収束した。
6月3日 20時ごろ DB02が負荷に耐えきれず、応答に長い時間がかかるようになった。その結果、視聴開始失敗や番組作成の失敗が発生するようになった。
6月3日 20時17分ごろ キャッシュヒット率上昇による負荷の自然減により、状況がいったん収束した。
6月3日 20時30分ごろ DB02からSlaveの役割を外すとともに、開発機だったサーバを新しくSlaveとして利用できるように設定した。
6月4日 20時15分ごろ DB02が負荷上昇に耐えられずダウンした。フェイルオーバーが行われるはずであったが、フェイルオーバーに失敗し、さらに書き込み禁止モードで再起動されてしまった。これにより、番組の作成ができなくなってしまった。
6月4日 20時21分ごろ DB02の書き込み禁止モードを解除した。
6月5日 6時0分から6時10分 ユーザー生放送・チャンネル生放送の緊急メンテナンスを行い、メモリを増設したDB01にMasterの役割を戻した。
6月5日 6時10分 最大1/2の確率で生放送番組の視聴が開始できない不具合が発生した。
6月5日 7時15分 上記障害の原因が判明し、修正を行った。
6月5日 20時44分 Slaveサーバの1台(DB03)がダウンしたため、DB04にアプリケーションの参照先を変更する作業を開始した。
6月5日 20時55分 上記の影響が収束した。
6月6日 13時ごろ データベースクラスタが、DB01からDB03を使う正常な体制に戻り、障害が収束した。
■ 再発防止策
今回メモリ不足が発生したデータベースクラスタにおいて、メモリの増設を行う。(実施済み)
コネクション取得時に異常だった接続先情報をキャッシュし、接続先を判断することで、一部データベースサーバの異常によるリクエスト全体の失敗を防止するようアプリケーションを改修する。(実施済み)
サービスの追加開発など、新規にシステム負荷が増加するような本番変更を行う場合、CPU使用率・メモリ消費量などの負荷検証をより厳密に行うようにする。また、本番環境でのシステム負荷をより継続的・密に行えるような監視システムを導入し、特に新規のシステムが追加されたときには注意して見守るような監視体制を整える。
サービスを停止してでもメンテナンスを行うべきかどうかの判断は、状況を楽観視せず、より慎重に行うようにする。
2018年6月2日 21時40分頃 ~ 2018年6月2日 22時26分頃
2018年6月3日 20時00分頃 ~ 2018年6月3日 20時17分頃
2018年6月4日 20時15分頃 ~ 2018年6月4日 20時21分頃
2018年6月5日 6時10分頃 ~ 2018年6月5日 7時15分頃
2018年6月5日 20時44分頃 ~2018年6月5日 21時35分頃
■ 障害の発生したシステム
新生放送システム 番組情報データベースクラスタ
■ 障害の影響が波及したシステム
ニコニコ生放送(ユーザー生放送、チャンネル生放送)
■ 障害の内容
2018年2月、チャンネル生放送が新配信システムおよび新生放送システムに移行しました。これにともなって、チャンネル生放送の統計情報を集計するサービスも新生放送システムに移行したのですが、このサービスには番組情報データベースを過剰に利用し、データベースサーバのメモリを過剰に消費するバグがありました。複数回の修正を行い、メモリの過剰消費は止まりましたが、すでに消費されてしまったメモリは解放されず、swap使用量も危険な水準に近づいていました。
ただし、「メモリ使用量が危険域にあるとはいえ、サービス自体は正常に稼動していること」「問題を解消するにはデータベースプロセス自体を再起動する必要があること。そのためにはニコニコ生放送全体の停止メンテナンスが必要になること」「6月7日にニコニコ全体停止メンテナンスが予定されていること」から、すぐには停止メンテナンスを行わず、6月7日の全体停止メンテナンスでメモリ増設を含めた対策を行う予定でした。
6月2日 21時40分ごろ、夜間のピーク時間の負荷に耐えられず、Master(書き込み処理)を担っていたDBサーバ(DB01)がダウンしました。データベースクラスタにはフェイルオーバーが設定されていたため、Masterサーバがダウンしたのち、30秒以内に自動的にSlaveサーバ(読み出し処理用サーバ)の一台(DB02)がMasterに昇格し、システム全体としての可用性は維持されました。
ただし、Masterサーバのダウンを検知してからフェイルオーバーが完了するまでの15秒~30秒の間は、番組を作成することができませんでした。
同日22時ごろ、番組開始にともなう負荷の上昇に耐えきれず、新しくMasterの役割を担ったDBサーバ(DB02)の動作が不安定になりました。特に、該当サーバにMasterの役割が移行したあとも、Slaveとしての役割も同時に果たしつづけたため、ディスクI/Oが飽和し、読みこみ・書き込みともに非常に遅い状態が発生しました。
その結果、視聴が開始しづらく、番組を作成しづらい(非常に時間が掛かる、またはタイムアウトする)状況が発生しました。アクセスの主たる要因は生放送番組判定APIだったため、APIのキャッシュが貯まってキャッシュヒット率が上昇するつれ、時間の経過と共にデータベースへのアクセスが減少し、22時26分ごろに過負荷が解消されました。
同日深夜、同様の障害を避けるため、ダウンした旧Master機(DB01)にメモリを増設したうえでSlaveDBとしてクラスタに再参加させ、再度の障害が発生したときには旧Master機(DB01)にMasterの役割が戻るように設定を行いました。また、開発機として利用していたデータベースサーバ(DB04)にも、念のためにメモリの増設を行いました。
6月3日 20時ごろ、番組開始にともなう負荷の上昇により、新しくMasterの役割を担ったデータベースサーバ(DB02)の動作が不安定になり、応答が遅延するようになりました。ただし、サーバ自体がダウンするにはいたらず、20時17分ごろに負荷は落ち着きました。
ニコニコ生放送は、0分や30分といった区切りのよい時間から番組が放送されることが多いため、このままでは21時にまた負荷でサーバが不安定になることが予測されました。そこで、新しくMasterの役割を担ったデータベースサーバ(DB02)からSlaveの役割を外す設定変更を行いました。同時に、開発機だったサーバをSlaveとしてDBクラスタに追加し、正常なクラスタ台数に戻しました。
6月4日の15時30分ごろから、対策検討会が開かれました。その結果、データベースサーバのメモリ不足を、サービス停止なしで安全に解消する方法がないことが判明しました。できるだけ早いタイミングで停止メンテナンスを行うことが合意されましたが、同日夜にかけて多くの番組が放送される予定であること、旧Masterサーバ(DB01)がメモリ不足に陥ってから72時間以上安全にサービスを提供していた事実に鑑み、6月5日の午前6時から停止メンテナンスを実施することになりました。
このとき、少しでも停止メンテナンスの時間を短くするために、DB01にMasterの役割を戻すフェイルオーバーだけを実施することにしました。
Slaveサーバのメモリを増設し、再起動してメモリを解放する作業は、必要であればクラスタ全体を停止させずに(クラスタからSlaveサーバを1台ずつ切り離して)行うことが可能だったので、停止メンテナンス中には作業をしないことにしました。Slaveサーバの対処をいつ行うかについては、6月5日の臨時停止メンテナンス後に検討することになりました。
6月4日 20時15分ごろ、夜間ピークタイムにともなう負荷上昇により、新しくMasterの役割を担ったDBサーバ(DB02)がダウンしました。
これにより自動的に旧Master機(DB01)にフェイルオーバーが行われ、クラスタ全体が健全な状態に復帰するはずでしたが、実際はフェイルオーバーが開始されるより前に、新しくMasterの役割を担ったDBサーバ(DB02)が自動的に再起動されてしまいました。このとき、書き込み禁止モードで再起動されたため、Masterサーバへの書き込みができなくなり、番組の作成ができなくなってしまいました。この状態は、20時21分ごろに手動で書き込み禁止モードを解除するまで続きました。
6月5日の6時から6時10分に早朝に短時間の臨時停止メンテナンスを行い、Masterサーバの役割を、メモリを増設した旧Master機(DB01)に戻しました。このとき、DB02をSlaveとして再参加させるためには手動でデータの整合を取る必要があるため、この時点ではクラスタに参加させませんでした。
しかし、メンテナンス終了後も、最大1/2の確率でユーザー生放送・チャンネル生放送番組の視聴が開始できない不具合が発生しました。
調査の結果、DB02を参照している設定が一部に残っていたためであると判明したため、設定を修正し、7時15分に障害がおさまりました。
6月5日の日中、Slaveの再起動をするべきか、するとしたらどのようにするか、を検討しました。
このとき、6月7日の停止メンテナンスにおいて、メモリ追加およびストレージのグレードアップがすでに計画されていたことから、予定通り停止メンテで作業したほうがよいのではないか、という判断になりました。
6月5日の20時44分ごろ、Slaveサーバの1台(DB03)がダウンしました。これにより、番組の新規視聴が一定の確率でできなくなってしまいました。DB03を使用しないように設定を変更し、20時55分ごろに状況が収束しました。
6月6日 13時から14時ごろ
アプリケーションの定期本番更新にともない、DB01をMasterに、DB02, DB03をSlaveに利用する通常の体制に戻りました。また、この時点で、DB01からDB03がすべてメモリ増設・再起動によるメモリ開放が完了した状態になりました。
■ ユーザー影響
生放送番組を視聴開始することが(一定の確率で)できない。
番組の配信ページへのアクセスにアクセスすることが(一定の確率で)できない。
■ タイムライン
5月30日以前 チャンネル生放送統計情報収集サービスがデータベースサーバのメモリを食い潰す問題を認識し、プログラムの改修を行った。しかし、すでに食い潰されたメモリは開放されず、通常時よりメモリが少ない状態が続いていた。
6月2日 21時40分ごろ データベースクラスタのMasterサーバ(DB01)がダウンし、フェイルオーバーが完了するまでの短時間(30秒以下)、番組作成ができない状態になった。フェイルオーバーは成功し、Slaveサーバの一台(DB02)がMasterに昇格し、サービスは正常な状態に戻った。
6月2日 22時ごろ 新しくMasterとなったサーバ(DB02)も負荷に耐えきれず、応答に長い時間がかかるようになった。その結果、視聴開始失敗や番組作成の失敗が発生するようになった。
6月2日 22時26分ごろ キャッシュヒット率上昇による負荷の自然減により、状況がいったん収束した。
6月3日 20時ごろ DB02が負荷に耐えきれず、応答に長い時間がかかるようになった。その結果、視聴開始失敗や番組作成の失敗が発生するようになった。
6月3日 20時17分ごろ キャッシュヒット率上昇による負荷の自然減により、状況がいったん収束した。
6月3日 20時30分ごろ DB02からSlaveの役割を外すとともに、開発機だったサーバを新しくSlaveとして利用できるように設定した。
6月4日 20時15分ごろ DB02が負荷上昇に耐えられずダウンした。フェイルオーバーが行われるはずであったが、フェイルオーバーに失敗し、さらに書き込み禁止モードで再起動されてしまった。これにより、番組の作成ができなくなってしまった。
6月4日 20時21分ごろ DB02の書き込み禁止モードを解除した。
6月5日 6時0分から6時10分 ユーザー生放送・チャンネル生放送の緊急メンテナンスを行い、メモリを増設したDB01にMasterの役割を戻した。
6月5日 6時10分 最大1/2の確率で生放送番組の視聴が開始できない不具合が発生した。
6月5日 7時15分 上記障害の原因が判明し、修正を行った。
6月5日 20時44分 Slaveサーバの1台(DB03)がダウンしたため、DB04にアプリケーションの参照先を変更する作業を開始した。
6月5日 20時55分 上記の影響が収束した。
6月6日 13時ごろ データベースクラスタが、DB01からDB03を使う正常な体制に戻り、障害が収束した。
■ 再発防止策
今回メモリ不足が発生したデータベースクラスタにおいて、メモリの増設を行う。(実施済み)
コネクション取得時に異常だった接続先情報をキャッシュし、接続先を判断することで、一部データベースサーバの異常によるリクエスト全体の失敗を防止するようアプリケーションを改修する。(実施済み)
サービスの追加開発など、新規にシステム負荷が増加するような本番変更を行う場合、CPU使用率・メモリ消費量などの負荷検証をより厳密に行うようにする。また、本番環境でのシステム負荷をより継続的・密に行えるような監視システムを導入し、特に新規のシステムが追加されたときには注意して見守るような監視体制を整える。
サービスを停止してでもメンテナンスを行うべきかどうかの判断は、状況を楽観視せず、より慎重に行うようにする。
連日の不具合によって、ユーザーの皆様にはご不便・ご迷惑をおかけいたしました。大変申し訳ありませんでした。
再発防止に取り組み、今後は同じ障害を繰り返さないようにいたします。
6月7日以降に発生した障害については、引き続き調査と報告書作成を進めておりますので、もうしばらくお時間をいただきたく存じます。よろしくお願いいたします。