MongoDBとビッグ・データ - oracle.com · MongoDBとビッグ・データ...

5
ORACLE.COM/JAVAMAGAZINE ///////////////////// JANUARY/FEBRUARY 2014 JAVA TECH 38 COMMUNITY JAVA IN ACTION ABOUT US blog //java architect / M ongoDB は、ドキュメント指 向ストレージ、インデックス の完全サポート、レプリケーショ ンと高可用性、自動シャーディン グ、クエリー、高速インプレース 更新、Map/Reduce、GridFS を おもな特徴とする NoSQL データ ベースです。 今号の Java Magazine では、 ビッグ・データという語が、幅広 いビジネス上の課題や技術的な 解決策に及ぶ包括的な意味で使 用されています。ビッグ・データ は、大量かつ多様で変化の速い データのことです。各企業で、ビッ グ・データへの対策の必要性が 高まっています。MongoDB は以 下の方法により、これらの課題を 解決します。 大量のデータ:MongoDB は 汎用のハードウェアで水平にス ケーリングするように作られて いるため、データの増加や変 化の加速に合わせてクラスタに ノードを容易に追加できます。 自動シャーディングに関する項 で、この基本について説明しま す。 リアルタイムの要件:業務系 データベースに対して期待 するような基本的なクエリー 機能をサポートします。さら に、MongoDB 特有の Map/ Reduce や集計フレームワーク により、リアルタイムの分析と 状況把握が可能です。本記事 では単純なクエリーについて 説明しますが、MongoDB は有 用な情報を得るためのデータ・ マイニングの用途向けに、幅 広い機能を提供しています。 急速な進化:各企業のニー ズは、アクセス可能なすべ てのデータから得られる情報 に応じて変化していきます。 MongoDB の動的なドキュメン ト・スキーマによって、ビジネ ス・ニーズの進化にあわせて アプリケーションも進化するこ とが可能です。この進化につい ては、次項「ドキュメント指向 ストレージ」で説明します。 本記事では、MongoDB での レプリケーションと高可用性のサ ポートや、重要なすべてのデー タを確実に保管するために不可 欠となる要件についても説明しま す。 ドキュメント指向ストレージ MongoDB はドキュメント・デー タベースです。データは JSON 形 式の半構造化ドキュメントとして コレクション内に保存されます。 行と列で構成される表にデータが 保存されるリレーショナル・デー タベース(MySQL など)とは異 なります。MongoDB のコレクショ ンはリレーショナル・データベー スの表と似ていますが、コレクショ ンは表よりもかなり柔軟です。こ の柔軟性については後ほど説明し ます。 リスト 1 に、キー と値による構造化 されたセットの例を 示します。この構造 では、トップレベル のプロパティ(例: name)に加えて、サ ブドキュメント(例: address)や配列(例: books―利用者が借 りた本の ID の配列) もサポートしていま す。リレーショナル・ データベースと比較 すると、この構造は、 オブジェクト指向の開発者が扱い 慣れている構造に非常に近いと言 えます。 リスト 1 のオブジェクトは、 ほぼ直接 リスト 2 の 2 つの Java クラスへと変換できます。 リスト 1 にあるサブドキュメン トの address は、 リスト 2 では Address という単独のクラスに変 換されています。また、 リスト 1 のドキュメント内の配列は、 リス ト2 List に対応しています。 このドキュメント構造には、可 変であるという利点もあります。 データに対して動的なスキーマを 適用できるのです。 アプリケーションが 将来どのように進化 するのかがよくわか らない新興企業や新 規プロジェクトにとっ て、構造が可変であ るというのは好都合 です。 リスト 2 Patron を例に説明します。 Patron(図書館の利 用者)は、アプリケー ション内で、図書館 の本を借りる人を表 MongoDB とビッグ・データ リレーショナル・データベースとは異なり、ドキュメント指向構造を持つ MongoDB。その柔軟性によって、ビッグ・データの操作が容易になります。 写真: JOHN BLYTHE クエリーを見越して MongoDB では、適 度に複雑なクエリー を組み立てることが できます。この点も MongoDB の長所で す。MongoDB はクエ リーの実行を見越して 作られています。 and Java Big Data Trisha GeeMongoDB Inc. で Java ドライバの保 守を担当する開発 者。Java の高パ フォーマンス・シ ステムの専門家 で、開発生産性の 向上に熱心に取り 組む。London Java Community のリー ダーで、Graduate Developer Community に参 加。開発者が悩む ポイントを乗り越え るノウハウ共有のた めに活動している。

