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

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

2014/04

オープンソースのドキュメント指向データベースである mongoDB を CentOS にインストールします。

mongoDB はいわゆる NoSQL データベースの1つで、特長として JSON オブジェクトをそのまま格納することが可能です。RDB ではないためリレーションから関連データをたどって取り出す、といったことはできませんが、JSON に格納された非構造的なデータをそのまま(定義なしで)格納して取り出すことができる、といった特徴があります。


標準リポジトリには含まれていないので、まずは yum リポジトリを用意します:
# vi /etc/yum.repos.d/10gen.repo

[10gen]
name=10gen Repository
baseurl=http://downloads-distro.mongodb.org/repo/redhat/os/x86_64
(32bit版の場合は http://downloads-distro.mongodb.org/repo/redhat/os/i686 )
gpgcheck=0
enabled=1


インストールは yum コマンド一発です:
# yum install mongo-10gen mongo-10gen-server


インストールできたら起動&自動起動設定:
# /etc/init.d/mongod start
# chkconfig mongod on

 

BlueMix 上で使えるデータストアでも触れましたが、この中には2つの DB2 サービスがあります。

1つは SQLDB というサービスで、これは標準的な DB2 と呼ばれている製品がベースになっている、と言われているものです。もう1つの BLUAcceleration というサービスは DB2 のアドバンス版がベースになっていると言われており、インメモリ最適化や列ストアによる高速な統計処理が可能になっているようです。

・・・と、こういった情報までは公開されています。ただ良くも悪くも情報がブラックボックス化されていて、以下の様な情報が公開されていません:
・使われている DB2 のバージョン(=開発時に用意する DB2 JDBC  ライブラリのバージョン)
・データベースの文字コード 

実は一般的にはこれらの情報は DB2 サーバーにコマンドライン接続してコマンドを発行することで確認することができます。ただ BlueMix 環境ではそれらがブラックボックスになっているので調べようがない、、と思っていました。

が、実際にこれら2つの DB2 サービスを作成して、それぞれ環境変数 VCAP_SERVICES を調べてみると、以下の様な内容を得ることができました(一部伏せ字にしてます):

SQLDB:
"SQLDB-1.0": [
 {
  "name": "SQLDB-iw",
  "label": "SQLDB-1.0",
  "plan": "SQLDB_OpenBeta",
  "credentials": {
   "hostname": "192.XXX.XXX.XXX",
   "host": "192.XXX.XXX.XXX",
   "port": 50000,
   "username": "uXXXXXX",
   "password": "XXXXXXXXXX",
   "db": "I_XXXXXX",
   "jdbcurl": "jdbc:db2://192.XXX.XXX.XXX:50000/I_XXXXXX",
   "uri": "db2://uXXXXXX:XXXXXXXXXX@192.XXX.XXX.XXX:50000/I_XXXXXX"
  }
 }
]

BLUAcceleration:
"BLUAcceleration-10.5.3 Rev. A Build 0.1": [
 {
  "name": "BLUAcceleration-es",
  "label": "BLUAcceleration-10.5.3 Rev. A Build 0.1",
  "plan": "Community_Beta",
  "credentials": {
   "hostname": "bluemix01.bluforcloud.com",
   "host": "bluemix01.bluforcloud.com",
   "port": 50000,
   "username": "bluXXXXX",
   "password": "XXXXXXXXXXXX",
   "db": "BLUDB",
   "jdbcurl": "jdbc:db2://bluemix01.bluforcloud.com:50000/BLUDB",
   "uri": "db2://bluXXXXX:XXXXXXXXXXXX@bluemix01.bluforcloud.com:50000/BLUDB"
  }
 }
]

SQLDB の方はホスト名(IPアドレス)が 192.XXX.XXX.XXX となっていました。これはいわゆるプライベート IP アドレス帯ではないのですが、おそらく BlueMix ネットワーク環境内の中に設置されたサーバーになっているようで、外部からは dns でも ping でも db2 クライアントからも直接接続することはできませんでした。BlueMix 上の MySQL なども同様なのですが、まあこのサービスは外部には直接公開されていない、と考えるべきでしょう。

一方、BLUAcceleration のサーバーはホスト名が bluemix01.bluforcloud.com という、どこかで見たような名前。。

・・・ bluforcloud.com って、あれだ、先日サービスがスタートした IBM 版の DBaaS サービスで使われているドメインですね。BlueMix の BLUAcceleration はここのサービス(Managed Service)を使っていたのか:
IBM BLU Acceleration for cloud


ということは、もしかして外部から参照できるかも・・・と思い、コマンドラインコンソールを使うため無償版の DB2 Express-C (10.5.1)をダウンロードしてインストールしました。で、まずはリモートのサーバーノードと DB をカタログ定義して、と:
$ db2
  :
  :
db2 => catalog tcpip node node1 remote bluemix01.bluforcloud.com server 50000
db2 => catalog database bludb as db1 at node node1


そして定義した db1 (=bluemix01.bluforcloud.com:50000 上の bludb データベース)に ID とパスワードを指定して接続を試みてみると・・・

2014042701

あっさり繋がってしまいました(笑)。合わせてこのサービスが 64bit 版 Linux 上に導入された DB2 10.5.3 であることも分かりました。JDBC ドライバはこの DB2 Express-C (10.5.1) にあるものをそのまま使えばよさそうです。

というわけで、続けてデータベース設定情報を確認、と・・・
2014042702


テリトリーコードは US 設定ですが、コードセットは UTF-8 ですね。安心して日本語が使えます。


#本音を言えばこういう情報は公開してほしい


っていうか、BlueMix 上で BLUAcceleration サービスだけ起動して、オンプレミスやクラウドに構築したウェブアプリサーバーからこの BLUAcceleration サービスに接続する、という使い方もできちゃいそうな感じだけど、いいんでしょうか? (^^; 個人的にはそれはそれで嬉しいかも(笑)。





自分用にまとめておく:

(注 2015/01/20 欧州リージョンのログイン方法を追記)


ログイン(米国リージョンの場合)
# cf login -a https://api.ng.bluemix.net -u (IBM ID) -p (パスワード)

ログイン(欧州リージョンの場合)
# cf login -a https://api.eu-gb.bluemix.net -u (IBM ID) -p (パスワード)

ログアウト
# cf logout

ターゲット指定
# cf target -o (IBM ID) -s dev

カレントディレクトリ以下(または war ファイル)をアプリケーション APP1 にプッシュ
# cf push APP1 ( -p ***.war )

アプリケーション APP1 のスケーリングを(インスタンス2個、メモリ1GBに)変更
# cf scale APP1 (-i 2) (-m 1024M)

デプロイ済みアプリケーションの一覧
# cf apps

アプリケーション APP1 の状態を確認
# cf app APP1

アプリケーション APP1 を削除
# cf delete APP1

アプリケーション APP1 を APP2 にリネーム
# cf rename APP1 APP2

アプリケーション APP1 を起動
# cf start APP1

アプリケーション APP1 を停止
# cf stop APP1

アプリケーション APP1 を再起動
# cf restart APP1

アプリケーション APP1 の直近のイベントを表示
# cf events APP1

アプリケーション APP1 の構成ファイル一覧を表示
# cf files APP1

アプリケーション APP1 のログを表示
# cf logs APP1

アプリケーション APP1 の環境変数を表示
# cf env APP1

アプリケーション APP1 の環境変数を設定
# cf set-env APP1 envname envvalue

アプリケーション APP1 の環境変数を初期化
# cf unset-env APP1 envname

アプリケーション APP1 のスタックを表示
# cf stack APP1

現在利用可能なサービス一覧の確認
# cf marketplace

サービス作成
# cf create-service (上記の一覧に現れるサービス種別名) (上記の一覧に現れるプラン名) (利用サービス名)

サービス SVC1 を削除
# cf delete-service SVC1

サービス SVC1 を SVC2 にリネーム
# cf rename-service SVC1 SVC2

生成済みサービス一覧
# cf services

アプリケーション APP1 とサービス SVC1 をバインド(紐付け)
# cf bind-service APP1 SVC1

アプリケーション APP1 とサービス SVC1 とのバインドを解消
# cf unbind-service APP1 SVC1

他にもあるんだけど、当面はこれで事足りるかな。








 
 

「Java で使えるバーコード読み取りライブラリ」を探していました。

開発の関係で「Java から使える」ことが条件でした。また「QRコード」のライブラリは見かけるけど、いわゆる「バーコード」 のは意外と少ない。そしてバーコードを「生成する」のではなく、バーコード画像を「読み取り」たかった、という条件もあります。 加えてライセンスフリーだといいな、と。

これだけの条件で探すとほとんど選択肢はなく、唯一見つけたのが「ZXing(ゼブラクロッシング)」というライブラリでした。 ZXing は単に JavaSE で使えるというだけでなく、Android SDK からも使えます。また QR コードにも対応していたり、読み書き両方に使えたりと汎用性も高そうです。ZXing はソースファイルで提供されているので、そのビルド方法も含めた利用手順を紹介します。なお最新版(3.0)の ZXing をビルドするには JDK 1.7 以上、および Apache Maven が必要です。 

RedHat Enterprise Linux や CentOS であれば以下のコマンドで JDK1.7 をインストールできます:
# yum install java-1.7.0-openjdk-devel

Apache Maven はこんな感じ:
# cd /etc/yum.repos.d
# wget http://repos.fedorapeople.org/repos/dchen/apache-maven/epel-apache-maven.repo # yum install apache-maven

JDK 1.7 と Maven が用意できたら ZXing をビルドすることができます。まず ZXing のダウンロードページから最新のソースファイルをダウンロードして、zip ファイルを展開しておきます。

と、言いたかったのですが、4月25日現在の最新版(3.0.2-SNAPSHOT)はビルドの途中でエラーになってしまい、なんかよく分からなかったので、僕はこちらの 2.3.0 というバージョンを使いました。

展開後、いくつかのフォルダが出来上がりますが、通常の Java(SE) 環境で利用するには core と javase のライブラリが必要です。そのためこの2つのフォルダで JAR ライブラリを Maven でビルドします:
# cd core
# mvn -DskipTests -Dgpg.skip=true install
→ ./target/ に JAR ファイルができている # cd ../javase # mvn -DskipTests -Dgpg.skip=true install
 → ./target/ に JAR ファイルができている

ビルドでできあがった core-X.X.X.jar と javase-X.X.X.jar(X.X.X 部分は ZXing のバージョン)が必要なライブラリになります。これらを Java のプロジェクト内で利用できるように(例えば WEB-INF/lib/ 以下に)コピーして、これで準備完了。

実際にバーコードをデコードするサンプルも記載しておきます。これはローカルシステムの c:/tmp/sample.jpg にバーコード画像がある場合の例ですが、こんな感じ: 
  String filename = "c:/tmp/sample.jpg";
    :
  try{
    //. 画像読み込み
    BufferedImage image = ImageIO.read( new File( filename ) );
    LuminanceSource source = new BufferedImageLuminanceSource( image );
    BinaryBitmap bitmap = new BinaryBitmap( new HybridBinarizer( source ) );

    //. デコード
    Reader reader = new MultiFormatReader();
    Result result = reader.decode( bitmap );

    //. バーコードフォーマット
    BarcodeFormat format = result.getBarcodeFormat();

    //. バーコードコンテンツ(読み取り結果)
    String text = result.getText();
      :
  }catch( Exception e ){
    e.printStackTrace();
  }
    :





さて問題の認識精度ですが、 、、まあ仕方ないのかな、って感じです。画像にバーコードだけが写っている状態であればまだしも、周囲に関係ない部分が含まれていたりすると認識してくれないケースが多いです。

とはいえフリーで使えるデコードライブラリは他に選択肢がないので、贅沢は言えませんよね。
 

(↓2015/Jan/26追記)
このブログエントリに書かれている内容は最新のものではありません。ご注意ください。
また、こちらの記事も参照ください:
Bluemix 内の MySQL データベースでサイズが選択可能になった
(↑2015/Jan/26追記)


IBM BlueMix からは数多くのデータストアサービスが提供されています。RDB(リレーショナルデータベース)だけでも4つあります(青っぽい背景のが IBM 提供サービス、白背景のがオープンソースベースのコミュニティ提供サービスです):

※2014年4月23日時点の情報を元に記述しています。詳しくは各リンク先を参照ください。
サービス価格最大サイズ説明
BLUEAccelerationベータ期間は無料標準で圧縮後1GB(最大10GBまで拡張可能)サイズは圧縮後のサイズなので、実際にはこれら以上のデータを格納可能
SQLDBベータ期間は無料1GB最大接続数は2(BlueMix環境からのみ)
MySQL無料10MB最大接続数は1000
PostgreSQL無料30MB最大接続数は1000

容量10MB のデータベースって・・・ (^^;

ちなみに RDB 以外のデータストアサービスについてはこんな感じです:

サービス価格最大サイズ説明
JSON DBベータ期間は無料1GBJSON ストア型
MongoDB無料250 MBJSON ストア型
Redis無料N/A (?)KEY-VALUE ストア型
Mobile Dataベータ期間は無料(?)ローカルネイティブのように使えるモバイル向けデータストア


それなりに実用的な量のデータを格納しようとすると、IBM 提供のデータストアサービスを選ぶことになるんでしょうかね。リレーションなしと割りきって JSON 型の MongoDB を選ぶという選択もあるけど。

この表だとわかりにくい差もあると思っています。例えば MySQL や MongoDB などは管理コンソールを別途 phpMyAdmin や phpMoAdmin などで用意する必要があります(参照)。一方、BLUAcceleration や SQLDB には標準で管理コンソール機能が付属していたりします。
2014042201


ちなみに BlueMix のサービスで MySQL を立ちあげた場合、BlueMix 内のアプリケーションサーバーからしか接続できません。ただし BlueMix の外で稼働している MySQL に BlueMix のアプリケーションサーバーから接続することは(パフォーマンスに目をつぶれば)可能でした。なので意地悪く特定のポートが閉じられている、とかいうことはなさそうです。どうしても MySQL で10MB以上のデータを使いたい、ということであればデータベースだけは外部接続にする、という選択肢もありますね(遅いし、PaaS のメリットも薄くなるのでオススメしませんけど)。



このページのトップヘ