まだプログラマーですが何か?

プログラマーネタとアスリートネタ中心。たまに作成したウェブサービス関連の話も http://twitter.com/dotnsf

タグ:mongodb

IBM DB2 V10.5 ではテクノロジープレビューという正式サポート前の扱いですが、NoSQL 機能が使えるようになっています。

これは MongoDB のような JSON オブジェクトストア機能であり、実際に MongoDB のコマンドラインクライアントからも利用することができます。

このテクノロジープレビュー機能を有効にして、実際に使ってみるまでの手順を紹介します。なお環境は CentOS 6(64bit) 版を前提とします。


まず IBM DB2 V10.5 を導入します。DB2 は無償版の Express-C エディションが提供されているのでそれを使います。詳しい手順はこちらのエントリを参照ください(エントリはバージョン10.1での説明ですが、2015年1月5日現在、同じ手順で最新のバージョン10.5がダウンロード&導入できます):
DB2 Express-C (10.1) を CentOS にインストール&セットアップする


併せて MongoDB を導入します。詳しい手順はこちらを参照ください(この手順では MongoDB サーバーも導入されますが、今回はクライアントのみ使います):
mongoDB を CentOS 上にインストールする


最後に DB2 の NoSQL 機能を有効化する手順の中で JRE が必要になるため、Java 実行環境を導入します:
# yum install java-1.7.0-openjdk


ここまでの準備ができたら実際に DB2 の NoSQL 機能のセットアップを行います。システム上で db2inst1 ユーザーに切り替えて、NoSQL 用のデータベース jsondb をコードセット UTF-8、テリトリー jp で作成します(異なる内容で作成する場合はコマンドの赤字部分を該当内容に合わせて変更してください):
# su - db2inst1
$ db2 create database jsondb automatic storage yes using codeset utf-8 territory jp collate using system

しばらく待つと NoSQL データベース jsondb が作成されます。プロンプトが戻ったら続けて DB2 のポートを開きます。そして DB2 を再起動(ストップ&スタート)して、この内容を反映させます:
$ db2set DB2COMM=TCPIP
$ db2 update dbm cfg using svcename 50000
$ db2stop
$ db2start

そして db2inst1 ユーザーの ~/.bashrc を開いて編集し、環境変数の設定を行います:
$ vi ~/.bashrc
  :
  :
(最後に以下を追加して保存)
export JAVA_HOME=/usr/lib/jvm/jre-1.7.0-openjdk.x86_64
export PATH=$PATH:/opt/ibm/db2/V10.5/json/bin
export CLASSPATH=$CLASSPATH:/opt/ibm/db2/V10.5/json/lib/nosqljson.jar:/opt/ibm/db2/V10.5/json/lib/mongo-2.8.0.jar:/opt/ibm/db2/V10.5/json/lib/js.jar:/opt/ibm/db2/V10.5/json/lib/db2NoSQLWireListener.jar

上記で作成した jsondb データベースは初期状態では無効になっているので、コマンドラインから有効になるよう指定します。改めて db2inst1 ユーザーでログインし(或いは上記の ~/.bashrc の変更を反映し)、以下のコマンドを実行します:
# su - db2inst1
$ cd /opt/ibm/db2/V10.5/json/bin
$ ./db2nosql.sh -user db2inst1 -hostName localhost -port 50000 -db jsondb -setup enable -password (db2inst1ユーザーのパスワード)

最後に通信リスナーを MongoDB と同じ 27017 番ポートで起動します(db2inst1 ユーザーで、/opt/ibm/db2/V10.5/json/bin ディレクトリ上で実行する必要があります):
$ cd /opt/ibm/db2/V10.5/json/bin
$ ./wplistener.sh -start -mongoPort 27017 -userid db2inst1 -password (db2inst1ユーザーのパスワード) -dbName jsondb -logPath /tmp

   :
--- The wire listener is being started ---
Starting the channel listener on port 27017

上記のように、画面に "Starting the chennel listener on port 27017" と表示されれば DB2 の NoSQL データベース機能の起動に成功しています。


最後に動作確認の意味で、この DB2 上で動いている NoSQL データベース jsondb に、MongoDB クライアントから接続してみましょう。同じシステム上の別端末を開いて、mongo コマンド(MongoDB クライアント)を実行してみます(青字はシステムからの出力結果です):
# mongo
MongoDB shell version: 2.6.6
connecting to: test
>

