HBase はスケーラブルで分散型、そして列指向で動的なスキーマを持つ、構造化データのためのデータベースです。HBase は何千台もの一般的なサーバーに分散された大規模なデータ (ペタバイトまたはそれ以上) を効率良く、高い信頼性のもとで処理することができます。HBase は Google の Bigtable データベースをモデルとして作られており、Apache Software Foundation の Hadoop プロジェクトのサブプロジェクトになっています。
注: この記事の執筆時点で HBase の最新リリースは V0.19.3 でした。この記事で説明する内容は、このリリースを基にしています。
HBase のデータは多次元マップとしてモデリングすることができ、値 (テーブルのセル) は下記の 4 つのキーで索引付けされます。
value = Map(TableName, RowKey, ColumnKey, Timestamp) |
ここで、
TableNameは文字列です。RowKeyとColumnKeyはバイナリーの値 (Java™ のbyte[]型) です。Timestampは 64 ビットの整数 (Java のlong型) です。valueは任意の長さのバイト配列 (Java™ のbyte[]型) です。
バイナリー・データは Base64 でエンコードされ、ネットワークに送信されます。
行キーはテーブルの主キーであり、通常は文字列です。行のソートは行キーによって辞書式順序で行われます。
テーブルに保存された情報は列ファミリーを構成します (列ファミリーはカテゴリーと考えることができます)。各列ファミリーは、ラベル (または修飾子) によって識別される任意の数のメンバーを持つことができます。column キーは、ファミリー名と : 記号、そしてラベルを連結したものです。例えばファミリーが info でメンバーが date の場合、列キーは info:date です。
HBase テーブルのスキーマによって列ファミリーが定義されますが、アプリケーションはテーブルに行を挿入する際にその場で新しいメンバーを作成することができます。また、1 つの列ファミリーに対して、テーブルの中の異なる行が異なる数のメンバーを持つことができます。つまり HBase は動的なスキーマのモデルをサポートしています。
表 1 は Persons という簡単な HBase テーブルの例を示しています。このテーブルには name と contact という 2 つの列ファミリーがあります。
表 1. 2 つの列ファミリーを持つ Persons テーブル
| 行キー | タイムスタンプ | 列ファミリー | |
|---|---|---|---|
| name | contact | ||
| 000001 | t3 | contact:http research.google.com/people/jeff/ | |
| t2 | name:first Jeffrey | ||
| t1 | name:last Dean | ||
| 000002 | t5 | name:first Gabriel | |
| t4 | name:last Mateescu | ||
セルが空の場合、そのセルのキーには値が関連付けられていません。例えば表 1 では、(000002, contact:http, t4) というキーに関連付けられたセルは空です。空のセルは HBase に保存されません。空のセルを読み取ることは、存在しないキーによってマップから値を抽出することと似ています。従って HBase テーブルは「疎な」行 (空のセルを多く含む行) で構成される場合に適しています。
どの行の場合も、1 つの列ファミリーの 1 つのメンバーにしか一度にアクセスすることはできません (リレーショナル・データベースでは、1 つのクエリーで 1 行の複数列のセルにアクセスすることができますが、それとは異なります)。1 行の中にある列ファミリーのメンバーはサブ行と見なされます。
テーブルは、Bigtable の「タブレット (tablet)」に相当する「リージョン (region)」に分解することができます。1 つのリージョンには、ある特定の範囲内にある行が含まれます。テーブルをリージョンに分解できる機能は大規模なテーブルを効率的に処理する上で重要なメカニズムです。
科学論文に関する情報を表現するという問題を考えてみてください。この場合、論文や著者はリソースです。RDF (Resource Description Framework) では、リソースに関するナレッジはアサーションによって表現されます (「参考文献」を参照)。ここで、アサーションとは下記の 3 つを組み合わせたトリプルです。
(subject, predicate, object). |
述語 (predicate) は、主語 (subject: アサーションによって参照されるリソース) と目的語 (object) の間の関係を定義します。例えば、「The article has the title Bigtable (この論文の表題は Bigtable です)」という文を以下のように表現することができます。
(The article, has title, Bigtable). |
アサーションの主語は URI によって識別されるリソースでなければなりません。述語は語彙の中で定義されている必要があるため、述語はその語彙の名前空間 URI と関連付けられます。アサーションの目的語は URI またはリテラルによって識別されます。目的語が別のアサーションの主語である場合には、その目的語は URI によって識別されるものでなければなりません。
この記事では、ある論文に関するナレッジをアサーションとして表現し、それらのアサーションを RDF/XML で表現します。
ここでは、Bigtable に関する下記の論文を対象とします。
F. Chang, J. Dean, S. Ghemawat, W. Hsieh, D. Wallach, M. Burrows, T. Chandra, A. Fikes, and R. Gruber, "Bigtable: A Distributed Storage System for Structured Data", ACM Trans. Comput. Syst. 26 (2), June 2008.
この論文については、例えば下記のような文で記述することができます。
- The Bigtable journal article has the title "Bigtable: A Distributed Storage System for Structured Data." (Bigtable に関するこの論文には、「Bigtable: A Distributed Storage System for Structured Data」という表題がつけられています。)
- The Bigtable journal article is written by Fay Chang. (Bigtable に関するこの論文は、Fay Chang によって執筆されました。)
ここで、
- The Bigtable journal article (Bigtable に関するこの論文) は両方の文の主語です。
- has the title (表題がつけられています) は最初の文の述語です。
- "Bigtable: A Distributed Storage System for Structured Data" (「Bigtable: A Distributed Storage System for Structured Data」) は最初の文の目的語です。
- is written by (によって執筆されました) は 2 番目の文の述語です。
- Fay Chang は 2 番目の文の目的語です。
これらの文を RDF/XML で表現するためには、適切な名前空間において主語の URI と述語の名前を決める必要があります。論文の URI に関しては、この Bigtable に関する論文の DOI (Digital Object Identifier) を URI として使用し (http://doi.acm.org/10.1145/1365815.1365816)、最初の文を次のような形にします。
The article with the URI "http://doi.acm.org/10.1145/1365815.1365816" has the title "Bigtable: A Distributed Storage System for Structured Data." (「http://doi.acm.org/10.1145/1365815.1365816」という URI の論文には、「Bigtable: A Distributed Storage System for Structured Data」という表題がつけられています。)
述語には、表 2 の語彙の用語を使用します。
表 2. 名前空間 URI と接頭辞
| 接頭辞 | 名前空間 URI | 説明 |
|---|---|---|
| rdf | http://www.w3.org/1999/02/22-rdf-syntax-ns# | RDF 語彙の用語 |
| dc | http://purl.org/dc/elements/1.1/ | Dublin Core の要素 |
| dcterms | http://purl.org/dc/terms/ | Dublin Core の用語 |
| eprint | http://purl.org/eprint/terms/ | Eprints の用語 |
| foaf | http://xmlns.com/foaf/0.1/ | FOAF 語彙の用語 |
これらの語彙を基にすると、Bigtable に関する論文について記述した文をリスト 1 のように RDF/XML の形式にすることができます。
リスト 1. RDF/XML で論文について記述する
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/" >
<rdf:Description rdf:about="http://doi.acm.org/10.1145/1365815.1365816">
<dc:title>Bigtable: A Distributed Storage System for Structured Data</title>
<dc:creator
rdf:resource="http://purl.org/sweb/Authors/google/research/Fay_Chang"/>
</rdf:Description>
</rdf:RDF>
|
ここで、<dc:title> という述語の目的語はリテラルですが、<dc:creator> の目的語は URI です。
この論文についての (すべての著者、発行日、発行元の名前などの情報を含む) 完全な記述をリスト 2 に示します (<dc:type> という述語は論文のタイプを定義します)。
リスト 2. RDF/XML で論文について完全に記述する
$ cat rdf/Bigtable.xml
<?xml version="1.0" encoding="UTF-8" ?>
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:dcterms="http://purl.org/dc/terms/" >
<rdf:Description rdf:about="http://doi.acm.org/10.1145/1365815.1365816">
<dc:title>Bigtable: A Distributed Storage System for Structured Data</title>
<dc:type>http://purl.org/eprint/type/JournalArticle</dc:type>
<dc:creator
rdf:resource="http://purl.org/sweb/Authors/google/research/Fay_Chang"/>
<dc:creator
rdf:resource="http://purl.org/sweb/Authors/google/research/Jeffrey_Dean"/>
<dc:creator
rdf:resource="http://purl.org/sweb/Authors/google/research/Sanjay_Ghemawat"/>
<dc:creator
rdf:resource="http://purl.org/sweb/Authors/google/research/Wilson_Hsieh"/>
<dc:creator
rdf:resource="http://purl.org/sweb/Authors/google/research/Deborah_Wallach"/>
<dc:creator
rdf:resource="http://purl.org/sweb/Authors/google/research/Mike_Burrows"/>
<dc:creator
rdf:resource="http://purl.org/sweb/Authors/google/research/Tushar_Chandra"/>
<dc:creator
rdf:resource="http://purl.org/sweb/Authors/google/research/Andrew_Fikes"/>
<dc:creator
rdf:resource="http://purl.org/sweb/Authors/google/research/Robert_Gruber"/>
<dc:publisher>ACM, New York, NY, USA</dc:publisher>
<dcterms:issued>2008-06</dcterms:issued>
<dc:subject>distributed databases</dc:subject>
<dcterms:isPartOf rdf:resource="urn:ISSN:0734-2071" />
<dcterms:bibliographicCitation>
ACM Trans. Comput. Syst., 26 (2) 26 pages (2008)
</dcterms:bibliographicCitation>
</rdf:Description>
</rdf:RDF>
|
著者について記述するためには FOAF (Friend of a Friend) を使用します。リスト 3 には Jeffrey Dean という主語に関するアサーションを示してあります。
リスト 3. RDF/XML で著者について記述する
$ cat rdf/Jeffrey.xml
<?xml version="1.0" encoding="UTF-8" ?>
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:foaf="http://xmlns.com/foaf/0.1/"
xmlns:eprint="http://purl.org/eprint/terms/" >
<rdf:Description
rdf:about="http://purl.org/sweb/Authors/google/research/Jeffrey_Dean">
<foaf:Person>
<foaf:givenname>Jeffrey</foaf:givenname>
<foaf:family_name>Dean</foaf:family_name>
<foaf:homepage rdf:resource="http://research.google.com/people/jeff/" />
</foaf:Person>
<eprint:affiliatedInstitution>Google, Inc.</eprint:affiliatedInstitution>
</rdf:Description>
</rdf:RDF>
|
HBase を使用してセマンティック Web をモデリングする
HBase を使用してセマンティック Web をモデリングするための最初のステップは、RDF を HBase テーブルにマッピングすることです。RDF/XML で論文と著者を記述したものを保存するためには、articles と authors という 2 つのテーブルを作成します。著者の所属を照会できる必要があることを念頭に置いて、この 2 つのテーブルを設計します。
articles テーブルの行キーは、この論文の DOI から得られます。例えば、Bigtable に関する論文の行キーは doi.org.acm_10.1145_1365815_1365816 です。このスキーマには下記の 3 つの列ファミリーがあります。
infoは表題、発行物の名称、発行日などの情報用です。authorsは著者達の URI 用です。affiliationsは著者達の所属用です。
authors テーブルの行キーは著者達の URI から得られます。例えば、Jeffrey Dean の URI (リスト 3 を参照) は google_research_Jeffrey_Dean というキーに変換されます。このスキーマには 2 つの列ファミリーがあり、info には著者に関する情報 (名前やホーム・ページ) を保存し、affiliations には著者の所属の履歴を保存します。
HBase を扱うための 1 つの方法として REST API を使う方法があります。リスト 4 に示す HTTP リクエストを使用してテーブルを作成します。
リスト 4. articles テーブルと authors テーブルを作成する
$ cat tables/Articles.xml
<?xml version="1.0" encoding="UTF-8" ?>
<table>
<name>Articles</name>
<columnfamilies>
<columnfamily>
<name>info</name>
</columnfamily>
<columnfamily>
<name>authors</name>
</columnfamily>
<columnfamily>
<name>affiliations</name>
</columnfamily>
</columnfamilies>
</table>
$ cat tables/Authors.xml
<?xml version="1.0" encoding="UTF-8" ?>
<table>
<name>Authors</name>
<columnfamilies>
<columnfamily>
<name>info</name>
</columnfamily>
<columnfamily>
<name>affiliations</name>
</columnfamily>
</columnfamilies>
</table>
$ cat tables/Articles.xml | curl -X POST -T - http://localhost:60010/api/
$ cat tables/Authors.xml | curl -X POST -T - http://localhost:60010/api/
|
「論文を RDF で記述する」セクションで構成した情報を articles テーブルと authors テーブルに追加します。リスト 5 は著者 Jeffrey Dean に関する情報を authors テーブルに挿入する方法を示しています (値は Base64 です)。
リスト 5. authors テーブルに情報を挿入する
$ more rows/Jeffrey_Dean_info.xml
<?xml version="1.0" encoding="UTF-8" ?>
<column>
<name>info:name</name>
<value>SmVmZnJleSBEZWFuCg==</value>
</column>
$ more rows/Jeffrey_Dean_affiliation.xml
<?xml version="1.0" encoding="UTF-8" ?>
<column>
<name>affiliations:</name>
<value>R29vZ2xlCg==</value>
</column>
$ cat rows/Jeffrey_Dean_info.xml | \
curl -X POST -T - http://localhost:60010/api/Authors/row/google_research_Jeffrey_Dean
$ cat rows/Jeffrey_Dean_affiliation.xml | \
curl -X POST -T - http://localhost:60010/api/Authors/row/google_research_Jeffrey_Dean
|
挿入ごとに POST リクエストを実行し、タイムスタンプを省略します。タイムスタンプを省略する理由は HBase がデフォルトのタイムスタンプを割り当てるからです。リスト 6 は Bigtable に関する論文についての情報を articles テーブルに挿入する方法を示しています。
リスト 6. articles テーブルに情報を挿入する
$ more rows/Bigtable_info.xml
<?xml version="1.0" encoding="UTF-8" ?>
<column>
<name>info:title</name>
<value>QmlndGFibGU6IEEgRGlzdHJpYnV0ZWQgU3RvcmFnZSBTeXN0ZW0gZm9yIFN0cnVjdHVyZWQgRGF0
YQo==
</value>
</column>
$ more rows/Bigtable_author_2.xml
<?xml version="1.0" encoding="UTF-8" ?>
<column>
<name>authors:2</name>
<value>SmVmZnJleSBEZWFuCg==</value>
</column>
$ cat rows/Bigtable_info.xml | curl -X POST \
-T - http://localhost:60010/api/Articles/row/doi.org.acm_10.1145_1365815_136581
$ cat rows/Bigtable_author_2.xml | curl -X POST \
-T - http://localhost:60010/api/Articles/row/doi.org.acm_10.1145_1365815_136581
|
authors テーブルと articles テーブルにデータを追加したら、そのデータに対してバッチ操作を実行します。ここでは Bigtable に関する論文の著者の所属を検索します。バッチ・プロセスでは両方のテーブルをスキャンして authors テーブルの列ファミリー affiliations から情報を抽出し、articles テーブルの列ファミリー affiliations の中に著者の所属情報を集積します。Bigtable に関する論文の場合、このバッチ・プロセスのアクションはリスト 7 のコードのようになります。ここでは、この論文のすべての著者が Google に所属しています。
リスト 7. 処理された情報を articles テーブルに追加する
$ more rows/Bigtable_affiliations.xml
<?xml version="1.0" encoding="UTF-8" ?>
<column>
<name>affiliations:</name>
<value>R29vZ2xlCg==</value>
</column>
$ cat rows/Bigtable_affiliations.xml | curl -X POST \
-T - http://localhost:60010/api/Articles/row/doi.org.acm_10.1145_1365815_136581
|
Bigtable に関する論文の著者の所属を取得するためには、Bigtable に関する論文の行の affiliations: 列に対して GET を実行します。
リスト 8. articles テーブルから情報を抽出する
$ curl -X GET http://localhost:60010/api/Articles/row/\ doi.org.acm_10.1145_1365815_136581?column=affiliations: <?xml version="1.0" encoding="UTF-8" ?> <row> <count> 1 </count> <column> <name> YWZmaWxpYXRpb25zOg== </name> <value> R29vZ2xlCg== </value> <timestamp> 1250049020108 </timestamp> </column> |
Base64 による値をデコードすると、YWZmaWxpYXRpb25zOg== に対して affiliations: が、R29vZ2xlCg== に対して Google が得られます。
HBase を使うと、この記事で説明した内容よりも複雑な質問に答えることができます。例えば、「Jeopardy!」というクイズ番組 (訳注: 「Jeopardy!」はアメリカで放送されている人気クイズ番組) のヒントとして「The author of this journal article about Bigtable has worked for the World Health Organization (Bigtable に関するこの論文の著者は世界保健機関で働いたことがある)」を HBase で処理すると、その回答を見つけることができます。そのためには、この論文のキーワードが行キーであるような Keywords というテーブルを作成します。このテーブルには、対象となるキーワードが使われている論文の DOI を保存するための列ファミリー journal_articles が含まれています。
Bigtable に関する論文のキーワードを保存すると、Keywords テーブルには、行キーが Bigtable で、列キーが journal_articles:1、そしてセルの値が doi.acm.org_10.1145_1365815_1365816 であるような行が含まれます。上記のクイズに答えるためには以下の処理を行います。
- Keywords テーブルの中でキーワード
Bigtableを検索し、この論文の DOI を取得します。 - ステップ 1 で得られた DOI によって articles テーブルの中で論文を検索し、著者達の URI を取得します。
- authors テーブルの中で URI によって著者を検索し、過去と現在の所属を抽出します。
- ステップ 3 で得られる結果セットから、列ファミリー
affiliationsにWorld Health Organizationというメンバーがある行を選択します。
すると回答は「Who is Jeffrey Dean? (Jeffrey Dean とは誰か)」となります。
HBase と Bigtable ではデータ処理パイプラインに新しい考え方を導入しています。一体型のシステムで SQL のようなプロセスによってデータを抽出、変換する手法は、分割統治法に置き換えられています。データベースは CRUD (Create, Read, Update, Delete) 操作をサポートしますが、複雑な変換は並列処理用に設計された外部コンポーネントに委譲されます。例えば並列処理を MapReduce アプリケーションによって行い、複製された分散ファイルシステム (HDFS (Hadoop Distributed File System) や Google File System など) を使うことで高いスループットが実現されます。
HBase ではテーブルの結合がないため、関連する情報を 1 つのテーブルに保持するために非正規化がよく使われます。この記事ではこの手法を説明しました。
HBase はまだパフォーマンスを改善する余地がありますが、現実に主流のソリューションとなる見込みがあります。
| 内容 | ファイル名 | サイズ | ダウンロード形式 |
|---|---|---|---|
| Sample XML | os-hbase-source_hbase.zip | 11KB | HTTP |
学ぶために
- Bigtable によって実現される単純なデータ・モデルを解説した「Bigtable: A Distributed Storage System for Structured Data」(F. Chang、J. Dean、S. Ghemawat、W. Hsieh、D. Wallach、M. Burrows、T. Chandra、A. Fikes、R. Gruber の共著、2008年 ACM 刊) を読んでください。
- 「An introduction to RDF」は RDF/XML を適確に概説しています。
- Apache HBase Project について調べてみてください。
- HBase に関する質問の答えを HBase のウィキで見つけることができます。
- HBase のアーキテクチャーのウィキを訪れ、基礎となっている HBase のアーキテクチャーについて学んでください。
- HBase の REST に関するウィキを調べ、HBase の API に関する質問の答えを見つけてください。
- HBase ユーザー・グループのミーティングで発表された「HBasics: An Introduction to Hadoop HBase」は HBase を適切に紹介しています。
- FOAF Vocabulary Specification 0.91 を調べ、FOAF について学んでください。
- developerWorks podcasts ではソフトウェア開発者のための興味深いインタビューや議論を聞くことができます。
- developerWorks の Technical events and webcasts で最新情報を入手してください。
- developerWorks を Twitter でフォローしてください。
- IBM オープンソース開発者にとって関心のある、世界中で今後開催される会議や業界展示会、ウェブキャスト、その他のイベントについて調べてみてください。
- developerWorks の Open source ゾーンをご覧ください。オープンソース技術を使った開発や、IBM 製品でオープンソース技術を使用するためのハウ・ツー情報やツール、プロジェクトの更新情報など、豊富な情報が用意されています。
- IBM とオープンソース技術、そして製品機能を調べ、学ぶために、無料の developerWorks On demand demos をご覧ください。
製品や技術を入手するために
- 皆さんの次期オープンソース開発プロジェクトを IBM ソフトウェアの試用版を使って革新してください。ダウンロード、あるいは DVD で入手することができます。
- IBM 製品の試用版をダウンロードするか、あるいは IBM SOA Sandbox のオンライン試用版で、DB2®、Lotus®、Rational®、Tivoli®、WebSphere® などが提供するアプリケーション開発ツールやミドルウェア製品を試してみてください。
議論するために
- developerWorks blogs から developerWorks のコミュニティーに加わってください。