セールスフォースのアーキテクチャ(シングルコード編)~ セールスフォースの内部コードで見る、過去との互換性をどう保つか
米国の計算機学会として知られるACMが主催したクラウドコンピューティングのシンポジウム「ACM Symposium on Cloud Computing 2010」(ACM SOCC 2010)が6月10日、11日にインディアナ州インディアナポリスで開催されました。
基調講演で行われたセールスフォースのアーキテクチャの解説を紹介しています。
(この記事は「セールスフォースのアーキテクチャ(マルチテナントデータベース編)~ Flex Schemaとオプティマイザ」の続きです)
シングルコードベースをいかに維持しているか
クラウドのすべてのテナントが同一バージョンのコードを利用する「シングルコードベース」を、セールスフォースはつねに維持しようとしている。そこには大きなメリットがあるからだ。私たちはたとえ重要な顧客から修正パッチの依頼があっても個別対応することはない。
セールスフォースはCRMのSaaSをシングルコードで提供し、成功してきた。アプリケーションプラットフォームであるForce.comでも、同じくシングルコードを採用しつつ、プラットフォームがアップデートされてもAPIの互換性を確保していきたい。
私たちがどのようにシングルコードベースを維持しているのか、その説明をしよう。
利用者はセールスフォースのアプリケーションやAPIがつねに変わらないことを期待する。一方で、私たちセールスフォースを開発している側としては、セールスフォースを進化させつつ、これらが適切に変化することもありうると考えている。この2つをどう両立していくかが課題である。
変えてはいけないものとは、以下の3つだ。
- スキーマシェイプ
- APIシェイプ
- 実行時の振る舞い
スキーマシェイプとは、システム内のスタンダードなオブジェクト。顧客アカウントなどのことで、これらのフィールド名などが変わったら問題になる。
APIでも引数の型などが変わらないようにすべきだし、実行時の振る舞いも変わらないようにしなければならない。
これを維持しつつ、しかしセールスフォースのシステムをつねに前進させていくにはどうすべきだろうか?
「シングルコード」とはどういうことかといえば、例えば今日(6月11日)と明日が、セールスフォースのバージョン「Spring 2010」の最後の日だ。その次の日には「Summer 2010」にアップデートする。
Summer 2010にアップデートするとSpring 2010は消えてしまい、もう使うことはできない。セールスフォースの利用者全員がその日からSummer 2010のバージョンを利用することになる。シングルコードというのはこういうこと。
しかし、Force.comの上では例えば「Spring 2002」のバージョンで作られたアプリケーションもあるかもしれない。そこで、最新のバージョンであってもSpring 2002のような過去のバージョンと同じことができるようになっている。
その仕組みが、最新バージョンはつねに1つ前のAPIをエミュレートするようになっているということだ。(1つ前のバージョンのAPIには、つねにそのさらに前のバージョンのAPIとの互換性が含まれているため、下位互換性がずっと維持される)
APIはバージョン化されており、アプリケーションは特定のバージョンのAPIを利用するように宣言する。
以前のバージョンのAPIとの互換性はどのように保たれているのか、具体的にみてみよう。これがセールスフォースの内部コードだ。どうやらいちばん恥ずかしい例をもってきてしまったようだが(笑)。
まず、Schema Shapeを維持するための内部コード。
これはあるスタンダードオブジェクトを定義するコードだ。このケースでは、過去に「Productオブジェクト」をAPIとして公開している。バージョン142ということは、おそらく2002年から2003年のあたりだろう。
このとき、オブジェクトを設計しただれかが基本的に間違った判断をしてしまったようだ。そしてその後オブジェクトの定義は大幅に変更になった。公開されるAPIは慎重に定義されるので、こうしたことはほとんどないのだが。
しかしそのオブジェクトは使い続けられるように、こうしてコードの中に残っている。ただし、「maxApiVersion="142"」と定義されているように、APIのバージョンを142以後と指定して利用するときには、このProductオブジェクトを見ることはない。
一方で、Minimumなバージョン指定もある。「Product2」として定義されているオブジェクトは「minApiVersion="134"」と書かれているため、バージョン132など、134より小さいバージョンを指定して利用するAPIからはこのオブジェクトを見ることはない。
このようにしてSchema Shapeは維持されている。
API Shapeも同様に、コードの中にJavaのアノテーションでAPIのバージョンが埋め込まれている。
バージョンの振る舞いについても同様だ。バージョンごとに振る舞いが変わる場合には、そのバージョン番号とともにコードの中に組み込まれる。たとえバグであっても、それは機能として永久にキープされるのだ。これが私たちのカルチャーとなっている。
そして、Force.comのうえではApexコードを用いて開発するパートナーも、同じように自分たちのアプリケーションを書くことができるようになっている。つまりパートナーのアプリケーションも「シングルコード」ベースを維持しつつ顧客に提供することができるようになっている。
クラウドのサービス、特にマルチテナントのクラウドでは、ソフトウェアのデバッグは難しい。従来のデバッガでは十分ではない。コードがリモートで動いており、またマルチテナントのクラウド環境では、さまざまな利用者がクラウドにアクセスしてくるのをブロックするわけにもいかず、リソースを管理できない(注:そのため、障害時の再現環境を作るのが難しい、という意味のようだ)。
Omniscient Debuggerが有望ではないかと考えている。これは実行内容をキャプチャするもので、あとから実行をトレースしたりステップしたりして再現できるためだ。
記事「セールスフォースのアーキテクチャ」
- セールスフォースのアーキテクチャ(物理アーキテクチャ編)~ Podによるスケールアウト
- セールスフォースのアーキテクチャ(マルチテナントデータベース編)~ Flex Schemaとオプティマイザ
- セールスフォースのアーキテクチャ(シングルコード編)~ セールスフォースの内部コードで見る、過去との互換性をどう保つか