【ITニュース解説】Anatomy of Facebook's 2010 outage: Cache invalidation gone wrong

作成日: 更新日:

ITニュース概要

Facebookの2010年大規模障害は、システムを高速化するキャッシュの無効化処理に失敗したことが原因だった。この処理ミスが連鎖反応を起こし、サービス全体が停止する事態を招いた。

ITニュース解説

システムエンジニアとして、大規模なWebサービスが安定して稼働する仕組みや、予期せぬトラブルがどのように発生するのかを理解することは重要である。2010年、世界最大のソーシャルネットワーキングサービスであるFacebookは、サービス開始以来最も大規模な停止事故を経験した。この障害は、およそ2時間半にわたりFacebookへのアクセスが不可能になるという深刻なものであったが、その根本原因は「キャッシュの無効化」という、一見すると地味な問題の失敗にあった。 Facebookのように毎日何十億ものユーザーが利用し、大量のデータが生成・参照されるサービスでは、全てのデータ要求を直接データベースから取得すると、データベースが過負荷になり、システムの応答速度が極端に低下する。この問題を解決するため、多くのWebサービスでは「キャッシュ」という仕組みを利用する。キャッシュは、頻繁にアクセスされるデータなどを一時的にメモリ上などに保存し、データベースに問い合わせることなく高速にデータを提供する技術である。これにより、データベースへの負荷を大幅に軽減し、サービスの高速化と安定稼働を実現している。Facebookのシステムも、膨大なデータトラフィックを処理するためにキャッシュを多用していた。 しかし、キャッシュには常に最新のデータを提供しなければならないという難しい要件が付随する。データベース内のデータが更新された場合、キャッシュに保存されている古いデータは無効となり、使われるべきではない。この古いキャッシュデータを削除したり、新しいデータに置き換えたりするプロセスを「キャッシュの無効化(Cache Invalidation)」と呼ぶ。キャッシュ無効化はデータの一貫性を保つために不可欠であるが、大規模な分散システムで正確かつ効率的に行うことは極めて難しい問題である。更新されたデータに関連するキャッシュを正確に把握し、適切に無効化する必要があるからである。 2010年のFacebookの障害は、まさにこのキャッシュ無効化処理に潜んでいたバグが引き金となった。当時、Facebookのシステムでは、一部のデータベースが異常を検知し、「メンテナンスモード」に入ることがあった。通常、このモードでは、そのデータベースが管理するデータに関連するキャッシュを無効化し、次回アクセス時に最新データをデータベースから取得する処理が実行される。これは古いデータが表示されるのを防ぐ安全策の一つであった。ところが、このキャッシュ無効化処理には特定の条件下で、想定をはるかに超える大量のキャッシュキーを削除してしまうバグが潜んでいた。 このバグが発動すると、通常であれば数個のキャッシュキーが無効化されるべきところが、何百万ものキャッシュキーが一斉に削除された。その結果、Facebookのウェブサーバーは、ユーザーからのリクエストに応えようとキャッシュを探すが、データは全て無効化されているため、キャッシュにヒットしない「キャッシュミス」が大量に発生する。キャッシュミスが起こると、ウェブサーバーは代替としてデータベースへ直接データを問い合わせる。本来キャッシュがデータベースへの問い合わせを減らす役割を担うにもかかわらず、バグによって大量のキャッシュミスが発生したため、データベースへのアクセス要求が激増したのである。 激増したアクセス要求は、Facebookのデータベースシステムに莫大な負荷をかけた。データベースは処理能力の限界を超え、次々と応答不能に陥り、さらに多くのデータベースが自らメンテナンスモードに入ってしまった。このメンテナンスモードへの移行は、さらにそのデータベースが管理するキャッシュ無効化処理をトリガーした。つまり、バグのあるキャッシュ無効化処理が、ダウンしたデータベースを起点として次々に呼び出され、健全なキャッシュまでも連鎖的に無効化していったのである。この負の連鎖反応はシステム全体に広がり、最終的にはFacebookのサービス全体が機能停止に追い込まれた。 復旧には、システム全体を停止し、問題を隔離した上で修正を適用し、徐々にサービスを再開していく必要があった。このFacebookの障害は、大規模な分散システムにおいて、いかに小さなバグが予測不能な連鎖反応を引き起こし、深刻な結果を招くかを示した。システムエンジニアとしてこの事故事例から学ぶべきは、キャッシュ管理の重要性と難しさ、デバッグ機能やメンテナンススクリプトでさえ慎重な扱いが必要である点である。また、システムの一部障害が全体に波及しないよう、「セーフティバルブ」のような防御機構の設置や、詳細な障害回復計画の設計が重要である。

【ITニュース解説】Anatomy of Facebook's 2010 outage: Cache invalidation gone wrong