Transcript of MongoDBとビッグ・データ - oracle.com · MongoDBとビッグ・データ...

Page 1: MongoDBとビッグ・データ - oracle.com · MongoDBとビッグ・データ リレーショナル・データベースとは異なり、ドキュメント指向構造を持つ

ORACLE.COM/JAVAMAGAZINE ///////////////////// JANUARY/FEBRUARY 2014

JAVA TECH

38

COMMUNITY

JAVA IN ACTION

ABOUT US

blog

//java architect /

MongoDB は、ドキュメント指向ストレージ、インデックス

の完全サポート、レプリケーションと高可用性、自動シャーディング、クエリー、高速インプレース更新、Map/Reduce、GridFS をおもな特徴とするNoSQLデータベースです。今号の Java Magazineでは、

ビッグ・データという語が、幅広いビジネス上の課題や技術的な解決策に及ぶ包括的な意味で使用されています。ビッグ・データは、大量かつ多様で変化の速いデータのことです。各企業で、ビッグ・データへの対策の必要性が高まっています。MongoDB は以下の方法により、これらの課題を解決します。 ■ 大量のデータ:MongoDB は汎用のハードウェアで水平にスケーリングするように作られているため、データの増加や変化の加速に合わせてクラスタにノードを容易に追加できます。自動シャーディングに関する項で、この基本について説明します。

■ リアルタイムの要件:業務系

データベースに対して期待するような基本的なクエリー機能をサポートします。さらに、MongoDB 特有のMap/Reduce や集計フレームワークにより、リアルタイムの分析と状況把握が可能です。本記事では単純なクエリーについて説明しますが、MongoDB は有用な情報を得るためのデータ・マイニングの用途向けに、幅広い機能を提供しています。

■ 急速な進化:各企業のニーズは、アクセス可能なすべてのデータから得られる情報に応じて変化していきます。MongoDB の動的なドキュメント・スキーマによって、ビジネス・ニーズの進化にあわせてアプリケーションも進化することが可能です。この進化については、次項「ドキュメント指向ストレージ」で説明します。本記事では、MongoDBでの

レプリケーションと高可用性のサポートや、重要なすべてのデータを確実に保管するために不可欠となる要件についても説明します。

ドキュメント指向ストレージMongoDB はドキュメント・データベースです。データは JSON形式の半構造化ドキュメントとしてコレクション内に保存されます。行と列で構成される表にデータが保存されるリレーショナル・データベース(MySQL など)とは異なります。MongoDBのコレクションはリレーショナル・データベースの表と似ていますが、コレクションは表よりもかなり柔軟です。この柔軟性については後ほど説明します。リスト1に、キーと値による構造化されたセットの例を示します。この構造では、トップレベルのプロパティ(例:name)に加えて、サブドキュメント(例:address)や配列(例:books―利用者が借りた本の IDの配列)もサポートしています。リレーショナル・データベースと比較すると、この構造は、

オブジェクト指向の開発者が扱い慣れている構造に非常に近いと言えます。リスト1のオブジェクトは、ほぼ直接リスト2の 2つの Javaクラスへと変換できます。リスト1にあるサブドキュメン