エラーが表示されていなければ接続できたことになります。続けて jsondb データベースに接続して、myfirstcollection コレクションに "_id" = 100 の JSON 文書を作成/更新/検索してみます:
> use jsondb (DB変更)
switched to db jsondb
> db.myfirstcollection.insert( { "_id":100, "name":"K.Kimura" } ) (文書作成)
Cannot use commands write mode, degrading to compatibility mode
WriteResult({ "nInserted" : 1 })
> db.myfirstcollection.findOne() (検索)
{ "_id" : 100, "name" : "K.Kimura" } (成功)
> db.myfirstcollection.update( { "_id":100 }, {"name":"Kei KIMURA" } ) (更新)
WriteResult({ "nMatched" : 1, "nUpserted" : 0 }) (成功)
> db.myfirstcollection.findOne() (再検索)
{ "_id" : 100, "name" : "Kei KIMURA" } (成功)
  :
  :
> quit()
#

MongoDB クライアントからの一通りのコマンドは全て成功しているようです。


mongo の基本的なコマンドに関しては全て動いているようですが、どの程度の互換性があるのか/ないのか、MongoDB のライブラリが使えるのか/使えないのか、まだちょっとわかりません。 でもこれが使えるようであれば、PHP から MongoDB ライブラリを経由して DB2 にアクセスする、といった、これまでできなかったような使い方も広がってくると思います。この機能が正式サポートされるのが楽しみです。




(参考)
http://www.ibm.com/developerworks/jp/data/library/techarticle/dm-1306nosqlforjson4/
 

謎だった Power 版 RHEL(RedHat Enterprise Linux) での MongoDB の動かし方が分かりました!

これまでは「CPU のエンディアンの違いにより MongoDB が動かなかった」と思っていたのですが、IBM のダウンロードサイトで Power 版 RHEL 向けビルド済み rpm パッケージの存在を確認しました。これを使います。


まず準備段階として Power 版 RHEL 環境を用意します。・・・といっても普通の人はそんな環境持ってないですよね(苦笑)。 2週間のお試し程度であれば、開発者向けサービスである IBM Power Development Cloud を利用して環境を構築することも可能です。 その場合の手順はこちらのブログエントリを参照ください:


Power 版 RHEL の準備ができたら早速 MongoDB を導入しましょう。といっても特別な作業ではなく、必要な rpm パッケージを IBM からダウンロードしてインストールするだけです。Intel 版 RHEL と異なるのはファイル名のアーキテクチャ部分が i686 とか x86_64 とかではなく、ppc64 になっていることくらいです。あと現在用意されている MongoDB はバージョン 2.4.9(RC0) のようです:
# cd /tmp
# yum install wget boost-devel
# wget ftp://ftp.software.ibm.com/linux/rpms/redhat/6.5/v8-3.14.5.10-2.el6.ppc64.rpm
# wget ftp://ftp.software.ibm.com/linux/rpms/redhat/6.5/libmongodb-2.4.9-1.el6.ppc64.rpm
# wget ftp://ftp.software.ibm.com/linux/rpms/redhat/6.5/mongodb-server-2.4.9-1.el6.ppc64.rpm
# wget ftp://ftp.software.ibm.com/linux/rpms/redhat/6.5/mongodb-2.4.9-1.el6.ppc64.rpm
# rpm -ivh v8-3.14.5.10-2.el6.ppc64.rpm
# rpm -ivh libmongodb-2.4.9-1.el6.ppc64.rpm
# rpm -ivh mongodb-server-2.4.9-1.el6.ppc64.rpm
# rpm -ivh mongodb-2.4.9-1.el6.ppc64.rpm

これで MongoDB のインストールは完了です。念のため、導入先を確認しておきましょう:
# which mongod
/usr/bin/mongod
# which mongo
/usr/bin/mongo

MongoDB の起動はコマンドラインから、以下の内容を実行します:
# mongod --dbpath /var/lib/mongodb

実行するとサーバーコンソールのようにメッセージがずらずらと・・・出てくればサービスの起動成功です。ちなみにサービスの終了は CTRL + C です。
2014121001


Mongo クライアントは何の違いも感じずに使えます:
2014121002


この Power 版 RHEL 向け MongoDB はいつから用意されてたんだろう? ともあれ、これで Power 版の RHEL でも MongoDB が動くことが確認できました。本当に Intel 版との違いがなくなりつつあることを実感します。


