メニュー

関連ページリンク

トップ > 129 > 129 - 人気ブログ(Blog)検索結果詳細 (2009年1月9日 9時)

[DB][Java] RDBMSをKey-Value Storageとして使う場合のパフォーマンス計測(H2, MySQL編)

Tokyo Cabinet, QDBM, Lux IOなど、DBM同士のパフォーマンス比較はWebで良く見かけるのですが、MySQLのような普通のRDBMSをKey-Value Storage的に使用した場合、DBMと比べてどれくらい差が付くものなのかイメージが湧かなかったので、実際に計測してみました。

Javaプログラムから、Berkeley DB、H2、MySQLの3種類のストレージを使用しました。条件は以下の通りです。

  • Berkeley DB Java Edition 3.3.75
    • デフォルト設定
  • H2 1.1.106
    • jdbc:h2:file:~/dbmbench
    • Embeddedモードで使用
    • デフォルト設定
    • DDLは以下を使用
create table casket (
  id integer auto_increment primary key,
  key_ varchar(255) binary not null,
  value blob not null
);
create index key_ on casket(key_);
    • insert文は以下を使用
insert into casket (key_, value) values (?, ?)
    • select文は以下を使用
select * from casket where key_ = ?
  • MySQL 5.0.45
    • jdbc:mysql://localhost/dbmbench
    • InnoDBを使用
    • innodb_buffer_pool_size = 256M
    • innodb_flush_log_at_trx_commit = 0
    • DDLは以下を使用
create table casket (
  id integer auto_increment primary key,
  key_ varchar(255) binary not null,
  value blob not null,
  index (key_)
);
    • insert文、select文はH2と同じ

その他の条件は以下の通りです。

  • Mac OS 10.5.6
  • 2GHz Intel Core 2 Duo, 4GB Memory
  • JVM引数は-Xmx512m
  • keyは8バイト固定。"00000000", "00000001", "00000002", ...
  • random insert, random select
  • 5回ずつ計測し、中央値を採用

レコード数による比較

valueの長さを10バイトに固定して、レコード数を1000から1000000まで変えた計測結果が以下です。時間の単位はmsです。

DBRecord
Count
Value
Length
InsertSelectInsert
/ Record
Select
/ Record
Berkeley1000101390.0130.009
Berkeley1000010120350.0120.0035
Berkeley1000001011705640.01170.0056
Berkeley1000000101334777390.01330.0077
H210001028210.0280.021
H210000103762410.03760.0241
H210000010596054770.05960.0548
H210000001098088834930.09810.0835
MySQL1000102462530.2460.253
MySQL1000010201127570.20110.2757
MySQL1000001020538295110.20540.2951
MySQL1000000102031483040980.20310.3041

上の表をグラフ化したものが以下です。まず合計処理時間です。

f:id:kaiseh:20090108233147p:image

1レコード当たりの処理時間です。

f:id:kaiseh:20090108233146p:image

レコードサイズによる比較

次は、レコード数を10000に固定して、valueの長さを100バイトから10000バイトまで変えた計測結果です。

DBRecord
Count
Value
Length
InsertSelectInsert
/ Record
Select
/ Record
Berkeley10000100135530.01350.0053
Berkeley10000500134470.01340.0047
Berkeley100001000205480.02050.0048
Berkeley1000050009051330.09050.0133
Berkeley100001000018192670.18190.0267
H2100001003612550.03610.0255
H2100005005994760.05990.0476
H21000010007734290.07730.0429
H21000050001620218731.62020.1873
H210000100001754418561.75440.1856
MySQL10000100255927850.25590.2785
MySQL10000500292928300.29290.283
MySQL100001000380528730.38050.2873
MySQL100005000779930440.77990.3044
MySQL10000100001902032441.9020.3244

上の表の合計処理時間グラフです。

f:id:kaiseh:20090109005215p:image

1レコード当たりの処理時間のグラフです。

f:id:kaiseh:20090109005216p:image

考察