トの address は、リスト2ではAddressという単独のクラスに変換されています。また、リスト1のドキュメント内の配列は、リスト2の List に対応しています。このドキュメント構造には、可変であるという利点もあります。データに対して動的なスキーマを

適用できるのです。アプリケーションが将来どのように進化するのかがよくわからない新興企業や新規プロジェクトにとって、構造が可変であるというのは好都合です。リスト2の Patronを例に説明します。 Patron(図書館の利用者)は、アプリケーション内で、図書館の本を借りる人を表

MongoDBとビッグ・データリレーショナル・データベースとは異なり、ドキュメント指向構造を持つMongoDB。その柔軟性によって、ビッグ・データの操作が容易になります。

写真: JOHN BLYTHE

クエリーを見越してMongoDBでは、適

度に複雑なクエリー

を組み立てることが

できます。この点も

MongoDB の長所で

す。MongoDB はクエ

リーの実行を見越して

作られています。and JavaBig Data

Trisha Gee:MongoDB Inc. でJavaドライバの保守を担当する開発者。Java の高パフォーマンス・システムの専門家で、開発生産性の向上に熱心に取り組む。London Java Community のリーダーで、Graduate Developer Community に参加。開発者が悩むポイントを乗り越えるノウハウ共有のために活動している。

Page 2: MongoDBとビッグ・データ - oracle.com · MongoDBとビッグ・データ リレーショナル・データベースとは異なり、ドキュメント指向構造を持つ

ORACLE.COM/JAVAMAGAZINE ///////////////////// JANUARY/FEBRUARY 2014

JAVA TECH

39

COMMUNITY

JAVA IN ACTION

ABOUT US

blog

//java architect /

します。ある利用者を初めて知ったときには、名前しかわからない可能性もあります。

利用者に対して最初に本を貸し出すときに初めて住所を尋ね、貸し出す本のIDを記録することになるでしょう。そのため、利用者のドキュメントは、リスト1に示したようなものになります。ここで、この図書館が後日、音楽 CDの貸出しを始めることになったとします。MongoDBでは新しいフィールドを簡単に追加できます(リスト3)。そのため、このアプリケーションで行うべきことは、利用者に対して最初にCDを貸し出すと

きに、CDの ID のリストを記録することだけです。アプリケーションのニーズの進化に応

じて、ドキュメント構造を容易に変えることができます。リレーショナル・データベースの場合、新しい列を追加して表を更新するにはスクリプトを実行する必要があります。しかし、MongoDBでドキュメントに新しい情報が必要となった場合は、単純にそのドキュメントに新しいフィールドを追加するだけで作業が完了します。このような動的な表現は、要件の変化に対応するのに便利なだけではありません。よく似ているけれども同一ではない項目を保存する場合にも非常に便利です。たとえば、本とCDの特性は異なります(本には著者、タイトル、ISBNなどのプロパティがあり、CDにはアー

ティスト、タイトル、トラック・リストなどのプロパティがあります)。しかし、各ドキュメントのフィールドが異なっていても、本、CD、その他の項目を同じコレクション内に保存できます。リレーショナル・データベースの表でこのような特性の違いに対処するためには、NULL 値がオプションとして含まれる列を使用するか、複数の表を用意して結合することになるでしょう。ドキュメント・データベースでは、こ

のような対処は不要です。フィールドの種類が異なるドキュメントをすべて同じコレクション内に格納できるからです。このような動的なドキュメント・スキーマを持つMongoDBであれば、データの種類が増え続ける状況に対応できます。また、そのようなデータこそ、企業がビッグ・データを取り扱う際に保管する価値のあるデータです。

レプリケーションと高可用性従来、開発者はレプリケーションや高可用性(HA)への配慮を運用担当者に委ねていました。しかし、DevOps が一般的になり、システムが 24 時間 365日稼働し続ける必要性が高まるにつれ、このように運用側に任せる余裕はなくなっています。幸いにも、MongoDBではレプリケーションとHAを標準的にサポート

