BT

最新技術を追い求めるデベロッパのための情報コミュニティ

寄稿

Topics

地域を選ぶ

InfoQ ホームページ ニュース Rubinius GemstoneのOODBがJRubyとRubiniusをサポート

Rubinius GemstoneのOODBがJRubyとRubiniusをサポート

SmalltalkベースのGemstone/S(製品サイト・英語)やJavaベースのFacets(製品サイト・英語)のようなオブジェクト指向データベースの開発元であるGemstone(サイト・英語)は、自社製品のRubyサポート化に取り組んでいる。要するにJRubyはFacetsのサポート対象になるということであり、Rubinius(サイト)がGemstone/Sに似ている機能を取り入れて非JRubyユーザーのために使われるということである。

オブジェクト指向データベースを使用する事より、オブジェクトグラフを透過的に永続化することが可能である。このことはリレーショナルデータベース(RDBMS)を使用することと対照的であり、オブジェクトデータをテーブルに格納しなければならない。O/Rマッピングも同様である。オブジェクトとRDBのマッピングは手動で行われ、RubyのActiveRecord又はJavaのHibernateのようなツールやライブラリ等の助けを借りて、開発者はテーブルにデータを保存する。

GemstoneのAlan McKean氏は我々InfoQにGemstoneとRubyに関する最近の開発に関して詳細を話してくれた。
Alan氏はこれらの取り組みが手がけている製品にどのように取り入れられるかを説明してくれた。
GemStoneはオブジェクト指向データベース製品を二つ扱っています。一つはJava向けの製品でFacets、もう一つはSmalltalk向け製品でGemStone/Sと言います。我々GemStoneはFacetsをJRubyへ、GemStone/SをRubiniusに対応させる予定です。JRubyプロジェクトが既に1.0としてリリースされているので、我々はJRuby1.0上でデモを動かしています。 現時点ではデモは問題なく動いているようです。これらの製品を使うには我々GemstoneのJVMをダウンロードする必要があります。 (JVMはSunからライセンスされており、Javaオブジェクトの透過的な永続化を可能にするために我々はバイトコードを手直ししました。)我々が手直ししたJVMは、若干(私のテスト上では5%程)現時点のSunのJVMより遅いのですが、理由は永続化処理と共に他の処理が動いているからです。
アラン氏は、JRuby実行時に現在の実装の詳細に起因した若干の問題を取り扱うために、JRubyチームとともに活動している。
JRubyの実装に解決すべき問題がひとつあり、私は修正案をJRubyチームに提出しました。JRubyは現在シリアライズや我々Gemstoneの永続化スタイルをサポートしていません。理由は全てのRubyオブジェクトはJRubyのランタイム(スレッド、動的メソッド、及び他の内部的なオブジェクト)に対して直接参照しているからです。Rubyオブジェクトがシリアライズ又は永続化される際、ランタイムシステムを直接参照しランタイムシステムと共に存在しているので、ランタイムシステムからオブジェクトを分離し、シリアリゼーションと透過的な永続化を可能にする方法を私は見つけました。シリアライズや永続化がが行われると、我々の永続化エンジンは動きました。
どのようにしてGemstoneと共にJRubyを使用しているのかを知るための永続化オブジェクトを作るサンプルコードが以下に続く。
# to persist an object in one VM  declare a
# persistent 'root' that allows access to objects with the
# 'name' of the object
# VMにオブジェクトを永続化するためにはpersistent 'root'を宣言してください。
# このように宣言するとnameという属性を持ったオブジェクトにアクセス出来ます。
persistent :people => :name


# begin a transaction, put a Ruby object and all objects that are
# connected to it into the persistent root, and commit it
# トランザクションを開始して、Rubyオブジェクトと、そのRubyオブジェクトに
# 含まれるRubyオブジェクトをpersistent root宣言したpeopleに追加してコミットしてください。
p = Person.new('Alan')
p.children << Person.new('Jimmy')
p.children << Person.new('Janie')
transaction
people << p
commit


# in another VM
# 他のVM上で
persistent :people => :name
p = people['Alan']
puts p.name
p.children.each do { |child| puts child.name }

Alan氏はAPIのデザインと、どのようにしてRailsから使う事が出来るのかということを説明してくれた。
透過的な永続化用APIのデザインを現在行っているところです。Railsでは、transactやcommitは使わないですよね。サンプルコードで見たようにpersistent rootを宣言し、オブジェクトをpersistent rootに追加するだけで良いのです。
リクエストが起きた時にトランザクション境界が生成され、レスポンスが返される直前にコミットされる。OODB風のやり方をActiveRecordと比較すると利点はより明白になる。
ActiveRecordの多くがオブジェクトとリレーショナルデータベース間のインピーダンスミスマッチを解消するために存在しているので、インピーダンスミスマッチがなくなればActiveRecordは必要なくなるでしょう。例えば、belongs_toやhas_manyなどは関連(データベース上の外部キー)をサポートします。そしてそれらはOODBでは必要ありません。同様にacts_as_listなども必要ないです。ActiveRecordが、DRY原則に違反している二重の概念を多く必要としているのが面白いですね。Rubyクラスで関連を宣言して、更にデータベースのスキーマで外部キーを設定するなんてことをしなくても良いのです。しかし我々はフィルター、バリデーション等をサポートしたいと思っています。

