uehaj's blog

Grな日々 - GroovyとかGrailsとかElmとかRustとかHaskellとかReactとかFregeとかJavaとか -

UNIX Magazineのクラウド特集は読んどくべき

2009年春号のUNIXマガジンは凄いおもしろい。Burtfs, iPhoneの話もいいんだけど、クラウド特集は一般雑誌で最もまとまった最新のサマリ情報。(ちょっとアマゾン見たら、売り切れになってプレミア付いてる!!)

しばらく前に買って放置してたんですが、読み直したら最近疑問に思ってたこと多くが整理できた。

上を読んで分かったこと・気づいたことや考えたことをいくつか:

  • ACIDはデータベースの概念だがBASEはOSを含む分散システム全体の概念。
  • CAP定理によりスケーラビリティを得るなら可用性と整合性は排反だが、ミクロに見ればACIDとBASEを1アプリ中で使い分けることができる。アトミックトランザクションが必要なとこはそうする。そうではないところはBASEで。(もともとトランザクションの世界でも、システム全体で完全なロック・排他をするようになってない。そんなことをすると性能が落ちて使い物にならない)
  • BASEが必要な理由はメッセージングが必要で有用な原理と同じ。従来メッセージングミドルウェアを使ってた分野では必然性が理解できる。
  • 結局のところ世界の根源原理はBASEに従っていて、ある特殊条件でACIDが成立しているかのように見える。(一般相対性理論と、特殊相対性理論の関係、あるいは古典物理と量子物理学の関係のよう)
  • GAEでは、予め定義されたテーブル(Kind)内でトランザクション可。これはそのように宣言しないと別マシン上に格納されてしまうかもしれないから。逆に言うと予め定義することで同じ物理マシン上で実行できることが保証される。結果としては「分散トランザクションは出来ないし、しない」ということ。
  • 高度に冗長化された高可用なシステムでは、メモリの意味が変わってきて、ハードディスクがただのバックアップになる。分散ハッシュはそういうことなのだ。
  • スキーマレスDBっつーのはようはアレだ、JavaScriptのオブジェクトみ たいな、GroovyのExpandoみたいな、要はハッシュじゃ。それが永続化されていてクエリできるんだから、「プロトタイプベースオブジェクト指向データベース(PTBOODB)」だ。

これからはエンタープライズクラウドっすよ。SIerや業務システム開発の業種の主戦場は5年後にはクラウドに移行していることでしょう。結局世の中は金で動いているがゆえに(後で書く)

おーい、雲よ!

クラウドという言葉を特に良く聞くようになってきた今日この頃です。ユニマガも特集してましたね。Google Apps Engineも晴れて待望のJava対応になりました。ちょっとまとめますと:

  • ビューはJSPを使うらしい
  • servletも使える。基本的にJava eeのWAR部分。ただしwarをそのままデプロイできるわけではない(フォルダ構成は似ている)。
  • データベース周りは、JPA/JDOなどを利用。DataNucleus Access Platformという、とあるJPAエンジン(ORマッピングフレームワーク)を使うのですが、この人は「BigTable用プラグイン」として下位層をGoogleBigTableを使える。つまりJPQLをつかうんですかね。
  • トランザクション周りは謎。
  • 分散ハッシュとしてMemcacheServiceというのがある。memcachedプロトコルとの関係は不明。

興味があるのが、従来のエンタープライズシステム開発がこういうクラウド環境上に移行できるのかどうか。例えば、金融処理とか受発注処理とかが。いや、いままでもクラウド環境はあったのですが、単に仮想環境だったりして、イメージがわかなかった。GoogleのはこれはJavaベースで(JRuby とかも動くらしい)あり、がぜん現実味が増してくるってものじゃないですか。

もし、従来悩ませてきた性能問題を、マシンパワー任せ(金任せ)でスケーラブルに回避しきれるなら、インハウスでDBMSを持つ必然性が減っていく(セキュリティや情報を外に出すことの問題はあるにせよ)ので、それと比較すべきコストの問題(というよりトータル所有コストの問題)が我々の開発をクラウドに乗せていく必然性と可能性を徐々に高めていくでしょう。

その可能性に関してポイントとなるのが、クラウドのブームの中で広まっているBASE(basically available, soft state, eventually consistent)という考えかた。従来のACIDにおけるトランザクションという単位で宇宙の状態を確定させたい・させよう、という便宜上の考えに対して生まれてきた、異なる考え方です。