本エントリーの計測条件において、Berkeley DBは、RDBMSをDBM的に使った場合に比べて、数倍から十数倍程度速いようです。特に、valueのサイズが増加したとき、H2とMySQLではある地点を境に急にパフォーマンスが劣化するので、Berkeley DBの優位性が際立ちます。

Tokyo CabinetやLux IOはBerkeley DBよりもさらに優秀とのことなので、RDBMSの十数倍から100倍くらいは速くなるんじゃないかと思います。

作者:kaiseh

更新日:2009年1月9日 0時34分

このブログのホーム

[Misc] 2008年の振り返りと2009年の抱負

明けましておめでとうございます。

僕の2008年を振り返ると、その前年の1981s忘年会で刺激を受けて、自分も面白いアウトプットを出したいと思ったことから始まった気がします。

TopHatenarを作ったのが5月ですが、その基礎になるデータ自体は、何かの材料にならないかと思って、1月頃からクロールしていました。いろいろとデータをこねくり回して試行錯誤した後、結局はシンプルにグラフ化するのが一番楽しいのではという結論になり、TopHatenarとして公開しました。その直後からとてつもないアクセスが集まって、本当にびっくりしました。

その後もHatenarMapsNewsgraphyが評価をいただき、gihyo.jpでの連載、書籍のレビュー、Web 2008 Expoでの講演など、とても貴重な経験をさせていただきました。またそれを通じて、第一線で活躍されている多くの方と知り合うことができました。視野が大きく広がった1年だったと思います。

一方S2Swingの方は、11月にようやく初版公開までたどり着いたものの、なかなか前に進むことができず、自分の力不足を痛感させられました。ソフトウェアの仕様を作るということの難しさが良く分かりました。

今年は、まずS2Swingに力を入れて、使いやすいフレームワークに育てていくことを目標にします。それから、これまで作ったWebサービスを、ニッチから抜け出すような何かに昇華できれば良いなと思います。

例えば、TopHatenarやHatenarMapsの対象を全ドメインに拡大して、日本のブログ界を総覧できるような存在まで持っていければ、かなりインパクトが出てくるんじゃないか、などと思っています。

今年もよろしくお願いいたします。

作者:kaiseh

更新日:2009年1月1日 23時21分

このブログのホーム

[WebService] TopHatenar+HatenarMapsのシステム構成

TopHatenarHatenarMapsのシステム構成が、バージョンアップの度に複雑化してきて、自分でも把握しづらくなってきたので、整理する意味で図を作ってみました。

f:id:kaiseh:20081229155324p:image

図に示したように、HatenarMapsは、S2RMIを使ってTopHatenarと協調動作しています。はてなダイアリーとはてなブックマークに関するデータをクロールしているのは、TopHatenarの側です。HatenarMapsの側では、TopHatenarのService層をS2RMI経由でコールして、集計済みのはてブ情報を取得し、クラスタリング処理の後にポリゴンを計算しています。その他、HatenarMaps上でコメントビームの表示等がリクエストされる度に、TopHatenarをコールしています。よって、HatenarMaps側のDBには、基本的にポリゴンデータしか入っていません。

以下、図中に出てくるフレームワークやライブラリについて紹介します。

JFreeChart

http://www.jfree.org/jfreechart/

Javaのチャートライブラリの決定版です。ほぼあらゆる種類のグラフを描くことができます。高機能すぎて、Javadocを読んだだけでは目的のクラスやメソッドを見つけ出すのが難しいほどです(笑)。

Ehcache

http://ehcache.sourceforge.net/

Javaの汎用キャッシュライブラリです。TTLやディスクキャッシュの使用可否をXMLファイルで簡単に設定できて、気軽に使えます。memcachedより高速という情報もあります。

TopHatenarはブログパーツを多くの方に貼っていただいているので、キャッシュが非常に重要ですが、今のところミスヒット率は10%未満と、良好な結果が出ています。

Cubby

http://cubby.seasar.org/

RESTっぽいURIを簡単に扱えることが特徴の、軽量なWebフレームワークです。重宝してます。

Mayaa

http://mayaa.seasar.org/