そして、これはつまり MongoDB に対応したフレームワーク(cakePHPとか)を Power 版 RHEL で動かすことができるようになったのかな?? とも思っているのですが、実際 cakePHP で使ってみると Intel 版では見たことのないエラーメッセージに遭遇したりして、まだもう少し待った方がいいのかな、とも思ってたりします。要はちゃんと動かして調べましょう、ということで。


最後に、自分が業務で開発に携わっている公開済みサービスがこの Power 版 RHEL 環境でもある程度動いたので記念アップ!
2014121003

 

PHP で MongoDB を使っていると、「その中身を簡単に確認したい!」と思うことがままあります。

MySQL であれば phpMyAdmin など、有名なツールがいくつかありますが、MongoDB の場合は数が限られてい(るように思い)ます。

そんな中で自分が使っているのが phpMoAdmin です。phpMyAdmin と名前が似ていますが、おそらく意識しているのでしょう。

phpMoAdmin はダウンロード&展開するとわかりますが、 moadmin.php という1つの .php ファイルから作られている MongoDB 管理用GUIツールです。ファイル1つなので、このファイルをドキュメントルート以下におくだけで設置完了です。

なお、接続先の MongoDB サーバーの情報もこのファイルの中に直書きします(何も指定しないとローカルホスト状の MongoDB を参照しに行きます)。
例えば MongoDB サーバーがリモートの mongo.test.com というサーバーで、デフォルトの 27017 番ポートで稼働している場合、この moadmin.php ファイルをエディタで開いて 'MONGO_CONNECTION' の値として以下のように記述して保存します:
  define( 'MONGO_CONNECTION', 'mongodb://mongo.test.com:27017' );

これでウェブブラウザからこの moadmin.php を開けば、目的の MongoDB サーバーにアクセスして、コレクションやレコードの状態を参照することができるようになります。


ところで、MongoDB を使っていると大量のデータを扱うことが少なくありません(そのための No-SQL だと思っています)。コレクション(RDB でいう所のテーブル)を指定して、そのレコードの一覧を参照することは簡単ですが、特定の条件を満たすレコードだけを取り出して見ることはできないでしょうか? それが今から紹介するクエリー(Query)機能です。

クエリーを実行するには、コレクションのレコード一覧の画面から "[query]" と書かれた箇所をクリックします:
2014101601

するとクエリーを指定するフィールドが開きます。ここに目的のレコードに絞り込むクエリーを記述して "Query" をクリックすることでレコードを選別することができます。
2014101602


さて、意外と戸惑ったのが、このクエリーの指定方法です。例えば「item_id の値が'14'のレコード」を探したい場合、どのように指定すればいいのでしょうか?意外と資料や情報が少なくて難儀しました。

結論としては CakePHP の find の中で指定するような感覚で、以下のように記載します:
 array('item_id'=>'14')
2014101603

無事見つかりました。同様にして「item_id が '14' で、category_id が '10' のレコード」であればこんな感じになります:
 array('item_id'=>'14','category_id'=>'10')


注意が必要な点として、どうやらこのクエリーで数値を指定する場合、そのデータが数値文字列なのか、数値なのかを意識して指定する必要がありそう、ということです。例えば先程の例を
 array('item_id'=>14)
のように 14 を数値文字列ではなく数値として指定した場合、レコードは見つかりませんでした。
2014101604


要するにデータがどのような型で格納されているのかをちゃんと意識して指定する必要があるのだと思います。

このあたりを気をつけていれば軽量で使える便利なツールといえそうです。


 

NoSQL データベースの1つで、非構造データを JSON 形式で保持できる mongoDB を「レプリカセット」と呼ばれる方法でクラスタリングします。

今回は3台の CentOS マシンによるクラスタ構成を行います。1台がプライマリ、1台がスレーブ、そして1台がアービターと呼ばれるフェイルオーバー時のマスター選択専用ノード(データは保持しない)で構成します。


プライマリ/スレーブ/アービターそれぞれのマシンの IP アドレスは P.P.P.P / S.S.S.S / A.A.A.A であると仮定して以下を記載します。


まず、3台のマシンそれぞれに MongoDB をインストールします。MongoDB の導入手順にそのものについては以下を参照してください:
mongoDB を CentOS 上にインストールする

上記手順最後のコマンド "chkconfig mongod on" までが実行されていれば、3台のマシン上それぞれで MongoDB が(独立して)稼働している状態になっています。


ここからがレプリカセット環境構築のための設定になります。まずそれぞれのマシン上で /etc/mongod.conf を編集します。編集内容は2点で (1) bind_ip 行をコメントアウト、 (2) replSet 行を追加 します:
# vi /etc/mongod.conf
  :
  :
# bind_ip=127.0.0.1 (コメントアウト)
  :
  :
replSet=testRS (この1行を追加)
  :
  :
なお、replSet=XXX で追加する行の XXX 部分は同じ文字列(上記例では testRS )を指定します。これによって3台の mongoDB サーガーが同一のレプリカセット環境上にあることを指定します。

bind_ip 行は接続を受け付ける元のアドレス範囲を指定する行です。127.0.0.1 が指定されていると localhost のみが指定されたことになり、他のマシンからの接続を受け付けなくなってしまうのでコメントアウトします。

ここまで出来た所で、3台のマシンそれぞれで mongoDB を再起動します:
# /etc/init.d/mongod restart


次にプライマリサーバー(P.P.P.P) 上で、各マシンの役割を指定します。プライマリサーバー上でコンソールにログインします:
# mongo

> 

コンソール画面内で以下を実行します:
> config = { _id:"testRS", 
  members:[
    { _id:0, host:"A.A.A.A:27017", arbiterOnly:true }, 
    { _id:1, host:"P.P.P.P:27017" },
    { _id:2, host:"S.S.S.S:27017" }
  ]
}
 :
:
> rs.initiate( config ) :
:
>

上記コマンドで testRS(replSet に指定した文字列値)に属する3台のマシンの IP アドレスとポート番号を指定し、A.A.A.A のマシンについてはアービターのノードであることも指示しています。 そしてその内容を rs.initiate コマンドで実行して初期化しています。

これが成功するとレプリカセットの完成です。rs.status() コマンドでレプリカセットの設定状況を確認することもできます:
> rs.status()
{
  "set": "testRS",
  "date": ISODate("2014-06-02T12:34:56Z"),
  "myState": 1,
  "members": [
    {
      "_id": 0,
      "name": "A.A.A.A:27017",
      "health": 1,
      "state": 7,
      "stateStr": "ARBITER",
      "uptime": 30,
      "lastHeartbeat": ISODate("2014-06-02T12:34:56Z"),
      "pingMs": 1
    },
    {
      "_id": 1,
      "name": "P.P.P.P:27017",
      "health": 1,
      "state": 1,
      "stateStr": "PRIMARY",
      "uptime": 80,
      "optime": Timestamp(1357209986000, 1),
      "optimeDate" : ISODate("2014-06-02T12:34:56Z"),
      "self": true
    },
    {
      "_id": 2,
      "name": "S.S.S.S:27017",
      "health": 1,
      "state": 2,
      "stateStr": "SECONDARY",
      "uptime": 30,
      "optime": Timestamp(1357209986000, 1),
      "optimeDate" : ISODate("2014-06-02T12:34:56Z"),
      "lastHeartbeat": ISODate("2014-06-02T12:34:56Z"),
      "pingMs": 1
    }
  ],
  "ok": 1 
}

> 

_id = 0 のマシンがアービター、1 のマシンがプライマリ、2 のマシンがスレーブになっていることを確認します。


一応これでレプリカセット環境としては動くようになりました。が、このままだとスレーブサーバーはプライマリサーバー以外のマシンからの接続を許可しないため色々不便です。というわけで、最後にスレーブサーバーにプライバリサーバー以外からも接続できるよう設定します。

スレーブサーバー上でコンソールにログインし、db.getMongo().setSlaveOk() コマンドを実行します:
# mongo

> db.getMongo().setSlaveOk()

>

これでスレーブサーバーに他のマシンから接続して状況を確認することもできるようになりました。




PHP を使ったアプリケーション開発フレームワークの1つ、cakePHP を最近あちこちで使うようになったので、その環境を構築する手順を紹介します。


まず前提条件として、PHP/MySQL(または mongoDB、或いは両方)/Apache HTTPD がセットアップ済みである必要があります。これらは全て異なるサーバーに用意しても構いませんが、本エントリでは同一のマシン内(localhost)に構築する前提で紹介します。

HTTP サーバーとして Apache HTTPD の代わりに Nginx を使うこともできますが、少し手順が異なってくるのでここでは詳細は省略します。DB は RDB を使うのであれば MySQL(又は互換性のある MariaDB) を、高速な JSON DB を使うのであれば mongoDB を、併用するのであれば両方をセットアップしておきます。これら前提条件の導入手順の詳細は以下を参照してください:
CentOS に PHP を導入する
CentOS に MySQL をインストールする
mongoDB を CentOS 上にインストールする
CentOS に Apache HTTPD を導入して SSL を有効にする


前提条件の用意が済んだら、公式ページから最新版の cakePHP をダウンロードします。仮にダウンロードモジュール名が cakephp-2.4.7.zip(バージョン 2.4.7)であったと仮定して以下の説明を続けます:


まずは cakePHP で開発するアプリケーションが使うデータベースを定義します。既存のものを使っても構いませんし、新規に作成しても構いません。ここでは MySQL 内に "cakedb" という名前の UTF8 データベースを作成しています。また同データベースにアクセスするためのユーザー cake_user を定義しました:
# mysql -u root -p
Enter password: (パスワード入力)
  :
  :
mysql> create database cakedb default character set utf8;
Query OK, 1 row affected (0.00 sec)
mysql> grant all privileges on cakedb.*  to cake_user@localhost identified by 'cake_pass' with grant option;
Query OK, 1 row affected (0.00 sec)
mysql> quit
#

次に cakePHP モジュールを展開します。この例ではドキュメントルート(/var/www/html/)以下に展開して、cake/ というフォルダ名に変更しています:
# cd /var/www/html
# unzip /tmp/cakephp-2.4.7.zip
# mv cakephp-2.4.7 cake

これで cakePHP がドキュメントルート以下に展開されました。が、利用するにはもう少し設定が必要です。まずは接続先データベースを定義します。まず app/Config/database.php.default を app/Config/database.php にコピーして、その内容を以下のように変更/保存します(この内容はデータベースに MySQL を使う前提で記載しています):
public $default = array(
  'datasource' => 'Database/Mysql',
  'persistent' => false,
  'host' => 'localhost',
  'login' => 'cake_user',
  'password' => 'cake_pass',
  'database' => 'cakedb',
  'prefix' => '',
  'encoding' => 'utf8'
);

public $cakedb = array(
  'datasource' => 'Database/Mysql',
  'persistent' => false,
  'host' => 'localhost',
  'login' => 'cake_user',
  'password' => 'cake_pass',
  'database' => 'cakedb',
  'prefix' => '',
  'encoding' => 'utf8'
);
この設定では上記で作成した MySQL 内の cakedb データベースに cake_user : cake_pass で接続するための $default という配列変数を定義しています。また全く同じ内容を $cakedb 変数にも設定しています。

cakePHP では特に何の指定もしない場合の接続先は $default 変数に定義する必要があります。そのための設定です。

なお、それだけならばわざわざ $cakedb 変数を定義する必要はないのですが、後から $default 以外の接続先を利用することも考慮してこのような設定にしています。MySQL 内の別のデータベースや、MySQL 以外の別データベースにも接続したり、接続先を随時変更したりすることができるようにこのようにしている(逆を言えば、MySQL 内の1つのデータベースだけを対象に読み書きするのであれば $default だけの定義で充分)、と理解してください。


次に cakePHP は一時的にファイルを作成することがあるため、そのための書き込み権限を付与します:
# cd app
# chmod -R 777 tmp

最後にセキュリティのための設定を行います。app/Config/core.php 内に 'Security.salt'(ハッシュキーの生成に用いる文字列)、および 'Security.cipherSeed'(暗号化・復号化で利用する文字列)がデフォルト状態で定義されています。これをそのまま使うのは危ないので、独自の内容に変更します。前者は半角英数字、後者は数値文字列で適当な内容に変更して保存ます:
    :
  Configure::write('Security.salt', 'ABCDabcd1234' );
    :
    :
  Configure::write('Security.cipherSeed', '12345678' );
    :


この時点で cakePHP を利用することができるようになります。ブラウザでドキュメントルートの cake サブディレクトリにアクセスすると、以下の様な画面になるはずです:
2014051301


この画面では緑および黄色のメッセージしか出ていませんが、ここに赤いメッセージが出ている場合はまだ設定が正しく完了していないことを意味しています。メッセージ内容を見直して、適宜対応してください。

とりあえず最低限のインストールはこんな感じです。



 

このページのトップヘ