しかし我々はフィルター、バリデーション等をサポートしたいと思っています。ActiveRecordと違い、OODBのRubyオブジェクトは、ある特定クラスのサブクラスとして定義する必要がないので、それが正確にActiveRecordと同じように見えるかどうかは疑わしいです。ActiveRecordが持つその他の問題点はサブクラス化です。透過的な永続化処理は、その問題点を解決します。リレーショナルデータベース(わずかなテーブル又はテーブル結合で)ではクラスの継承関係を表す良い解決策がありません。我々の永続化処理技術を使うと、クラスの継承関係をリレーショナルデータベース上で表す処理が自動的にサポートされます。中心となるコンテンツをサブクラス化し、どんなモジュールでも良いので、それをドメインクラスにミックスインしてみてください。ちゃんと動きますよ。
Alan氏は技術的な詳細に続いて、GemstonカスタムなJVMがどうやって永続化処理を実現しているのかという点を説明してくれた。
我々GemstoneはRubyオブジェクトをJavaで表したものを永続化します。JRubyオブジェクトは、インスタンス変数のマップを持ったシンプルなJavaオブジェクトです。それはイメージベースではありません。私がJRubyチームへ送った修正によってシリアライズが可能になりますが、我々はシリアライズを使用しません。 我々の永続化技術はページキャッシングに基づいています。8キロバイトの小さなページメモリが、コミットの時にフラッシュされ、アプリケーションがオブジェクト参照を使用するようになるので、ページは永続化を行った状態から停止状態に変わります。オブジェクトは同じページメモリに集約する傾向があるので、ページが一旦送られると、ほとんどページングが行われません。

Rubyオブジェクトの構造は洗練されていません。同じRubyクラスのインスタンスでも、異なった構造をしています。何故上記のようなことになるのでしょうか?理由はRubyの場合インスタンス上で実行されるメソッドによりインスタンス変数が動的に追加されるからです。だからRubyの場合、オブジェクトの構造は生存期間中に、どのようなメッセージを送られたかによってそれぞれ異なるのです。Rubyのこのような点はインスタンス変数をクラス内で静的に宣言しているJavaやSmalltalkとは非常に異なるところです。だからRubyオブジェクトのマイグレーションは大きな問題にはなりません。サポートの意味をなす必要条件がいくつかあります。例えばインスタンス変数を宣言しているメソッドがクラス定義から取り除かれたときインスタンス変数や、そのインスタンス変数に関連した値を取り除く事です。しかし我々は管理業務タスクとして、その点はツールによってサポートされるようになるだろうと考えています。
GemstoneによるRubyサポートの他のブランチはRubinius上で動くようになるだろう。 Rubiniusとは、RubyのVMであり、それはほとんどRubyで書かれている。またRubinius はSmalltalkから収集した概念を取り入れて作られている。 (infoQは最近Rubinius開発者のEvan Phoenix氏とのインタビュー記事を書いた。Rubinius VM Internals(英語)Rubinius Internals like ObjectSpace and Threading(英語)を参照してほしい。)
ところで、Rubinius VM上での進展に関して引き続き注目していてください。それはJRuby上では動きませんし、我々のJVMを使う必要がありません。Rubinius VMが我々の必要条件を確実にサポートしてもらうように、我々はEvan Phoenix氏と共に活動しております。それから、おそらくgemをインストールして、我々の永続化技術を使うようになるでしょう。1サーバー当たりデータリポジトリは4GBまでという制限付きですが、無料で製品を提供することが我々の意向です。それは我々がSeasideフレームワークでやっていたことと同様です。4GB以上のデータ領域が必要だったり、複数サーバーに対してスケールしたい場合は、ライセンスの購入が必要になります。
Gemstoneは、新しいウェブフレームワークとツールをサポートするのに忙しかったのだ。新しいRubyサポートの次に、Seaside(サイト・英語)フレームワークは同様にサポートされる。
我々の永続化処理技術をSmalltalkのシーサイドフレームワークに適用しており、今秋リリース予定です。Seasideのアプローチは我々がRubyやRailsに対して行おうとしていることと非常に似ています。
最初の発表はGLASSである。GLASS(サイト・英語)とはGemstone/Linux/Apache/Smalltalk/Seasideのそれぞれの頭文字を並べたものである。

原文はこちら:http://www.infoq.com/news/2007/08/gemstone-ruby

この記事に星をつける

おすすめ度
スタイル

BT