HTMLテンプレートエンジンです。テンプレートを奇麗なHTMLで書ける上に、JavaオブジェクトをJavaScriptの式で参照できたり、レイアウト共有機能(HTMLのコンポーネント化)が秀逸だったりとメリットが多いので、Cubbyと組み合わせて使っています。

S2JDBC

http://s2container.seasar.org/2.4/ja/s2jdbc.html

JPAの改良版的な位置付けのO/Rマッパーです。Genericsや可変長引数をフル活用した「流れるようなインターフェイス」によって、DBアクセスコードを簡略化できます。

S2RMI

http://s2rmi.seasar.org/ja/

DIコンテナに登録された任意のオブジェクトを、アノテーション等一切不要でJava RMI対応にできてしまうという、DI+AOPの真価を見せつけてくれる素晴らしいライブラリです。

S2Flex2

http://s2flex2.sandbox.seasar.org/ja/

これを使うことで、FlexからJavaオブジェクトを簡単に呼び出せるようになります。通信にはAMF3が使われるので高パフォーマンスです。

ちなみにHatenarMapsではFlex 3を使っているので、今度S2Flex2の代わりにS2BlazeDSも試したいと思っています。

最後に

こうして見ると、TopHatenarとHatenarMapsは、かなりSeasar色に染まってますね。JavaでWebサービスを作るとき、Seasarファミリーはとても役に立つと思います。

作者:kaiseh

更新日:2008年12月29日 17時5分

このブログのホーム

[WebService] HatenarMapsのブログパーツを開始しました

HatenarMapsでの領地の状況を、ブログパーツとして貼れるようにしてみましたので、ぜひご利用ください。

こんな感じの画像を埋め込むことができます。

f:id:kaiseh:20081227210844p:image

貼り付け用のHTMLサンプルは以下になります。"XXXXXXXX"の部分を、自分のはてなIDに書き換えてください。

<a href="http://hatenarmaps.com/view/XXXXXXXX"><img src="http://hatenarmaps.com/chart/XXXXXXXX" width="160" height="120"/></a>

指定されたIDの領地が存在しない場合は、今のところ、1×1ピクセルの空白の画像が返ってくる仕様になっています。

その他

ブログパーツ機能以外にも、HatenarMapsに2点修正を加えました。

  1. マウスホイールでの拡大・縮小に対応しました。
  2. 年表で、領地の面積推移を棒グラフ表示するようにしました。

よろしくお願いします。

作者:kaiseh

更新日:2008年12月27日 21時17分

このブログのホーム

[WebService] 新HatenarMapsのFAQ

新しいHatenarMapsについて、ブクマコメント等でいろいろ疑問をいただいているので、FAQにまとめました。

○○について書いたことが一度もないのに、○○地区に入っています。何で?

できるだけ適切(?)な地区に入るようにしていますが、クラスタリングの性質上、そのようなことも起こり得ます。今後も継続して、精度の向上を目指していきますのでご了承ください。

TopHatenarでブックマーク数3000位以内なのに、HatenarMapsに載っていません。何で?

ブックマーク総数が多くても、タグの付与数が一定基準に達していない場合、ブログの特徴を判断することが難しいので、HatenarMapsの表示対象外になります。

個別エントリーが領地を獲得する基準は?

現在の日付を基準に、過去1年間に書かれたエントリーの中から、ブックマーク数が多い順に最大10エントリーが領地を獲得します。ただし、5users未満のエントリーは対象外です。

個別エントリーが領地を失う基準は?

2つのケースが考えられます。

  1. エントリーを書いてから1年以上経過した。
  2. 同一のユーザが後発で書いた他のエントリーがより多くのブックマークを獲得したため、最大10エントリーの枠から押し出された。

実際のブログや個別エントリーのURLにジャンプするには?

地形をダブルクリックしてください。

島の外形の由来は?オーストラリア?

ドラゴンクエスト3の「ランシール」という大陸です。中心部に「地球のへそ」と呼ばれる、主人公が勇気を試されるダンジョンがあります。

f:id:kaiseh:20081225233550p:image

