スティルハウスの書庫の書庫

はてなダイアリーで書いてた「スティルハウスの書庫」を移転してきました。

App Engine: Now Serving Javaを見たメモ

App Engine: Now Serving Java

  • Servlet API
    • HTTP Sessionは永続化され、どのクラスタノードからでも同じセッション内容を取得できる
  • App Engine API jar
    • パッチリリースのアップグレードは自動的に行われ、再デプロイの必要はない
  • ApiProxy
    • APIコールはApiProxyを経由して実行される
    • 個々のリクエストの情報(ThreadLocal)を保存する
    • APIコールをAOPのようにインターセプトして、その前後に追加処理を挿入できる
      • ログ記録など
    • クラスパス変更(JAR入れ替え?)だけで、APIのサービスプロバイダーを変更できる
      • unit testに便利
  • Flexible Sandboxing
    • きめ細かなサンドボックス制御で、安全性を確保しつつ、できるだけ多くの既存コードを動かせる環境を提供する
    • app engineで使える既存ライブラリ
Dependency Injection Frameworks
  - Guice, Spring, etc.
Aspect Oriented Programming
  - AspectJ, Spring AOP, etc.
Web frameworks
  - Google Web Toolkit, Tapestry, BlazeDS (Flex), etc.
  - Grails (Just Announced!)
Alternate JVM languages
  - Scala, Rhino, JRuby, Jython, Clojure, Groovy, PHP, etc.
  • DevAppServer
    • ローカル環境で各APIをエミュレート
      • ローカルディスクでDatastore
      • Memcache
      • URL fetch
  • 近日リリース予定
    • Async API
    • Task queues
    • 全文検索
    • メール受信
    • XMPP
    • 大規模ファイルのアップロードとダウンロード
    • Datastoreのエクスポートツール
  • Questions
    • (高負荷時などに)アプリが新しいノードにデプロイされたときの遅延は?
      • アプリが使うライブラリ規模にもよるが、数100ms〜数秒程度。
    • Java版とPython版の性能の違いは?
      • きちんとした比較はしていない。使い方によって異なるが、あまり大きな違いはない。GAE以外の環境で両者を比べた場合と同じ程度。
    • Cometサポートは?
      • 現状ではレスポンスのストリーム送信に対応しないため、Cometは使えない。現状、Cometサポートはロードマップにはないが、XMPPはサポート予定なので、プッシュ通信は実装できるようになる。
    • どんなJVMを使っている?
      • サンの1.6版JVMをそのまま使っている。アプリのロードを速くするため(Server VMではなく)HotSpot Client VMを使っている。
    • googleスタッフがデータを閲覧しないためのセキュリティポリシーはあるか?
      • 社内のポリシーがある。

Offline Processing on App Engine: a Look Aheadを見たメモ

Offline Processing on App Engine: a Look Ahead

  • 背景
    • バックグラウンド処理やバッチ処理の要求がとても多い
      • cronはあるが、たくさんの処理や高頻度の処理には向かない
  • 概要
    • 現状はApp Engine Labsの扱い:APIが未確定。課金方法も未定
    • Python版が6/18にリリース済み(追ってJava版)
  • TQとは?
    • ベストエフォートFIFOに処理要求を登録しておくと、バックグラウンドで実行。
    • 実行に失敗した場合は、成功するまでリトライする
taskqueue.add(description_of_work )
  • TQのメリット
    • 非同期
    • 軽量で遅延が少ない。Datastoreの最大3倍
    • 信頼性が高い:成功するまでリトライ
    • スケーラブル:新しいタスクをいくらでも追加できる。それぞれ並列処理される。
  • 他のTQシステム
    • 各種MQ、Amazon SQS、Azure queuesなど
    • pub-subメッセージングと統合されていることが多い
  • Queueingとpub-subの違い
    • Queueing:非同期処理によりネットワークやCPU、ディスクのキャパシティを効率よく引き出し、スループットを最大化する
    • pub-sub:非同期処理により多数の小さなtxを効率よく扱う。fan-outや優先処理、フィルタリング、分散txなどを提供
    • app engineのTQは前者のみを対象とする
  • GAE TQの特徴
    • Web Hookベース
      • RESTfulなpushベースのインタフェースでタスクを起動。今後登場する各種APIWeb Hookを活用する予定
      • コールバックしてほしいURLをTQに登録する。TQのワーカーがバックグラウンドでURLをコールバックする
