Migration to a Better Datastore

App EngineのブログにMigration to a Better Datastoreという記事が出ていたので,野良翻訳してみる.

要約

  • これまでは,Bigtableの複製機能でデータセンタ間の複製を行っていたが,整合性が無くなる可能性があるため,データセンタがまるごとクラッシュした場合の復旧が遅くなっていた.
  • MegastoreというBigtableの上の機構の複製機構を利用することでこの問題を解決.今後は,データセンタがクラッシュした場合には,ある程度のデータロスはあるが,整合した状態で,別のデータセンタをつかって続行できるようになる.
  • この移行を9/22の太平洋時間5pmにやる.1時間ぐらい落ちるから覚悟しておけ.

よりよいデータストアへの移行

App Engine チーム Ryan Barrett

Google は,経験的に,すべてのことを健全な懐疑主義であつかうべきだと知っている.われわれは,サーバが,ラックが,共有されたGFSのセルが,ときにはデータセンター全体でさえ,わずかな予兆だけで,ときにはそれさえなく落ちることを予期している.だから我々の製品は,可能な限り,複数のサーバ,複数のセル,時には複数のデータセンターで同時に実行され,一つもしくは複数の冗長要素が落ちたとしても,製品としては実行を続けられるようにしてある.われわれはmこれを「マルチホーム」と呼んでいる.この言葉は,一般にはネットワークに関してのみ使う言葉だが,Google内部ではもうすこし広い意味で使われている.

web検索のような読み出しのみの製品に関してはマルチホームにするのは簡単だ.しかし,読み書きをリアルタイムでユーザにさせるような製品,たとえばGMailGoogle Calendar, App Engineではそれほど簡単ではない.わたしは個人的に,マルチホームをApp Engineのデータストアに適用する方法を考えてきた.昨年は,Google/IOでそれについて話をした

このアーティクルでは,App Engine のマルチホームが現在どのように行われているか,来週のリリースでどのように改善されるかを述べる.最後に,App Engineのメンテナンススケジュールについて述べる.

Bigtable の複製と,データセンタ引っ越し計画

App Engine を起動すると,各アプリケーションのデータストアは,複数のデータセンタのうちの一つで提供される.データは,Bigtableの複製機能を用いて.バックグラウンドで他のデータセンタに複製される.これは,多くの意味でうまくいっており,成熟して,頑健なリアルタイム複製が,データおよびメタデータに関して実現できている.

たとえば,アプリのデータストアがデータセンタAで提供されていて,データセンタAからデータセンタBに切り替えたい場合には,まずデータストアをリードオンリにし,Bigtableの複製機能がすべての書き出しをAからBにフラッシュするのを待ってから,データセンタBでリードライトモードで提供を再開する.これはたいていの場合はうまくいく.が,それはAとBが両方とも健全であることに依存している.もちろん,Bが健全でなければBに切り替えたいとは思わないが,Aが健全でなくBが健全ならば,本当はBに切り替えたいのだ.

障害への対処

われわれは,App Engineが依存するサービス,つまりすべてのデータセンターのGFSやBigtableの健全性を常にモニタしている.しかし,まれに予期しない問題が起きることもある.そのような場合に,バックアップの手段があることは非常に重要だ

数ヶ月前に起きた障害のことを覚えているだろうか?我々は,詳細な分析結果を公表している.簡単にいうと,使っていた共有GFSセルがクラッシュし,復旧に時間がかかったのだ.われわれが利用しているGoogleのインフラは,GFSのセルだけでない.共有インフラはわれわれの力であると同時に,欠点でもある.最大の問題は,隔離ができないことだ.共有インフラのどこかに問題があったり,クラッシュしたりすれば,それを利用しているすべての製品が影響を受ける.

先ほどの例で言えば,データセンタAのBigtableセルが健全でなければ,面倒なことになる.Bigtableの複製は高速だが,バックグラウンドで行われる.したがって,少なくとも少しは遅れがあることにまり,だからこそ,Bに切り替える前にはデータのフラッシュをまたなければならないわけだ.もしAが健全でないなら,Aに納められたデータは,しばらくの間アクセスできない.したがってフラッシュすることもできず,Bへのスイッチもできない.Bigtableのセルが復旧してフラッシュが完了するまで,Aを待つしかないのだ.このような極端なケースでは,Aがいつになったら復旧するのかわからない.いつになるかわからないAの復旧まで待つのではなく,限定された少量のデータ欠損を覚悟で,Bに切り替える方法を持っておきたい.たとえばこんな風に.

Bに複製されていないデータをフラッシュするのをあきらめて,データセンタBに切り替える.ありがたいことに,複製されていないデータはそれほどない.なぜなら通常複製はかなり高速だからだ.障害の性質にもよるが,複製されていないデータの量は,アプリのごく一部で,多くの場合はすべてのアプリに対して,直近の数千のプット,デリート,トランザクションコミットぐらいだろう.

もちろん,Aが復旧してきたら,複製されていなかったデータを復旧することができる.しかし,すでにデータセンタBでデータストアを提供し始めていたら,自動的にAからBにコピーすることはできない.同じエンティティに対するコンフリクトが生じる可能性があるから.とはいえ,最悪の場合でも,データのダンプを提供することはできる.そうすれば,データが完全に失われることはない.データのマージを補助するツールを提供することもできるだろう.

不幸なことに,Bigtable複製はこのようなシナリオを実現するのに十分ではない.App Engineは,Bigtablerow単位のトランザクションを用いる.この機能は,1つのrowの中の複数のcolumnに対する読み書きをトランザクションとして整合性をもって実行する機能である.残念なことに,Bigtableの複製は,row単位でなく,column単位で行われる.したがって,AのBigtable上のトランザクションで2つのcolumnを更新した場合,一つのcolumnだけが複製され,もう一つは複製されていないと言うことがあり得る.

