はじめに

デジタルイノベーション推進のため、エンジニアに新たなIT要素技術とその知識・技能の獲得が求められています。

IoT基盤構築を例にとると、大量のセンシングデータ等を高速かつリアルタイムに処理・格納するためのIT要素技術として、従来型のSQLデータベースよりも高速にデータ処理可能なインメモリデータグリッドといった新技術の採用が進んでいます。それに伴って、データベース構築手法を中心にデータベースエンジニアにも新たな知識・技能の獲得が求められています。

本記事では、インメモリデータグリッド実装として、Pivotal GemFire(以下、GemFire)を取り上げ、データベースエンジニアのためのインメモリデータグリッドにおけるデータベース設計・構築・管理の基本について解説します。

データ構造について

従来型のSQLデータベースでは、テーブル型データ構造の採用が主流です。他方、GemFireはNoSQLデータベースとしてキーバリュー型データ構造を採用しています。SQLデータベースとGemFireとの比較という観点で、両データ構造のおおまかな違いについて図1をご覧下さい。

F8256447e084c1421ea5e9e91e0fedd1d0bd9e49
図1 テーブル型とキーバリュー型の違い

まず言えるのは、GemFireでは他のNoSQLデータベース同様、SQLデータベースにおけるテーブル間の関係性を定義する外部キーの概念がないことです。一般的に、キーバリュー型のNoSQLデータベースはデータアクセスパフォーマンスを重視しており、パフォーマンス劣化を引き起こす外部キー制約のような整合性チェックは極力行いません。GemFireもその例に漏れず、外部キーの概念がありません。

また、キーバリュー型データ構造はカラムがキーとバリューの二つしかないテーブル型構造に見えます。ただし、GemFireはキーやバリューとしてオブジェクト指向言語Java等のオブジェクトをそのまま格納することができる、いわばオブジェクトデータベースの側面があります。したがって、オブジェクトとして表現し得る任意の構造を持ったデータを格納することが可能です。つまり、GemFireでSQLデータベースのようなテーブル型データ構造を持つことが可能と言えます。

以下、SQLデータベースからインメモリデータグリッドへのシームレスな移行を念頭に、GemFireでSQLデータベースと同様のテーブル型データ構造でデータ設計、データベース構築を行うことを考えます。

テーブル設計

SQLデータベースでデータベースを構築する際、DDLを用いて格納するデータ型を厳密に定義した上でテーブル設計・作成を行います(図2)。

97ef7672f0dc627b96ac417ed21267a51eadb8c5
図2 DDL によるテーブル設計例

GemFireの場合、他のNoSQLデータベースと同様、DDL等でデータ型を厳密に定義する概念はありません。「リージョン」と呼ばれる、SQLデータベースのテーブルに該当する領域に、データとして任意の型のオブジェクトを挿入することができます。ただ、型制限なくリージョンへのデータ挿入を許可すると、データベース管理が煩雑となり、最悪の場合、データベースに不整合が発生します。また、アプリケーション側でデータ型に応じた判定処理等が必要となり、データ処理に関するバグを増やす要因となります。

データ型を厳密に定義し、リージョンへ挿入するデータ型制限を行う一つの方法として、オブジェクト型を定義し、それを元にクラスを記述(以下、ドメインクラス)、対象リージョンに対して当該クラスから生成されたオブジェクト以外挿入できないよう設定することが挙げられます。

まず、オブジェクト型の定義ですが、GemFire自体がJava言語で記述されているので、Java言語でドメインクラスを記述します。図2の例に沿って記述すると図3のようになります。

89bd1d428d4f5bc00e93922d1f475226af075616
図3 ドメインクラスによるオブジェクト型定義例

Java言語の仕様に従って、テーブル名をクラス名に、各カラムの型と名前をフィールド変数としてオブジェクト型と変数名にマッピングします。実際に GemFireに格納・各種操作を行うオブジェクトとして扱うためには、アプリケーション開発者の責務としてコンストラクタやゲッターメソッド、セッターメソッドの定義が必須ですが、データ定義は上述のコードのみです。クラスのパッケージ名は任意のものでかまいませんが(GemFireで予約済みのorg.apache.geodeやcom.gemstone.gemfireを除く)、ドメインクラス用に共通のパッケージ名を設定すると後述のオブジェクトシリアライザの設定が容易になります。ここでは、パッケージ名としてio.pivotal.dataと設定しています。

次に、テーブル型データ構造をキーバリュー型のデータ構造へマッピングする方法について検討します。いくつかの方法が考えられますが、ここではSQLデータベースのような主キー制約を実現する観点で、テーブル型データ構造の主キー(図2のid)をキーバリュー型のデータ構造のキーにマッピングします。そして、図3のドメインクラスはバリューにマッピングすることになりますが、このままですと、キーとバリューとに主キー相当の値が重複して保持されてしまいます。重複を避けたい場合は図3のフィールド変数idをドメインクラスから削除することになるでしょう。ここでは、データの扱いが容易なので主キー相当の値をそのままキーとバリューに重複して保持することとします(理由については後述します)。