Seasar Conference 2009 Springに行ってきた
SeasarConに行ってきました。
プレゼン聞きながらTwitter眺めたい!!イーモバイルが欲しくなってきた今日この頃。
自分用のメモ書きを残しておきます。
Slim3 on Google App Engine/Java
-
BigTable = 老害かどうかのリトマス試験紙
-
年をとっているから老害なのではなく、新しいもの・経験のないものを使いにくい、と排除してしまうのが老害
-
GAEでは既存のアプリ・フレームワークが使えない、制限が多い
- 使いにくい、使わないと判断してしまったら老害の可能性
-
デメリットという代償を払うことで、アプリケーションがスケールするメリットを得られる
- 制限を楽しんで、乗っかることでHappyになれる
Slim3
-
GAE/Jに最適化されたフルスタックのMVCフレームワーク
-
Simple and “Less is More”
- 無駄なものをそぎ落とす
-
Google Develper Dayにて
- 既存のRDBMSは、データを保存するには大きすぎる
- だからGoogleはBigTable/GAEを作った
-
Slim3も同じ
-
特徴
-
TDDをサポート
- テストケース、コントローラを自動生成する機能が組み込まれている
- Test時はServletをエミュレートしてテストしやすくしている
- BigTableはテスト時、メモリ上で代替
-
HOT reloading
- TDDと組み合わせて小気味良い開発を
-
Type safe query
- モデルのエラーもコンパイラで検知
- クエリを文字列ではなく、Javaのクラスとして表現することで可能としている
- モデルをメタデータ(自動生成)から取得
- 実行時ではなく、コンパイラで検知できる
- Eclipseのデモで実演
- EclipseのCtrl+1でサクサク開発できる
- BigTableはスキーマレスな環境なので、モデルのリファクタリングを快適に行える
-
TDDの話
- リファクタリングによって、設計を良くする、だけじゃなくて…
- Red(ストレス),Green(爽快感)の繰り返しによって、開発者のモチベーションと潜在能力を高める
- 開発のリズム重要
- 普段なら適当にコード書いて適当にテスト書いて…
- TDDでは目的を先にはっきりさせてから、短いサイクルでフィードバックを得る
- これの繰り返し
デモ
TDDがサポートされているということで、TDDで足し算アプリを作る様子がライブで見ることが出来ました。
個人的には、TDDってまだまだエッジの利いた技術者が集っている現場/プロジェクトでは当たり前に行われているけど、自分が属しているような労働集約型の典型的な現場ではまだまだ知られていない開発手法なので、これが浸透するにはどれくらいかかるんだろう、と余計なことに思いを巡らせてしまいました。
TDDは、あくまでも開発手法であって、品質を保証するものではないので品質テストはまた別途必要だよ、ってことがマネージャ陣に理解されてないと、
- テストするのにプログラム書くの?
- そのプログラムは品質保証されてるの?
- そのテストプログラムのテストはどうするの?
- テストプログラムを作るための工数はどうするの?
- お客さんに提出する成果物はプログラムじゃわからないよ
- テストケースがプログラムじゃレビュー時に本質が見えなくなるだろう
- etc…
なんて言われてしまうことが容易に想像できる。まずは理解させるところから始めないとなーとか思うと、めんどいなぁって思ってしまいました。
老害を説得するのに、無駄な労力を使うよりかは、そういうことに理解がある人・組織へ移った方が絶対早い。
Cubby in Action
Cubbyは興味があったけど、前回のセッションが見れなかったので今回は参加。
前半
Cubby1.1が前提の話。
-
特徴
-
シンプル&スモール
-
アノテーション・taglib少しだけ覚えればOK
-
CoolなURIをサポート
- アノテーションorアクションクラス名をURIにしてRESTっぽく
- 正規表現もあり
-
JSP2.0 Love!
-
基本Strutsスタイル
- request→Action→returnをviewに
- URLとコードの紐付け
- リクエストパラメータのバインディング
- 入力バリデーション
- ビューにおける値の出力補助
-
しないこと
- AjaxなJavaScriptコードの生成
- Request/Response以外のスコープ管理
- PDFやExcelなどリッチな出力方式
- 要は、高度なことはしないよ
-
-
ポイント
-
Actionの設計
-
基本コンポーネントの拡張
- Validatorを拡張
- ActionResultを拡張
-
秘密の機能コンバータ
-
Actionの設計
-
デフォルトのActionはほぼ何もしない
-
汎用的な機能を持つ既定クラスを設計する
-
AbstractAction…ログや認証情報など
-
AbstractAction
- AbstractPagerAction…ページング処理
- AbstractMobileAction
- とか
-
基本コンポーネントの拡張
-
汎用バリデーション
- Refererに戻るバリデーション
- MultiEmailAddressValidatior
- JAXB2.0(オブジェクトをXMLに変換)
- APIの提供のために作った
秘密の機能コンバータ
- エンティティとパスのバインディング
前半のまとめ
-
Cubby != フルスタックフレームワーク
-
作りたいものとの間にギャップが…
- そこが工夫のしどころ
-
Strutsの再解釈したフレームワーク
後半
Cubby2.0の機能や特徴について
-
Spring/Guice Integration
-
POJO Action
-
JUnit4
- Annotationベース
-
Validation with Oval
-
improvement of type conversion
実際のコードなどは後日公開されるセッション資料を参照。
45分で動かせるBuri/escafeFlow入門
セッション資料が公開されているので詳細はそちらへ。
BigTableとJDOの勝ちパターン
BigTableの話だけで終わってしまうかも。JDOは時間があれば。
BigTable
-
BigTableは分散HashMapのようなイメージ
- キーの重複はあり
- キーがソートされている
-
だからGoogleではArrayと呼ばれている
-
キーによるアクセスしか出来ない
-
BigTableのキーは以下の3つのパートに分かれる
-
Row
-
Column Group
- プリミティブなデータはデフォルトグループ
- シリアライズされたオブジェクト等も保存できるけど、デフォルトグループではない
-
Timestamp
- データのUpdateではなく、履歴持ちをするため、過去にさかのぼれる
-
BigTable Structure
-
chubby
- 分散ロックサーバ
- キーの取得時にアクセスされ、ルートのTabletサーバのIPアドレスを取得し、そこからデータのある別のTabletサーバへ
-
Tablet Server
-
それぞれ分散されて存在
-
Root Tablet
-
MetaData Tablet
- そのデータがどこのTabletに属するか
-
User Tablet
- データが存在するTablet
- データが増えると、Tabletそのものが分割される
-
各Tabletへ3回問い合わせされる
- 10ms位でアクセス
-
memtable
- 最初Indexだけ読み込まれる
- キーをmemtableで検索して、なければGFSから読み込んでキャッシュする
-
-
GFS
-
SSTable(index, data),log
- ReadOnly
- ディスクに格納
- indexをmemtableにソートされた状態で保存する
-
-
書き込み
-
ジャーナル(log)→メモリに書き込む→GFSへ書き込む
-
メモリ上のデータが大きくなってくると、memtable→SSTableに書き込みを行い、logをクリアする
- マイナーコンパクション
-
スケジューラでディスクに書き込む
- メジャーコンパクション
-
BigTableへのアクセス
-
Read
-
Write
-
Delete
-
上は全てキーによるアクセス
-
Scan
-
Prefix Scan
- 先頭10バイトとか
-
Range Scan
- From,To
-
これらはキーがソートされているから可能
-
Prefix:B
- A
- B1(Hit)
- B2(Hit)
- B3(Hit)
- C
-
Range B,D
- A
- B(Hit)
- C(Hit)
- D(Hit)
- E
-
-
キーのイメージ
-
Parent:aaa
- Parentの部分をkindと呼ぶ(RDBMSのTableのようなもの?)
- aaaがキー
-
Parent:aaa/Child:bbb
-
Parent:aaa/Child:bbb/GrandChild:ccc
-
Parent:xxx
-
Parent:xxx/Chile:yyy
-
-
キーの切り方をEntity Groupと呼ぶ
-
BigTableはトランザクションはサポートしない
-
行へのアクセスをAtomicに保障する
-
Readed Timestamp
-
write Journal
-
Apply Journal
-
updateedCommited Timestamp
- 上記の手順で動いて、Timestampで楽観的排他制御を行うことで、擬似的にトランザクションを扱う
-
-
Scan時には一貫性は保障されない
-
ログには親のキーのみ書き出す
-
BigTableはRDBMSの考え方とは全く違う
- トランザクション
- データの持ち方
- 過去の資産をそのまま流用するのは難しい
BigTableのIndex
-
kind index
-
single property index
-
composite index
- 推奨しないから話さない(使ってない)
-
kind index
-
select * from GrandChild(SQL的に)
- と同義なのはprefix:GrandChild
- kindからGrandChildをサーチして、物理的なキーを返す
- 物理的なキー→Parent:aaa/chile:bbb/GrandChild:ccc
-
-
single property index
-
where name = ‘aaa’(SQL的に)
- と同義なのはprefix:Parent name aaa
- |kind|property|value|
-
where age > 20 && age <= 30(SQL的に)
- <>な検索はRange Scan→keyをget→valueをget
-
where name = ‘aaa’ && age = ‘30’(SQL的に)
- name = ‘aaa’でprefix scan
- age = ‘30’でprefix scan
- それぞれのprefix scanをマージするイメージ(SQLでいうところのmerge join)
- それぞれのprefix scanはパラレルに行われる
-
single property index+order byするときはインデックスが必要
-
その場合はクライアントでSortした方がよい
-
where句は=以外使わない
-
=以外のデータを拾いたいときは、ガッサリ拾って=以外をフィルタリングする
-
order byはwhere句を使わないときだけ制限を受ける
-
-
一回のアクセスで1000件までしか取得できない
- ページング処理でカバー
-
Googleの中の人曰く、
- 非正規化を怖れるな*1
会場からの質問
-
顧客からはたくさんの項目を一度に画面に表示したい、というニーズがある
- JOINできないからそういうときはどうしたらいい?
- 画面の設計を見直したほうがよい
- お客さんにスケールする・コストが下がるというメリットの代わりに、そういう制限があることをわかってもらう必要があるかも
- ミッションクリティカルな場面ではOracleなどのRDBMSは強い
- だけどそれ以外ではBigTableで殆どイケるでしょ
-
全件カウントしたいときは?
- カウントテーブルを作るのが必勝パターン
ライトニングトークス
全体的にはすごくHeavyweightなLTでしたww
*1:!!w