作者:kaiseh

更新日:2008年12月26日 0時6分

このブログのホーム

[DB][Java] RDBMSをKey-Value Storageとして使う場合のパフォーマンス計測(H2, MySQL編)

Tokyo Cabinet, QDBM, Lux IOなど、DBM同士のパフォーマンス比較はWebで良く見かけるのですが、MySQLのような普通のRDBMSをKey-Value Storage的に使用した場合、DBMと比べてどれくらい差が付くものなのかイメージが湧かなかったので、実際に計測してみました。

Javaプログラムから、Berkeley DB、H2、MySQLの3種類のストレージを使用しました。条件は以下の通りです。

  • Berkeley DB Java Edition 3.3.75
    • デフォルト設定
  • H2 1.1.106
    • jdbc:h2:file:~/dbmbench
    • Embeddedモードで使用
    • デフォルト設定
    • DDLは以下を使用
create table casket (
  id integer auto_increment primary key,
  key_ varchar(255) binary not null,
  value blob not null
);
create index key_ on casket(key_);
    • insert文は以下を使用
insert into casket (key_, value) values (?, ?)
    • select文は以下を使用
select * from casket where key_ = ?
  • MySQL 5.0.45
    • jdbc:mysql://localhost/dbmbench
    • InnoDBを使用
    • innodb_buffer_pool_size = 256M
    • innodb_flush_log_at_trx_commit = 0
    • DDLは以下を使用
create table casket (
  id integer auto_increment primary key,
  key_ varchar(255) binary not null,
  value blob not null,
  index (key_)
);
    • insert文、select文はH2と同じ

その他の条件は以下の通りです。

  • Mac OS 10.5.6
  • 2GHz Intel Core 2 Duo, 4GB Memory
  • JVM引数は-Xmx512m
  • keyは8バイト固定。"00000000", "00000001", "00000002", ...
  • random insert, random select
  • 5回ずつ計測し、中央値を採用

レコード数による比較

valueの長さを10バイトに固定して、レコード数を1000から1000000まで変えた計測結果が以下です。時間の単位はmsです。

DBRecord
Count
Value
Length
InsertSelectInsert
/ Record
Select
/ Record
Berkeley1000101390.0130.009
Berkeley1000010120350.0120.0035
Berkeley1000001011705640.01170.0056
Berkeley1000000101334777390.01330.0077
H210001028210.0280.021
H210000103762410.03760.0241
H210000010596054770.05960.0548
H210000001098088834930.09810.0835
MySQL1000102462530.2460.253
MySQL1000010201127570.20110.2757
MySQL1000001020538295110.20540.2951
MySQL1000000102031483040980.20310.3041

上の表をグラフ化したものが以下です。まず合計処理時間です。

f:id:kaiseh:20090108233147p:image

1レコード当たりの処理時間です。

f:id:kaiseh:20090108233146p:image

レコードサイズによる比較

次は、レコード数を10000に固定して、valueの長さを100バイトから10000バイトまで変えた計測結果です。

DBRecord
Count
Value
Length
InsertSelectInsert
/ Record
Select
/ Record
Berkeley10000100135530.01350.0053
Berkeley10000500134470.01340.0047
Berkeley100001000205480.02050.0048
Berkeley1000050009051330.09050.0133
Berkeley100001000018192670.18190.0267
H2100001003612550.03610.0255
H2100005005994760.05990.0476
H21000010007734290.07730.0429
H21000050001620218731.62020.1873
H210000100001754418561.75440.1856
MySQL10000100255927850.25590.2785
MySQL10000500292928300.29290.283
MySQL100001000380528730.38050.2873
MySQL100005000779930440.77990.3044
MySQL10000100001902032441.9020.3244

上の表の合計処理時間グラフです。

f:id:kaiseh:20090109005215p:image

1レコード当たりの処理時間のグラフです。

f:id:kaiseh:20090109005216p:image

考察

本エントリーの計測条件において、Berkeley DBは、RDBMSをDBM的に使った場合に比べて、数倍から十数倍程度速いようです。特に、valueのサイズが増加したとき、H2とMySQLではある地点を境に急にパフォーマンスが劣化するので、Berkeley DBの優位性が際立ちます。