このようなことが起こると,フラッシュせずに,Bにスイッチした場合,データストアの内部が不整合になり,A内のデータなしで整合した状態に戻すことが難しくなる.6/2の障害の際データセンタBに移行できなかった理由の一部は,このようなことが起こるのを恐れたからだ.

Megastore複製 が助けに

ありがたいことに,整合性問題を解決する方法がある.Megastore複製である.Megastoreは,Bigtable上に構築された,Google内部のライブラリで,宣言的なスキーマ,複数rowにまたがるトランザクション,2次インデックス,さらに最近ではデータセンタをまたがる整合性の保証された複製を行う.App Engineのデータストアは,Megastoreを是々非々で利用している.App Engineは,Megastoreのすべての機能を必要とはしていない.たとえば,宣言的なスキーマなどはいらない.しかし,整合性の保証された複製に関しては,開発段階から注目していた.

Megastore複製は,複数データ間で複製をとるという意味ではBigtable複製に似ているが,BigtableのColumn単位ではなく,エンティティグループにたいするトランザクション全体に対して複製を行う.さらに,エンティティグループに対するトランザクションは,常に整合して行われる.つまり,データセンタAのBigtableが健全で無くなり,フラッシュをまたずにデータセンタBに移行するという,極端な手法をとらざるを得なくなった場合にも,Bは常に整合性のあるAのスナップショットになっている,ということだ.最新の更新が反映されないエンティティグループがあるかもしれないが,少なくとも,Aの復旧を待たずにBを直ちに利用することができる.

Paxosするべきか,Paxosしないべきか,それが問題だ.

Megastoreの複製機構は,データセンタ間の複製をPaxosをつかって,同期的かつアトミックに行っていた.残念なことに,
Google I/Oでのトークで述べたとおり, データセンタをまたいだPaxosのレイテンシは,App Engineデータストアのような,低位な,開発者を対象としたストレージシステムに対しては,大きすぎる.

このため,われわれはMegastoreの開発チームと共同して,他の方法を模索した.Bigtableの複製と似た,非同期な,バックグラウンドでの複製である.この仕組みは,開発者が期待するような書きこみレイテンシを維持することができる.複製が(Paxosであろうとそれ以外のなにかであろうと)同期的には行われないからだ.それでいて,整合性は保証され,複製されていないデータを最小限に保って,データセンタを移行することができる.

もっと先へ,もっと高く

Megastoreの非同期複製機構は,かなり前から完全に機能するようになっている.われわれはこの機構を厳重にテストし,頑健性を確認すべくストレステストを行ってきた.さらに,Google内部のApp Engineで,数ヶ月にわたって利用している.そして,9/22からパブリック版のApp EngineのデータストアもMegastoreの複製機構を利用することになる.

この移行にはデータストアのダウンタイムが必要になる.まず, 20-30分の間, データストアをリードオンリにする.この間に通常の複製によるデータのフラッシュと,コミットされているが,完全に適用されていないトランザクションをロールフォワードする.次に,データストアを完全に停止してBigtable内のトランザクションログcolumnを消去し,再構築する.これはMegastoreの複製機構が異なるログフォーマットを用いるからである.これが終われば,データストアを復旧して,Megastore 複製を利用できるようになる!

これまで述べたように,Megastore複製によって,App Engineは個々のデータセンタの障害に対して頑健になり,長期間の障害が生じる可能性が大きく低減される.さらに,開発者に対して,データの読み書きに関する2つのオプションを提供することができる可能性がある.一つ目は,プライマリデータストアからの読み出しに時間がかかりすぎる場合に,別のデータストアからの読み出しを許すことである.これによって,読み出しがタイムアウトする可能性を減らすことができるだろう.二つ目は,オプトインベースの,完全なPaxosベースの書き込み操作である.これによって,データは常に同期的に複数のデータセンタ間で複製されることになる.書き込みレイテンシの増大と引き替えに,高い可用性を得ることができるだろう.

これらの機能はまだ検討段階だが,我々は,アプリに最適な方法を開発者が選べるようにしたいと考えている.

メンテナンススケジュール

最後にメンテナンスのスケジュールについて.通常,App Engineのメンテナンス時間は,メインのデータセンタを変更するのにかかる時間に相当する.メンテナンスにはだいたい1時間かかる.その間,アプリは動作を続けるが,データストアやmemcacheへのアクセスは,リードオンリになるか,全くできなくなる.

最近,我々はデータセンタの移行を事前になるべく公開することにした.この情報は完全ではないが,多くの開発者から,もっと早くメンテナンス情報が欲しいと言われたので.2009年のメンテナンススケジュールは下記の通り

  • 9/22(火) 5PM (アメリカ西海岸時間) Megastoreへの移行
  • 11/3(火) 5PM (アメリカ西海岸時間)
  • 12/1(火) 5PM (アメリカ西海岸時間)

変更されることはないと思うが,変更された場合には,GoogleグループのApp Engine Downtime Notifyで,可能な限り早くお知らせする.我々は,個人的にも開発者のアプリが中断することなく動作するよう注力しており,平日のメンテナンスはあまりよくないのはわかっている.しかし,App Engineが依存しているGFS,Bigtableなどのエンジニアチーム全体とのバランスで,この曜日,この時刻を選択した.今後数ヶ月のうちには,Megastore複製によって,メンテナンス時間を短縮できるのではないかと思っている.


ここまで翻訳

所感

  • Googleさん,まじぱねえっす.
  • Megastoreなんてものがあるのは知らなかった.トークだけでペーパはないようだ.
  • ほぼ一月に1度のメンテナンスって結構長い?普通?西海岸5時って,日本だと朝10時,冬時間なら9時.割に直撃っぽい.