Scale OutアンチテーゼとeCloud構想
Scale OutアンチテーゼとeCloud構想:中島の考え
RDMA実装で明らかになってきたクラウド時代の新データモデル
この話、反論を思いついたら書きますといっておいて放置していた。
中島さんは一言でも反論しようもんなら100倍になって返ってくることで恐れられているが、萎縮してたからではなく今は単に忙しいのだ。でも反論すると後で怖いので疑問ということにしておきます。
中島さん自身、10年くらい前に、e-Datacenterの話の関連で、マルチテナントのSaaSモデルを予言されていたので、今のPublicクラウドには異論はないのだと思う。
今回のお話を聞く限りでは、Publicクラウドは肯定されているが、それをそのままPrivateクラウドに適用することがだめといっておられるように思う。要は、NFRの作りこみがナンセンスであることと、CPUの高い処理能力が今後も見込めるということ。これは私もある程度納得できる話である。
ただ、アプライアンス志向については、何となく私でもイメージできたものの、もう少しPrivateクラウドの標準化の重要性が認知されてこないと一般の人にはまだ馬の耳に念仏かもしれないとは思う。社内の資源をデータセンターに集約してガバナンスをきかせる、そのためには標準化が重要であるという話は出てきてはいる(プライベートクラウドを構築した大手国内企業、その理由と利点を語る)が、中島さんの話を理解するには、もっと踏み込まなければならないと思う。
この考えをさらに発展させると、NW設備なども集約した1アプライアンスが、データセンター1個分ぐらいのインパクトをもつということになる。でもこのイメージが、果たしてどれくらいの人に受け入れられるかは全くわからない。昔、e-Datacenterの話を聞いたときもそうだったが、私はさっぱりわからず拒絶反応を起こしかけた。そう、この世の中にないものをイメージしろっていわれても拒絶反応を起こすのが普通なのだ。
そのときは何もわかってないけど、とりあえずわかったふりしておくのが無難と考え、そして、10年たって流行りだすと、知ったかぶってウンチクをしゃべりだすというのが(私を含め)大多数の人の行動でもある。
でも現実を直視すると、今の私はどうやって飯を食べていくかが問題で、10年後なんて、そんとき考えりゃいいじゃんというのも本音。誰かが投資してくれて10年間飯食わしてくれるなら話は別だが、体育会系のノリでガチンコできるわけがない。10年後はもしかしたら、HWアプライアンスのウンチクをいっているかもしれないけど。
ということで、本題に移る。
3つの疑問
疑問1 結局、CPU単体の能力は無視できないじゃないか
大規模なデータ処理をマルチコアで走らせた場合、16コア以上ではスピードが減少するということが、IBM名誉フェローのFran Allen氏の昨日3月10日に行われた日本の情報処理学会創立50周年記念全国大会の招待講演
で紹介された。
たしかに、Intel QPIで懸案だったレイテンシを解決できるのかもしれない。それは、AT互換機の黎明期に登場したローカルバス以上のショックはあるとは思うけれども、リニアに無限にスケールしていく話ではないように思う。(わかりませんけど)
一般にアーキテクチャは、計算ユニットとデータストア、この2つのあいだにあるバンド幅、レイテンシといったものを解決するためにあります。そしてここにパフォーマンスのバリアがあるのです。マシンの性能をより向上させていくには、こうしたバリアを乗り越えていくことが必要です。そしてこうしたバリアを乗り越えるためにキャッシュなどのデータをやりとりをするために多くの資源がつぎ込まれていきました。
計算ユニットをもっとストレージの中に分散して入れていく、というモデルがあるのかもしれません。
そして性能向上のための並列処理はこれ以上ハードウェアではできないのです。この道具をどう使うのか、それはソフトウェアにまかせられているのです。
・・・
最後に、この講義に非常に関連しているニュースを紹介しましょう。大規模なデータ処理をマルチコアで走らせた場合にどうなるか、という最新の研究です。
これによると、16コア以上ではスピードが減少するというのです。そしてこうしたマルチコアのCPUは市場に登場します。
これを解決するための答えは私にはありません。おそらくマルチコア時代にのこの問題を解決するには、デザインを見直し、アルゴリズムを再考する必要があるのでしょう。
疑問2 同期的処理が必要なのは部分的なのになぜ全体アーキテクチャが必要か
以下はECの概要図(下)で実際に私が構築したものである。点線から上の段がインターネットの外部システム。真ん中が社内の受注システム。さらに点線の下が社外の外部システムと社内の基幹システムである。真ん中の点線の丸には、受注、在庫、出荷、販売の各サブシステムがあるが、それらは実質的には1つのシステムであり同期的に連携していた。外部システムであるYahooや楽天サイトからの受注データの入力、および、配送システム、会計システムへの出力については非同期のバッチにて行っていた。
これは、受付時の在庫引当など、お互いに連動しあう部分のデータにおいては同期的な処理が必要だったが、会計処理など時間が過ぎて〆められた部分のデータにおいては、非同期的な処理で十分だったということ。同期的な部分はせいぜい直近の3か月分で、それ以外の3ヶ月以前のものは同期処理は必要ない。データの割合からいえば1対9。大部分が非同期処理で可能なものであった。何がいいたいかというと、本当に同期処理が必要な部分というのは極めて少ないということ。
さらに受注処理のなかでも、商品検索、カート機能、在庫引当機能は、下図のように、それぞれ設計のスタンス(観点)が異なり、本当に同期処理が必要なのは在庫引当機能だけであったことも付け加えておく。
外部システム連携では、例外的なエラーデータが含まれることも多いので、大量のデータをFTPなどで一旦受け付けておいて、エラーがあった行だけを送り返すといった感じで処理が進む。これは一種のEventually Consistencyである。
このシステムでは、Yahoo、楽天からの受注取込時におけるエラーデータ修正処理(出荷日にお届けできないなど)。配送業者へのデータ送信時におけるエラーデータ修正処理(配送不能地域など)などがあった。これらはほとんどがコールセンターオペレータによるお客様(ゴメンナサイ)対応になってしまっていた。
このように、外部システム連携では不確実性があるため、必要であれば人手を介してエラー修正することは、ある程度覚悟しなければならないと思われる。
この事例はECという特殊なものなので、企業システムのすべてにあてはまるものじゃないとは思うが、一般的に外部システム連携に関しては、疎結合・非同期処理で十分なのではないか。
それから、外部システムの境界は、社内外という意味だけではないことも付け加えておきたい。社内の2つの異なるシステムがそうかもしれないし、同一システム内のコンポーネントをサービス化してもそうなるかもしれない。(ECシステムの場合は、受注と在庫が別々のサービスとして立っていた)
同様に、プライベートクラウドにおいてパワフルなコンピュータリソースが登場したとしても、複数のVMに区切って様々なサービスを立てる場合においては、同様の話になってしまうと思う。その場合、サブシステム間の連携は非同期と割り切るしかない。
ちょっと話がそれるが、一般的なWebスケールのAPI(WebServices)は、外部システム連携の不確実性を考慮して提供しなければならないため、結果としてシンプルなRESTが流行ることになったと思う。Webスケールとは外部システムの集合と考えてよい。WS-*がサブシステム間の同期処理を念頭に置いているのに対し、RESTは基本ステートレス(非同期)である。WebスケールのAPIは、不確実性を想定していないとうまく機能しないし、同期的な処理にはなじまない。同期ではステートフルな実装が強要されるが、それは時間とリソースの束縛を意味する。もちろん、WSDLでインターオペラビリティが確保できるなんて話は幻想であることはいうまでもない。
疑問3 BASEトランザクションはそんなにダメなのか
前述のECシステムにおいて、受注、在庫は同期的に連携していたといったが、実はこれはWebサービス連携であった。私はどうしても2つのコンポーネントに別けたかった。というか、在庫は第二フェーズの機能なのでそうせざるを得なかった。それで、どのようにしたかというと補償トランザクションで連携することにした。その結果、 補償トランザクションの悪夢のような話になった。ほれ、いわんこっちゃない、といわれそうだが、一方でコンポーネント化やサービス化のメリットも大変大きかったので、これはこれで正しかったとは思っている。
【EC開発体験記-サービス志向-】 疎結合で真価を発揮
言語の記事でも触れたが、私たちのECシステムでは、PHPと Javaの両方を使っている。PHPが主にリクエスター、Javaが主にプロバイダーだ。実は、PHPの開発者はJavaを知らないし、Javaの開発者はPHPを知らない。共通スキルはMySQLとLinuxだけだ。一昔前であれば考えられなかったチーム編成なんじゃなかろうか。お互いを干渉しない。干渉しようと思ってもできない。結果、自然と自分の責任範囲に集中することになる。これで本当の意味でサブシステム化が可能となる。私はサブシステム化する目的の一つは並行開発にあると考えている。密結合では実質的に無理な状況であった並行開発を、サービス志向であれば可能にできる。「完全なる隠蔽」によりシステム全体に及ぼす影響を最小限にできるため、分業・並行開発ができるようになるのだ。
前述したように、コンポーネントを単位とするのが理想であり、その点では各処理はサービス化して疎結合が普通なのだけれども、受注と在庫のように、同期的処理が必要な場合もある。
GAEでは、下図のように、DatastoreやMemcache、TaskQueueなど、すべてのリソースがネットワークだけで繋がっているため、基本的にWebサービスの呼び出しとなり、トランザクションは、EntityGroupのBASEトランザクションとなる。
EntityGroupのロックは楽観的ロックを基本にしたもので、ロックをかけない非協調型であることが特徴だ。協調とは相手に合わせて自分が振舞うことで、非協調とは相手のことを考えない空気の読めないようなやつのことをいう。麻雀やると必ずいるだろう?自分のパイだけ直視して何の根拠もなくアンパーイとかいって全ツッパするヤシだ。
悲観的ロックは、協調して動作することが基本。電車が運行管理システムで発射時間や速度が厳密にコントロールされている世界。一方の楽観的ロックは、各自が信号機を守って運転する自律の世界。ダイヤどおりに到着する電車に対し、渋滞もあって時間通りに着かないリスクがあるのがタクシー。でもこっちの方がとても効率がいいのである。
リアルタイムで非協調な世界の代表はTwitter。ゆるく繋がって返事をしてもしなくても構わない世界。「リアルタイムで非協調」はWebスケールにおける重要なキーワードである。
例えば、受注と在庫引当の2つがBASEトランザクションで連携すると、以下のように、アプリケーションによる2フェーズ処理のような感じになる。(BASEトランザクションの話は、送金のトランザクション処理パターンなどが詳しい)
① 1つのリクエストに対して受注を行いそれから在庫引当を非同期に実行する。在庫引当は必ず1回実行することは保証できるが数量によっては引当失敗が起こりうる。しかし、それを検知して受注をキャンセルすることはできない。
② ①のリクエストに対して、引当失敗かどうかをクライアントからポーリングするなどしてチェックする。一定時間以内に確認できなければ失敗とみなすなど、例外処理も考慮する。
結論からいうと、補償トランザクションはダメである。上記のようなBASEトランザクションも大変である。ではどうすればよいか。
まず第一に、サブシステムの境界をちょっとだけ大きく広げ、サブシステム内であれば、ACIDトランザクションが可能になるようなフレームワークを作る。そのフレームワークはBASEトランザクションになるのだけれども、開発者はそれを意識せずに使えるというものである。
ECシステムでいえば、受注、在庫、出荷、販売はそれぞれのコンポーネントとして独立しているが、サブシステムとしてみると1つであり、それぞれが同期的に連携可能とする。
GAEのフレームワークであるSlim3は、Google App EngineでGlobal Transactionを実現している。
Slim3では、CoordinatorがMemcacheやTaskQueueを使って2フェーズコミットを実行することでGlobal Transactionを実現している。つまり、BASEの仕組みで動作するACIDトランザクションシステムである。なんのこっちゃ!?と思われるかもしれないが、これは本当にすごいことだと私は思う。
MemcahcedやTaskQueueといったCoordinatorの補佐をする機能は別途必要ではあるが、これらを含め、Scale Outのアーキテクチャーとして有効性が確認できれば、その応用としてマルチコア問題を解決できる可能性もあると思う。複数のCPUに共有メモリと高速バス ≒ Memcached+Apps+Datastoreに単純に置き換えて考えられなくもないと思う。
Eventually Consistencyにも同期型、非同期型の2つのタイプがあり、同期型が実質的にACIDと同じ効果をもたらすならば、そんなに毛嫌いする必要もない。もしろ、HWを補完する機能はこういったソフトウェア技術かもしれないじゃないか。
楽観的ロックもしかり、BASEトランザクションの応用はいろいろ可能だと思うのだが、どうだろうか。
0 件のコメント:
コメントを投稿