しています。これらの機能のセットアップも簡単です。図 1に示すように、MongoDB はレプ

リカ・セットによるHAをサポートしています。レプリカ・セットにはプライマリ(デフォルトで、データの読取りを行い、すべてのデータの書込みを行う場所)があります。ただし、データを読み取る場所については設定を変更できます。セカンダリは、プライマリに書き込まれたすべてのデータのコピーを確実に保有し、レプリケーションの実行を担当してHAを実現します。いかなる時点でも、プライマリがビューから消失した場合には、適切なセカンダリが新しいプライマリとして選出されます。詳細については、レプリケーションに関するドキュメントを参照してください。

patron = { _id:"joe", name:"Joe Bookreader",}

すべてのリストのテキストをダウンロード

{ _id:"joe", name:"Joe Bookreader", address:{ street:"123 Fake St", city:"Faketon", zip:12345 } books:[ 27464, 747854, ...]}

リスト1 リスト2 リスト3

図1

Page 3: MongoDBとビッグ・データ - oracle.com · MongoDBとビッグ・データ リレーショナル・データベースとは異なり、ドキュメント指向構造を持つ

ORACLE.COM/JAVAMAGAZINE ///////////////////// JANUARY/FEBRUARY 2014

JAVA TECH

40

COMMUNITY

JAVA IN ACTION

ABOUT US

blog

//java architect /

自動シャーディングレプリカ・セットは、HAとレプリケーションを実現する手段として優れていますが、ビッグ・データに見られるような大量で変化の速いデータを処理できるほどのスケーラビリティを備えていません。このスケーラビリティを実現するのがシャーディングです。MongoDBでは、特定のコレクションを選択し、指定したシャード・キーに基づいて複数のレプリカ・セットにシャーディングする(分散させる)ことができます(図 2)。図 2に、名前を基準にして利用者コ

レクションをシャーディングした様子を示します。シャーディング後の構成には、複数のレプリカ・セットが存在します(Replica Set 1、2、3。セカンダリは

S1、S2と略記)。また、レプリカ・セット間のルーターとして動作する複数台のMongoS サーバーと、どのデータがどのレプリカ・セットに保存されているかを追跡管理する3台の構成サーバーもあります。この例では、利用者コレクションを利用者の姓に基づいてシャーディングすることにします。MongoDB は、ドキュメントを均等に分散させる方法を把握しています。MongoDB は、ドキュメントの配分が変化したかを調査し、アプリケーションに影響を及ぼさずに、データを異なるサーバー間で適宜入れ替えます。アプリケーションで使用するMongoDBドライバは、MongoSインスタンスにアクセスします。このインスタンスが、適切なサーバーへのクエリー

のルーティング方法を把握するための処理をすべて実行します。

クエリー前項までにMongoDB の背景、ドキュメント・データベースとしての特徴、および可用性とスケーラビリティを確保するための複数サーバーによる運用方法について説明しました。次に、Java 開発者として実際にサーバーを取り扱う方法について詳しく説明します。Java 仮想マシン(JVM)上で稼動するアプリケーションの開発においては、多数の選択肢からMongoDB の操作方法を選択できます。本記事では、MongoDB Inc. がサポートするJavaドライバを利用するという、ごく基本的な手法を取り上げます。データベースへのアクセスで、よく話題になるのが CRUD操作(作成、読取り、更新、削除)です。MongoDB はNoSQLデータベースであることから、JPA や JDBC によりデータベースを操作する意味はあまりないのですが、JavaアプリケーションからCRUD操作を実行することは非常に簡単です。はじめに:以下のサンプルを実行する場合やMongoDBを試す場合には、まずMongoDBをインストールする必要があ

ります。MongoDB は、ノートPCにインストールして実行できるほど軽量であり、リソースが独占されることを心配する必要はありません。注:本記事で紹介するサンプルのソー