Tokyo CabinetやLux IOはBerkeley DBよりもさらに優秀とのことなので、RDBMSの十数倍から100倍くらいは速くなるんじゃないかと思います。

作者:kaiseh

更新日:2009年1月8日 15時34分

このブログのホーム

[Misc] 2008年の振り返りと2009年の抱負

明けましておめでとうございます。

僕の2008年を振り返ると、その前年の1981s忘年会で刺激を受けて、自分も面白いアウトプットを出したいと思ったことから始まった気がします。

TopHatenarを作ったのが5月ですが、その基礎になるデータ自体は、何かの材料にならないかと思って、1月頃からクロールしていました。いろいろとデータをこねくり回して試行錯誤した後、結局はシンプルにグラフ化するのが一番楽しいのではという結論になり、TopHatenarとして公開しました。その直後からとてつもないアクセスが集まって、本当にびっくりしました。

その後もHatenarMapsNewsgraphyが評価をいただき、gihyo.jpでの連載、書籍のレビュー、Web 2008 Expoでの講演など、とても貴重な経験をさせていただきました。またそれを通じて、第一線で活躍されている多くの方と知り合うことができました。視野が大きく広がった1年だったと思います。

一方S2Swingの方は、11月にようやく初版公開までたどり着いたものの、なかなか前に進むことができず、自分の力不足を痛感させられました。ソフトウェアの仕様を作るということの難しさが良く分かりました。

今年は、まずS2Swingに力を入れて、使いやすいフレームワークに育てていくことを目標にします。それから、これまで作ったWebサービスを、ニッチから抜け出すような何かに昇華できれば良いなと思います。

例えば、TopHatenarやHatenarMapsの対象を全ドメインに拡大して、日本のブログ界を総覧できるような存在まで持っていければ、かなりインパクトが出てくるんじゃないか、などと思っています。

今年もよろしくお願いいたします。

作者:kaiseh

更新日:2009年1月1日 14時21分

このブログのホーム

[WebService] TopHatenar+HatenarMapsのシステム構成

TopHatenarHatenarMapsのシステム構成が、バージョンアップの度に複雑化してきて、自分でも把握しづらくなってきたので、整理する意味で図を作ってみました。

f:id:kaiseh:20081229155324p:image

図に示したように、HatenarMapsは、S2RMIを使ってTopHatenarと協調動作しています。はてなダイアリーとはてなブックマークに関するデータをクロールしているのは、TopHatenarの側です。HatenarMapsの側では、TopHatenarのService層をS2RMI経由でコールして、集計済みのはてブ情報を取得し、クラスタリング処理の後にポリゴンを計算しています。その他、HatenarMaps上でコメントビームの表示等がリクエストされる度に、TopHatenarをコールしています。よって、HatenarMaps側のDBには、基本的にポリゴンデータしか入っていません。

以下、図中に出てくるフレームワークやライブラリについて紹介します。

JFreeChart

http://www.jfree.org/jfreechart/

Javaのチャートライブラリの決定版です。ほぼあらゆる種類のグラフを描くことができます。高機能すぎて、Javadocを読んだだけでは目的のクラスやメソッドを見つけ出すのが難しいほどです(笑)。

Ehcache

http://ehcache.sourceforge.net/

Javaの汎用キャッシュライブラリです。TTLやディスクキャッシュの使用可否をXMLファイルで簡単に設定できて、気軽に使えます。memcachedより高速という情報もあります。

TopHatenarはブログパーツを多くの方に貼っていただいているので、キャッシュが非常に重要ですが、今のところミスヒット率は10%未満と、良好な結果が出ています。

Cubby

http://cubby.seasar.org/

RESTっぽいURIを簡単に扱えることが特徴の、軽量なWebフレームワークです。重宝してます。

Mayaa

http://mayaa.seasar.org/

HTMLテンプレートエンジンです。テンプレートを奇麗なHTMLで書ける上に、JavaオブジェクトをJavaScriptの式で参照できたり、レイアウト共有機能(HTMLのコンポーネント化)が秀逸だったりとメリットが多いので、Cubbyと組み合わせて使っています。

S2JDBC

http://s2container.seasar.org/2.4/ja/s2jdbc.html

JPAの改良版的な位置付けのO/Rマッパーです。Genericsや可変長引数をフル活用した「流れるようなインターフェイス」によって、DBアクセスコードを簡略化できます。

S2RMI

http://s2rmi.seasar.org/ja/

DIコンテナに登録された任意のオブジェクトを、アノテーション等一切不要でJava RMI対応にできてしまうという、DI+AOPの真価を見せつけてくれる素晴らしいライブラリです。

S2Flex2

http://s2flex2.sandbox.seasar.org/ja/

これを使うことで、FlexからJavaオブジェクトを簡単に呼び出せるようになります。通信にはAMF3が使われるので高パフォーマンスです。

ちなみにHatenarMapsではFlex 3を使っているので、今度S2Flex2の代わりにS2BlazeDSも試したいと思っています。

最後に

こうして見ると、TopHatenarとHatenarMapsは、かなりSeasar色に染まってますね。JavaでWebサービスを作るとき、Seasarファミリーはとても役に立つと思います。

作者:kaiseh

更新日:2008年12月29日 8時5分

このブログのホーム

[WebService] HatenarMapsのブログパーツを開始しました

HatenarMapsでの領地の状況を、ブログパーツとして貼れるようにしてみましたので、ぜひご利用ください。

こんな感じの画像を埋め込むことができます。

f:id:kaiseh:20081227210844p:image

貼り付け用のHTMLサンプルは以下になります。"XXXXXXXX"の部分を、自分のはてなIDに書き換えてください。

<a href="http://hatenarmaps.com/view/XXXXXXXX"><img src="http://hatenarmaps.com/chart/XXXXXXXX" width="160" height="120"/></a>

指定されたIDの領地が存在しない場合は、今のところ、1×1ピクセルの空白の画像が返ってくる仕様になっています。

その他

ブログパーツ機能以外にも、HatenarMapsに2点修正を加えました。

  1. マウスホイールでの拡大・縮小に対応しました。
  2. 年表で、領地の面積推移を棒グラフ表示するようにしました。

よろしくお願いします。

作者:kaiseh

更新日:2008年12月27日 12時17分

このブログのホーム

[WebService] 新HatenarMapsのFAQ

新しいHatenarMapsについて、ブクマコメント等でいろいろ疑問をいただいているので、FAQにまとめました。

○○について書いたことが一度もないのに、○○地区に入っています。何で?

できるだけ適切(?)な地区に入るようにしていますが、クラスタリングの性質上、そのようなことも起こり得ます。今後も継続して、精度の向上を目指していきますのでご了承ください。

TopHatenarでブックマーク数3000位以内なのに、HatenarMapsに載っていません。何で?

ブックマーク総数が多くても、タグの付与数が一定基準に達していない場合、ブログの特徴を判断することが難しいので、HatenarMapsの表示対象外になります。

個別エントリーが領地を獲得する基準は?

現在の日付を基準に、過去1年間に書かれたエントリーの中から、ブックマーク数が多い順に最大10エントリーが領地を獲得します。ただし、5users未満のエントリーは対象外です。

個別エントリーが領地を失う基準は?

2つのケースが考えられます。

  1. エントリーを書いてから1年以上経過した。
  2. 同一のユーザが後発で書いた他のエントリーがより多くのブックマークを獲得したため、最大10エントリーの枠から押し出された。

実際のブログや個別エントリーのURLにジャンプするには?

地形をダブルクリックしてください。

島の外形の由来は?オーストラリア?

ドラゴンクエスト3の「ランシール」という大陸です。中心部に「地球のへそ」と呼ばれる、主人公が勇気を試されるダンジョンがあります。

f:id:kaiseh:20081225233550p:image

作者:kaiseh

更新日:2008年12月25日 15時6分

このブログのホーム