taskqueue.add(url='/work/mail', params=dict(
    to='foo@example.com',
    subject='Hello',
    body='this is a message!'))
      • 非同期なので登録は一瞬で終わる(数10msくらい)。メール送信処理を待つ必要がない
      • ステータス200を返せばタスク終了
      • ワーカーの数は負荷に応じて自動調節されるので、開発者がワーカーのプールを管理する必要はない
      • (従来のリクエスト処理と同様に)ダッシュボード上にURLごとのCPU消費状況が表示される
  • タスクはIdempotenceにする
    • タスクは繰り替えし(二重に)実行されても問題のないように書くこと
    • さまざまな理由(タスク自身の問題、コンテナの問題、またはそのほかの理由)でタスクは2回以上実行されることがある
    • memcacheなどを使って排他する方法が考えられる
  • Queueの使い方
    • queue.yamlで定義
    • 優先度や処理頻度の違いに応じて異なるQueueを定義。さまざまなタスクが混在できる
queue:
- name: mail_queue
  rate: 2000/d
- name: speedy_queue
  rate: 5/s

応用例

  • Write behind cache
    • ユーザーリクエスト処理時はキャッシュに書き込んでおき、TQのタスクでDatastoreに一括書き込み
    • カウンターでの利用:memcacheのカウンター値を加算し、タスクでDatastoreに書き込み

Future

  • JMS統合
  • MapReduceサポート: しかし他にももっとツール(シャッフル用の中間ストレージなど)が必要
  • Queue用AdminConsole

Questions

  • タスクにも30秒制限は適用される?
    • される。
  • TQはapp engine外部のタスクも呼べる?
    • 使える。Web Hookはapp engine以外のアプリも呼べる。

The Softer Side Of Schemas - Mapping Java Persistence Standards To the Google App Engine Datastoreを見たメモ

The Softer Side Of Schemas - Mapping Java Persistence Standards To the Google App Engine Datastore

Datastoreについて

  • ストレージをシンプルにする
    • Gmailのような規模でなくても、どんなアプリでもスケーラビリティを考える必要がある。
  • Entity
    • Kind(テーブル)
    • Key(主キー)
    • Entity Group(パーティション/階層化の単位)
    • Property(カラム)
  • Datastoreの特徴的な機能
    • Ancestor:root、親、子といったentityの階層構造とグループ(entity group)を作れる
    • Heterogenous property types: 個々のentityごとにpropertyの型を変えることができる
    • multi-value properties: 1つのpropertyに複数の値(List Property)を保存できる
    • variable properties: entityごとにスキーマを変えることができる

Soft Schema

  • Soft Schemaとは
    • 「アプリケーション層のみが制約を受けるスキーマ
    • 開発が簡単。タイプセーフなプロトタイピングをすばやく実施
      • 従来は、JavaSQLのそれぞれに個別の設計や実装、デプロイメント、テストが必要だった
      • SSではすべてがJavaに統一される
  • DatastoreでのSS
    • 既存のAPI(JDO/JPA)を通じて利用できる
    • 移植が簡単。もしGAEが適さないと分かった場合でも、そのまま他の環境に移植できる。GAEにロックインされない
    • List Propertyによるクエリ:とても便利
  • リレーションシップ管理
    • オブジェクト間の関連に限らず、永続化、オブジェクトとデータストアのマッピングなどをJDO/JPAが集中管理
    • それらをアプリ内のさまざまな部分(Javaクラス、設定ファイル、SQLコード、スキーマJDBCなど)で実装・管理する必要がなく、メンテナンス性が高い
  • Entity Groupの透過的な管理
    • 1つのEGの書き込み処理は、1〜10回/sec程度に限られる
    • "owned"関連を持つentity同士でEGを形成する:EGの使い方を理解しやすい
    • "unowned"関連はサポートしていない:EGがないのでtx管理できない

GAEへのマイグレーション

  • プライマリーキーの扱い
    • 単一カラムの場合はそのまま使える
    • 複合キーの場合はentityの親子関係に置き換える
    • N:N用のマッピングデーブル(ジョインテーブル)はList Propertyに置き換える
  • トランザクションの扱い
    • データモデルからEGのroot entityを見つける
      • オンラインサービスでは「ユーザー」データが最適な場合が多い
    • 複数のroot(EG)に対するトランザクションが必要な場合
      • 仕様を見直す
      • compensating txを実装:2つめのtxが失敗した場合は、最初のtxをキャンセルする、など
  • クエリの扱い
    • joinは使えない:非正規化するか、複数のクエリに分割する