ス・コードはこちらからダウンロードできます。接続:本記事のサンプルでは、「library」というデータベースに接続します。また、利用者の情報は「patrons」というコレクション内に保存します。Javaアプリケーションから前述のデー

タベースやコレクションにアクセスするために、リスト4のようなコードを記述します。このデータベースやコレクションがまだ存在していない場合は、データの挿入時に自動的に作成されます。明示的に作成する必要はありません。作成:前述の「図書館の利用者」のサンプルを再度取り上げます。新たな利用者をデータベースに挿入する場合は、リスト5のようなコードを記述します。ドキュメントは基本的には、フィールドの名前とフィールドの値を対応付けるマップです。データベースにデータを保存するためには、ドメイン・オブジェクト(サンプルでは Patronとその Address)を、マップによく似たデータ構造であるDBObject に変換する必要があります。

MongoClient mongoClient = new MongoClient(new MongoClientURI("mongodb://localhost:27017")); DB database = mongoClient.getDB("library"); DBcollection collection = database.getCollection("patrons");

リスト4

すべてのリストのテキストをダウンロード

図2

Page 4: MongoDBとビッグ・データ - oracle.com · MongoDBとビッグ・データ リレーショナル・データベースとは異なり、ドキュメント指向構造を持つ

ORACLE.COM/JAVAMAGAZINE ///////////////////// JANUARY/FEBRUARY 2014

JAVA TECH

41

COMMUNITY

JAVA IN ACTION

ABOUT US

blog

//java architect /

この変換を開発者が手動で行う必要はありません。オブジェクト/ドキュメント・マッパー(ODM)という、Java オブジェクトを自動的にDBObject に変換する機能があるからです。ただし本記事では、手動による方法の基本を説明します。 insert を呼び出した後、ドキュメントがMongoDB 内に保存されます。読取り:データベース内に何らかのデータがある状態になりましたので、次に行う作業はおそらく、そのデータを読み取ることです。MongoDBでは、適度に複雑なクエリーを組み立てることができます。この点もMongoDB の長所です。MongoDB はクエリーの実行を見越して作られています。データベース内の特定の利用者を名前によって検索するためには、リスト6のようなコードを記述します。クエリーもまたドキュメントです。サンプルでは、nameフィールドの値が Samと一致するすべてのドキュメントを検索するためのクエリーを作成しました。その結果はカーソルとして返され、このカーソルに対して繰返し処理を実行できます。結果が 1つしかないと

わかっている場合(たとえば、IDを使用したクエリーの場合)、あるいは 1つ目の結果にしか関心がない場合は、リスト7のようなコードを記述します。この単純なQuery by Exampleよりも複雑なクエ

リーを組み立てることもできます。例として、本を借りていないすべての利用者を検索しましょう。$exists 演算子を使用して、books 配列がドキュメント内に存在するかを確認できます(リスト8)。また、あらゆるデータベースで期待されるような方式により、sort、skip、limit などの操作を実行できます(リスト9)。本記事では、作成可能なクエリーの種類について、ごく簡単に概要を説明していますが、クエリーに関する情報については、MongoDB のWeb サイトに詳しく記載されています。更新:読取りと同様に、ドキュメントの更新にも多くの選択肢があります。特によく使用する更新方法として、ドキュメント全体の置換えか、もしくは関心のあるフィールドのみの更新が可能です。利用者の住所の 1行目のみを更新

する場合は、リスト10のようなコードを記述します。この操作では、findCharlieというクエリーを作成して、更新対象のドキュメントを検索します。このクエリーは、一意の利用者 IDによって利用者(Charlie)を特定します。また、updateCharlieAddressという、更新操作を表す 2つ目のドキュメントを作成します。このドキュメントでは、address サブドキュメントの streetフィールドに新しい値を設定します。最後に、この更新を実行するために、ドキュメント