トランザクションが終わっていれば状態は確定する」というのは開発者にとっては理解しやすいのですが、性能がスケールしない、マシン数の増大によってスケールさせられないという脱却不能な問題があります。

これに対して、BASEは、トランザクションというでかい祖粒度の(利便性の高いわかりやすい)単位ではなく、多数の条件の複合体として、状態の確定条件を単純には決めない。最終的には確定しないわけには行かないんだけど、それを可能な限り(便宜上必要なだけ)遅らせるようなものかと理解しています。トランザクションの様に、一歩一歩確定させながら進めるということをあきらめるのです。

変に例えると、ACIDが古典物理学的であるとするなら、BASEは量子論的である気がする。

将来のエンタープライズクラウド上で整合性保証のために用いられるプログラミング技術は、ACID より遥かに理解しにくい、複雑なものになるでしょう。いままでトランザクションモニタという黒子がやってきた処理のパンドラの箱が開いて、平均的なプログラマがそれをやらなければならないようになるのは悪夢です。ある種のパラダイムシフトが必要なんじゃあないでしょうか。

ただ、そもそも「エンタープライズシステムをクラウド環境にのっけるの?」という話はあるでしょう。それに対抗できる言説はただ金つまりコストの問題をもとにしたものでしょう。今後未来永劫、毎年毎年マシンの維持管理及びリプレース費チューニング費に何千万何億やっぱり払うのかどうかです。それはたぶん、許されない。(現状では単独の経済性の問題として必ずしもクラウド環境の方が安いとも言えないみたいですけど)。

あと、スケーラビリティの問題、つまりユーザ数が数百倍になったりデータ数が数百倍になったときに、それを突破的に解決できる望みは、今のところクラウドさんちのところにしかないのです。インターネットサービスほどでは無いにせよ、僕らがイントラシステムなどを開発するときに直面する技術的(かつ致命的な)問題の大きな割合を性能問題が占めることを考えると、その可能性を無碍に切り捨てるというわけにはいかないし、あと最低10年はこの業界にいるつもりがあるエンジニアとしては見ておかないわけにはいかない。

参考リンク。

Java 7の文法上の変更

上の参照先にJava7の言語仕様変更に関する具体的な構文がでていたのでちょっとメモ的に。

try {
  ...
} catch (final Throwable t) {
  throw t;
}

この目的は、「catchした例外を、(なんかして)、そのまま rethrowする」というような、というような、透過的な例外の処理をする際に生じる問題を解決すること。例えば、「何でもいいから起きた例外をロギングする」という場合、

  ..
} catch (Throwable t) {
   System.out.println(t);
   throw t;
}

とするわけだが、これだとこのcatch節を含むメソッド全体にthrows Throwable;という例外宣言をする(かあるいはtryで囲む)ことになる。実際には起きる例外が変わったわけじゃないのに。なのでcatch (final Throwable t) のようにfinalつけると、例外宣言変更とか例外の周囲をいじらずに、キャッチした例外をそのまま上げることが可能になる。
(感想)
使うシチュエーションは限られていそうだがはまれば嬉しそう。フレームワーク内とかでは使うかな?予約語使い回しっぽくて、検索性が悪そうだな。

catch (IOException|SQLException ex) {

みたいな。同内容のcatchブロックを簡潔に表記できる。
(感想)
便利そうではあるが|はちとキモイな。

Swing Frameworkに私としては期待。Beans Bindingがないのは残念だが。

djUnitのススメ

djUnitというのは、ユニットテストをするためのEclipse のプラグインであります。機能的にすぐれていて、かつ情報もまとまっていて大変よろしいです。

* http://works.dgic.co.jp/djwiki/Viewpage.do?pid=@646A556E6974

djUnitには、JUnitを呼び出して実行するユニットテストの機能に加えて、2つの機能があります。

(1)カバレッジ
(2)相互作用テスト

(1)に関してここでは説明しませんが、djUnitカバレッジを取るのは非常に簡単で直感的です。内部的にはjcoverageを呼んでいるようです。

お勧めしたいのが(2)の相互作用テストで、これってのは、「あるメソッド呼び出しをきっかけとして、どんなメソッド呼び出し(回数・引数・返り値)が引き続いて発生するのか」をチェックするものです。基本的に「メソッド呼び出しの結果そのオブジェクトの状態がどう変化するのか」しか試験できないUnitテストよりはるかに強力です。(もちろん、ユニットテストが無意味だということではなくて、向き不向きがあって、ユニットテストでは試験できない領域があるということ。)

なお、相互作用テストは「モックを用いたテスト」とかいう、意味の分かりにくい呼び方をされることもありますが、「相互作用試験」と覚えておけば理解が早いです。実際、djUnitを使う限りモックオブジェクトなる概念の存在を意識する必要がありません。

Groovy Eclipse を組み込んでおけばちゃんとGroovyでdjUnit試験を書くこともできます。ただし、テストメソッドの戻り値の型はdefじゃなくてvoid型にしておかないといけないみたいです。

import junit.framework.TestCase
import jp.co.dgic.testing.framework.DJUnitTestCase

public class HelloTestGroovy extends DJUnitTestCase {
	void testHello() {
		Hello.main(["abc","def"] as String[])
		def arg = getArgument("java.io.PrintStream", "println", 0)
		assertEquals("Hellox", arg);
	}
}

上で例えばdef testHello()だとテストメソッドとして認識してくれません。
あと、試験結果のツリービューからテストコードのGroovyソースにジャンプできないなど、多少問題がありました。


参考: http://d.hatena.ne.jp/uehaj/20080701/1214894591

.NETプラットフォームでJavaコードをコンパイル&実行できるSDK「Ja.NET SE」

Ja.NET

これって、さりげなくすごくね?Visual J#との関係は? Groovy.NET、Grails.NETがいながらにして実現?JRuby.NETとかも可能か。
.NET CLR上だとJVMより速かったりして。
JavaNews経由。

(追記)
http://www.infoq.com/jp/news/2008/12/Ja-NET
をみると、コンパイラEclipse JDTベースで.NET ILを吐くようにしたもの、ライブラリはApache Hermonyベースとか。

Javaへのクロージャ導入は、苦労じゃ?

http://www.infoq.com/jp/news/2007/12/closures-preserving-feel-of-java

留意しておきたいことは、既にJVM向けのすばらしいプログラミング言語があって両者を提供しており、さらにJavaの相互運用性も備えていることです。

ふむふむ。

それはScalaです。

ずこー。


私個人の意見を言うと、Javaへのクロージャ追加は、あまりよいことのように思えません。


「Groovyがあるから」ということはおいておいても、機能拡張を際限なく、しかも互換性をいったん断ち切るのならともかく、後方互換性を保ちつつやろうとすると、なんでもありの化け物言語になる可能性が高いわけです。
前回書いたJSPの難解さとかが悲惨な一つの例で、難易度を下げようとする努力の結果が、互換性に足を引っ張られて、継承階層構造を複雑にするなど、逆効果になってドつぼに陥っているという面があると思っています。


言語としての「一分(いちぶん)」を知るというか、本来の初心としての言語ミッション、みたいのを固く守って、流行にあわせてつらつら変えていかないほうが言語寿命が延びるのではないかと思う。今Cが滅びていないのも、C++との役割分担というかすみわけがうまくいったからではないかと思います。

Javaの延長線としてのGrails

もともとのJavaの基本理念として、マシン依存・OS依存なコードのみをCで書く、という役割分担の考え方があります。Grailsが訴求しているのは、その考え方(役割毎の言語分担)と似たところがあります。つまり、インプリメンテーション依存、プラットフォーム依存な部分を極力業務specficコードから除去分離しよう、ということです。結局のところ、DIも、LLも、CoCもAOPもORMも、このための実現技術とみることができます。Grailsがこれらすべての結集であることが、Grailsを単なるWebアプリフレームワークではなく、特筆すべき重要な技術だと位置づけるべき理由です。というようなことを山田さんやみなさんが考えられているのかなーとここしばらくつらつらGrailsをいじっていて思いました。いやもちろん、「簡単な高生産性Webアプリフレームワーク」であることも、重要なことではありますが、それ以外のものもある、と。


CoCもDIもLLもAOPもORMも、それぞれ当然単独で有用な技術なのですが、「なんのために」を考えることで構図(技術の大局的な流れ)がクリアになってきます。