select * from PERSON p, ADDRESS a
where a.person_id = p.id and p.age > 25 and a.country = “US”
↓
select from com.example.Person where age > 25 and country = “US”
    • 関数が使えない(toUpperなど):関数適用後の値を別カラムに入れておく
      • 書き込み時にできるだけ事前処理を行っておくことで、読み込みを高速化できる
    • そのほか、条件演算子の不足:メモリ上でフィルタ

Questions

  • 大規模なグラフ(関連)を一括で取得するような、何らかのプリフェッチ機能(eagar loading)はないか?
    • joinできないので、サポートできない。複数のクエリが必要となる。JDOのバッチgetは利用できる。
  • 分散txをサポートする予定はあるか?
    • 未定。アプリレベルでGAE上で分散txを実装した例がある(他セッションを参照)
  • DataNuculeusのダーティフィールド検出を使っているか?
    • 使っていない。Datastoreでは1つのプロパティのみの更新ができないので、全フィールドの更新となる。
  • JDOのowned関係にないentity間でEGは形成できるか?
    • できる。Low Level APIを使う必要はなく、他のentityのキーを持つunowned関係を明示的に記述する必要がある。

KVSやMapReduceはクラウドの真価ではない

ちょっと逆説的に書きました。key-value store (KVS)やMapReduceは、クラウドにはなくてはならない重要な技術ではありますが、それらの技術単体では一般のエンジニアにとってそれほど価値はありません。もともと分散ストレージや分散処理技術は昔から学術研究の恰好のネタでしたし、最近になって技術的ブレークスルーがあったわけでもありません。

クラウドの真価は、「すでに巨大なクラウドがそこにあり、きちんと運用され、ビジネスモデルがある」ということです。学術研究や、まだ実績の少ないOSSフレームワークなどのレベルから、Google並の商用サービスに至るまでには、超えられない壁があります。例えばBigtable論文では、クラウドを構築して実運用することがいかに大変かが記されています。

One lesson we learned is that large distributed systems are vulnerable to many types of failures, not just the standard network partitions and fail-stop failures assumed in many distributed protocols. For example, we have seen problems due to all of the following causes: memory and network corruption, large clock skew, hung machines, extended and asymmetric network partitions, bugs in other systems that we are using (Chubby for example), overflow of GFS quotas, and planned and unplanned hardware maintenance.

たとえて言うならば、クラウドは「マンション」のようなものです。HadoopCouchDBはたいへん面白い技術ですが、それは「マンションを建てる基礎技術」に過ぎず、上述のような泥臭い苦労を背負ってまで自前でマンションを建てる必要に迫られる人はごく少数です(Amazonとかmixiの中の人)。

クラウドのブレークスルーは、AmazonGoogleが苦労して建てた巨大マンションの部屋が、とても安く(タダで)賃貸され始めたことです。KVSという簡素な収納しかなく、その使い方も相当慣れが必要ですが、代わりにいくらでも物を置けて部屋も好きなだけ拡張できます。マンションによっては、困った時にはご近所さん総出で助けてくれるMapReduceという仕組みもあります。たくさんの人が、これらの珍しい装備を見よう見まねで使い始め、意外にも結構「住みやすい」ことに気づき始めたところです。

こうした理由から、いまクラウドのKVSやMapReduceが関心を集めているのだと思います。

Big Table: A Distributed Structured Storage Systemを見たメモ

Big Table: A Distributed Structured Storage System


Googleの典型的なクラスターノード構成>

  • クラスターノード構成
    • クラスターノード
      • Intelベースの安いPC
      • Linux OS
      • Scheduler slave
      • GFS chunk server
    • Cluster scheduling master
    • Lock service (Chubby)
    • GFS master
  • これらのノードの上に、スケジューラが各種サービスを載せていく
  • tablet
    • 1つのtabletは100〜200MB程度のデータを保有
    • 1台のtablet serverで100以下のtablet保有
    • 復旧が高速:1台がダウンしても、その100個のtabletは他の100台のサーバーが保有している
    • Masterが負荷分散を管理し、高負荷のサーバーからtabletを移動
    • tabletサーバーのGFS書き込み
      • 1つはローカルのchunk serverが空いていればそこに書く
      • 残り2つは離れた場所(少なくても同じラックではない場所)のchunk serverに書く
      • tabletが移動しない限り、tablet serverはローカルのchunk serverにアクセスする
      • 負荷分散のためtabletが移動すると、データは残したままtabletのみ移動する
      • バイナリアップグレード時などに、できるだけローカルに置くようにデータを再配置する