を特定するクエリー(findCharlie)と更新の詳細(updateCharlieAddress)を、ドキュメントが含まれるコレクションのupdateメソッドに渡します。ドキュメント内で新しい単一の値を追加または更新する必要がある場合には、この方法で問題ありません。一方、更新対象のドメイン・オブジェクトがすでにあるという状況もよくあります。その際に、処理を単純化するために、新しい値をすべて設定したうえで(もしくはデータベースから削除したい値を削除したうえで)このドメイン・オブジェクトごとデータベースに保存し直すことも可能です。このサンプルに当てはめると、たとえば Charlie を表す Patron がすでにあり、更新後の Charlie オブジェクトを、古い Charlie を上書きしてMongoDB に保存することになります。このコードはリスト11のようになります。見てのとおり、リスト10のコードよりも単純です。これらのサンプルを単純化するために、ドメイン・オブジェクトに

toDBObject() メソッドを追加したからです。ただし、このような変換はデータ・アクセス・オブジェクト(DAO)内で行うか、前述のODMを利用する方が良いでしょう。削除:データベースにデータを保存しただけでデータベースの操作は終わりではありません。データの削除が必要になることもあります。皆さんもおそらく、MongoDB の動作パターンがわかってきた頃でしょう。削除のために、削除するドキュメントを表すドキュメントを作成することも不思議ではないはずです(リスト12)。リスト12のコードによって、指定した条件に一致するすべてのドキュメントが削除されます。サンプルの場合は、IDによる一致検索が実行されるため、1つのドキュメントのみが削除されます。一方、複数のドキュメントに一致するクエリーを渡すこともできます。その場合は条件に一致するすべてのドキュメントが削除されます。たとえば、ロンドンに住

BasicDBObject addressAsDocument = new BasicDBObject("street", patron.getAddress().getStreet()) .append("city", patron.getAddress().getCity()) .append("phone", patron.getAddress().getPhone());DBObject patronAsDocument = new BasicDBObject("_id", patron.getId()) .append("name", patron.getName()) .append("address", addressAsDocument) .append("books", patron.getBooks());collection.insert(patronAsDocument);

リスト5 リスト6 リスト7 リスト8 リスト9 リスト10

すべてのリストのテキストをダウンロード

妥協なしMongoDBは、標準機能としてスケーラビリティと高可用性を実現するように作られています。そのため、開発者はビッグ・

データの要件に対応

できるアプリケーショ

ンを、設計で妥協す

ることなく構築できま

す。

Page 5: MongoDBとビッグ・データ - oracle.com · MongoDBとビッグ・データ リレーショナル・データベースとは異なり、ドキュメント指向構造を持つ

ORACLE.COM/JAVAMAGAZINE ///////////////////// JANUARY/FEBRUARY 2014

JAVA TECH

42

COMMUNITY

JAVA IN ACTION

ABOUT US

blog

//java architect /

むすべての利用者を削除するとすれば、リスト13のようなコードを記述します記述します。

まとめMongoDB は、開発者がデータを捉える方法によく似たドキュメント構造を提供します。ドキュメントとドメイン・オブジェクトはうまく対応付けられます。このデータベースは、標準機能としてスケーラビリティと高可用性を実現するように作られています。そのため、開発者はビッグ・データの要件に対応できるアプリケーションを、設計で妥協することなく構築できます。さらに、Pure Java を利用してデータベースを容易に操作できるように設計された Javaドライバも用意されています。Java API や JVM言語 API を開発する他の各種プロジェクトの基盤としても利用されていることから、Java やJVMの開発者がMongoDBを操作するための幅広いツールも提供されています。</article>

LEARN MORE• MongoDBエコシステム

Patron updatedCharlieObject = //our updated object DBObject findCharlie = new BasicDBObject("_id", charlie.getId()); collection.update(findCharlie, updatedCharlieObject.toDBObject());

リスト11 リスト12 リスト13

すべてのリストのテキストをダウンロード

and JavaBig Data

MORE ON TOPIC: