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

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

(注 この記事は古くなったので、新しい記事をこちらに記載しています)
http://dotnsf.blog.jp/archives/1059206837.html


全文検索エンジン ElasticSearch に日本語形態素解析ソフトウェアである Kuromoji のプラグインを導入して、日本語全文検索環境を構築します。


まずは ElasticSearch をインストールします。ElasticSearch のインストールそのものの手順については以前のエントリを参照してください:
ElasticSearch を導入して CouchBase サーバーの全文検索を行う


ElasticSearch の導入ができたら、この段階で動作確認をしておきます。まずはデータを登録します(青字は実行結果です):
# curl -XPUT http://localhost:9200/mytest/test/1 -d '{ "title":"memo", "text":"ほげほげ" }'

{"_index":"mytest","_type":"test","_id":"1","_version":1,"created":true}


id = 1 のデータとして、title = "memo", text = "ほげほげ" の JSON データを Index = mytest, Type = test で登録しました。次にこのデータを GET メソッドで検索します:
# curl -XGET http://localhost:9200/mytest/test/_search -d '{ "query": { "match": { "title":"memo" } } }'
{"took":54,"timed_out":false,"_shards":{"total":5,"successful":5,"failed":0},"hits":{"total":1,"max_score":0.30685282,"hits":[{"_index":"mytest","_type":"test","_id":"1","_score":0.30685282,"_source":{"title":"memo","text":"ほげほげ"}}]}}


title = "memo" のデータを mytest/test で検索した所、"text" = "ほげほげ" の期待通りの結果が得られました!(ただし、この時点ではまだ Kuromoji を使っていません) 動作確認ができたので、このデータを削除しておきます:
# curl -XDELETE http://localhost:9200/mytest/test/1
{"found":true,"_index":"mytest","_type":"test","_id":"1","_version":1}

ElasticSearch が正しく導入できて、動作も確認できた所で Kuromoji プラグインを導入して ElasticSearch を再起動します:
# /usr/share/elasticsearch/bin/plugin --install elasticsearch/elasticsearch-analysis-kuromoji/2.2.0
# /etc/init.d/elasticsearch restart

そして Kuromoji を有効にして、再度簡単な動作確認をしてみます。まずは新しいインデックスを作成して、Kuromoji をアナライザとして指定します:
# curl -XPUT http://localhost:9200/kuromoji_sample -d '{ "index": { "analysis": { "tokenizer": { "kuromoji_user_dict" : { "type":"kuromoji_tokenizer" } }, "analyzer": { "analyzer": { "type":"custom", "tokenizer": "kuromoji_user_dict" } } } } }'
{"acknowledged":true}

この新しく作成したインデックスに対して日本語文字列を POST して、形態素解析が有効になっているかどうかを確認します:
# curl -XPOST 'http://localhost:9200/kuromoji_sample/_analyze?analyzer=analyzer&pretty' -d '東京スカイツリー'
{
"tokens":[{
"token":"東京",
"start_offset":0,
"end_offset":2,
"type":"word",
"position":1
},{
"token":"スカイ",
"start_offset":2,
"end_offset":5,
"type":"word",
"position":2
},{
"token":"ツリー",
"start_offset":5,
"end_offset":8,
"type":"word",
"position":3
}]
}

「東京スカイツリー」が3つの単語に分割できていることがわかります。これが kuromoji による拡張機能です。


この kuromoji を使ったインデックスを ElasticSearch のデフォルトアナライザとして指定し、ElasticSearch を再起動します:
# vi /etc/elasticsearch/elasticsearch.yml
  :
index.analysis.analyzer.default.type: custom
index.analysis.analyzer.default.tokenizer: kuromoji_user_dict
  :
# /etc/init.d/elasticsearch restart

では改めて2つの日本語データを登録しておきます:
# curl -XPUT http://localhost:9200/kuromoji_sample/test/1 -d '{ "title":"メモ1", "text":"カレーは飲み物" }'
{"_index":"kuromoji_sample","_type":"test","_id":"1","_version":1,"created":true}

# curl -XPUT http://localhost:9200/kuromoji_sample/test/2 -d '{ "title":"メモ2", "text":"カレーライスは和食" }' {"_index":"kuromoji_sample","_type":"test","_id":"2","_version":1,"created":true}

そして、まずは「カレー」で検索してみます:
# curl -XGET http://localhost:9200/kuromoji_sample/test/_search -d '{"query":{"match":{"text":"カレー"}}}'
{
"took":67,"timed_out":false,"_shards":{
"total":5,"successful":5,"failed":0
},"hits":{
"total":1,"max_score":0.15342641,"hits":[{
"_index":"kuromoji_sample","_type":"test","_id":"1","_score":0.15342641,"_source":{
"title":"メモ1","text":"カレーは飲み物"
}
}]
}
}

正しく「カレーは飲み物」のデータがヒットすることが確認できます。気づいていただきたいのは、この時に2番目の「カレーライスは和食」のデータがヒットしていないということです。Kuromoji は「カレー」と「ライス」ではなく、「カレーライス」という単語を認識しているのだと想像できます。

次に「カレーは」で検索します:
# curl -XGET http://localhost:9200/kuromoji_sample/test/_search -d '{"query":{"match":{"text":"カレーは"}}}'
{
"took":8,"timed_out":false,"_shards":{
"total":5,"successful":5,"failed":0
},"hits":{
"total":2,"max_score":0.2169777,"hits":[{
"_index":"kuromoji_sample","_type":"test","_id":"1",
"_score":0.2169777,"_source":{
"title":"メモ1","text":"カレーは飲み物"
}},{
"_index":"kuromoji_sample","_type":"test","_id":"2",
"_score":0.02250402,"_source":{
"title":"メモ2","text":"カレーライスは和食"
}}]
}
}

2つのデータがヒットしています。ここでは "_score" の値に注目します。

_id = 1 のデータでは「カレーは飲み物」という7文字のうち4文字が一致しているため、そのスコアが高くなっています。一方、_id = 2 のデータでは「カレーライスは和食」という9文字のうち「カレー」という3文字と「は」という1文字しか一致していないこともあり、そのスコアが低くなっています。その結果、前者の方がより高い精度で一致していると判断されていることになります。これによってスコア付きの日本語検索も有効に行われていることが分かります。


結構簡単に日本語検索エンジンが作れてしまいました。ElasticSearch は REST でデータの読み書きができるし、Input/Output のフォーマットが JSON なので、プログラマ的にも便利で楽しそうな検索エンジンです。



 

IBM Bluemix は開発者向けのコンテストなども行われていますが、オープンな Cloud Foundry をベースとした PaaS 環境です。そのため、コミュニティなどから Cloud Foundry 向けに提供されている実行環境を流用して環境構築することも可能ですし、それも Bluemix の魅力の1つです。

その一例として、コンテンツ管理システムとして有名な WordPress サーバー環境を Bluemix 上に構築するまでの一連の手順を紹介します。

一部、このエントリの内容と重複していますが、ご了承ください:
BlueMix 上で PHP アプリを動かす



まず IBM Bluemix にログインして、ダッシュボードが表示されている状態にします。そして "Create Application" と書かれたボタンをクリックして、WordPress を導入することになるアプリケーションサーバーを1つ追加(作成)します:
2014062701


アプリケーションサーバーの種類を選択します。最終的には Buildpack から PHP アプリケーションサーバーを選択することになるので、ここではどれを選択しても構いません。図では Liberty for Java を選択しています:
2014062702


"CREATE APP" ボタンをクリックします:
2014062703


アプリケーションサーバーの名称と、ホスト名(の mybluemix.net の前の部分)を指定して "CREATE" ボタンをクリックします。この例では名称は "wordpress"、ホスト名は "wordpress.mybluemix.net" に指定しています。名称は "wordpress" のままでも構いませんが、ホスト名には同じものが使えません。実際に入力する場合はこれとは異なるホスト名を入力してください:
2014062704


しばらく待つとアプリケーションサーバーが作成され、"wordpress" サーバーがダッシュボードに追加されているはずです:
2014062705


次に WordPress のデータベースとなる MySQL サーバーを追加します。再びダッシュボード画面から今度は "Add a Services" ボタン(先ほどの "Add Applicatoin" よりも下にあるはずです)をクリックします:
2014062706


IBM Bluemix 環境内に用意されているサービスの一覧が表示されます。今回は WordPress 用の MySQL データベースサーバーを追加するのが目的なので、少し下の "Data Management" セクションの中にある "mysql" と書かれたアイコンをクリックします:
2014062707


先程と同様の確認画面が表示されるので、"CREATE AND ADD TO APP" ボタンをクリックします:
2014062708


次の画面では、この MySQL サーバーをどのアプリケーションサーバーと紐付けるのか(或いは紐付けなしで起動するのか)を入力する箇所があります。ここでは先程作成した "wordpress" サーバーを選択します。そして "CREATE" ボタンをクリックして MySQL サーバーを作成します:
2014062709


紐付けを行った "wordpress" アプリケーションサーバーを再起動します、という旨のメッセージが表示されたら "OK" をクリックして再起動します。再起動処理は一瞬で終わります:
2014062710


この状態で再びダッシュボード画面を確認すると、作成した MySQL サーバーがサービスとして追加されていることが確認できるはずです:
2014062711


次に、この MySQL サーバーにアクセスするための情報を確認します。ダッシュボード画面の上の方に戻り、アプリケーションサーバー("wordpress")のアイコン部分をクリックします:
2014062712


この "wordpress" サーバーのシステム概要が表示されます。この時点で "wordpress" アプリケーションサーバーと、MySQL サーバーが関連付けられていることが確認できます。 MySQL への接続情報を取得するには、この画面の左ペインから "Runtime" と書かれた箇所をクリックします:
2014062713


この画面の下の方の "Environment Variables" と書かれた所に、環境の変数の情報が表示されている箇所があります:
2014062714


その中にこのような感じで、MySQL サーバーへのアクセス情報が書かれています。この中の赤字部分の内容をメモしておきましょう:
{
   "mysql-5.5": [
      {
         "name": "mysql-qs",
         "label": "mysql-5.5",
         "plan": "100",
         "credentials": {
            "name": "(databasename)",
            "hostname": "192.155.XXX.XXX",
            "host": "192.155.XXX.XXX",
            "port": 3307,
            "user": "(username)",
            "username": "(username)",
            "password": "(password)",
            "uri": "mysql://(username):(password)@192.155.XXX.XXX:3307/(databasename)"
         }
      }
   ]
}

ちなみに "name" の値がデータベース名、"hostname" は MySQL サーバーのホスト名(IPアドレス)、"port" は接続ポート番号ですが、常に 3307 のようです。そして "username" と "password" がユーザー名とパスワードになります。


ここからしばらくは Bluemix 上ではなく、自分のローカル環境での作業になります。まずローカル環境で cf ツールが使える状態にしておきます。cf ツールの導入方法についてはこちらを参照ください。cf ツールが使えるようになっている前提で以下を続けます。ちなみに以下は Linux 環境に cf ツールを導入している前提での説明になりますが、Windows 環境でもほぼ同じだと思っています(未確認です)。

まずはアプリケーションサーバーのドキュメントルートに相当する空のディレクトリを1つ作成しておきます。今後、このディレクトリの中にドキュメントルートの内容となるモジュールを追加していくことになります:
# cd /tmp
# mkdir wp
# cd wp


今回は PHP アプリケーションである WordPress を導入することになりますが、この PHP アプリを Bluemix で動かす場合、ローカル環境ではアプリケーションサーバーのドキュメントルート以下の状態を作っておく必要があります。今回であれば、ドキュメントルート以下に WordPress を導入することになるので、WordPress のモジュールを用意して展開しておくことになります。

というわけで、まずは最新版の WordPress を入手します。WordPress のホームページから最新版のバージョンを確認して、モジュールをダウンロードします(2014/06/27 時点での最新の日本語版は 3.9.1 でした):
# wget http://ja.wordpress.org/wordpress-3.9.1-ja.zip

ダウンロードしたモジュールを展開します。展開後、インストールモジュールは不要なので削除するか、このディレクトリ以下に含まれないディレクトリに移動します(含まれていると一緒にデプロイされてしまいます):
# unzip wordpress-3.9.1-ja.zip
# rm wordpress-3.9.1-ja.zip

なお、今回は /tmp/wp をドキュメントルートとします。WordPress は /tmp/wp/wordpress 内に展開されているので、実際に WordPress にアクセスするには http://wordpress.mybluemix.net/wordpress という URL でアクセスすることになります。もし http://wordpress.mybluemix.net/ という URL でアクセスできるようにしたいのであれば、/tmp/wp/wordpress をドキュメントルートとみなすことになります。この点、ご注意ください。


展開された WordPress モジュールの設定ファイルを Bluemix 環境用に編集します。まずは wordpress/wp-config-sample.php ファイルを wordpress/wp-config.php にリネームします(これが設定ファイルになります):
# mv wordpress/wp-config-sample.php wordpress/wp-config.php

次にこの wordpress/wp-config.php を編集して、Bluemix 上の MySQL サーバーにアクセスできるようにします。具体的には以下の赤字の箇所を上記でメモした自分の環境に合わせて編集してください:
# vi wordpress/wp-config.php
: define('DB_NAME', '(databasename)' ); データベース名 define('DB_USER', '(username)' ); DBユーザー名 define('DB_PASSWORD', '(password)' ); DBパスワード define('DB_HOST', '192.155.XXX.XXX:3307' ); ホスト名:ポート番号
define('FS_METHOD', 'direct' ); プラグインのアップデート用にこの行を追加 :

これらに加えて最初から加えておきたいプラグインやテーマなどがあれば初めから入れておきます。今回は特に用意しません。

最後にメディアアップロード用とアップグレードのフォルダを作成して、プラグインやテーマ用フォルダと合わせて書き込みパーミッションを与えておきます:
# mkdir wordpress/wp-content/uploads
# mkdir wordpress/wp-content/upgrade # chmod 777 wordpress/wp-content/uploads
# chmod 777 wordpress/wp-content/upgrade
# chmod -R 777 wordpress/wp-content/plugins
# chmod -R 777 wordpress/wp-content/themes 

これでローカルホスト側の準備も整いました。改めてドキュメントルート用に作成したフォルダへ移動して、cf ツールで API にログインし、ディレクトリごと Bluemix の wordpress サーバーへ push します。またその際にコミュニティから提供されている PHP アプリケーションサーバーの buildpack を指定することで wordpress サーバーを PHP アプリケーションサーバーとしてデプロイします。デプロイに少し時間がかかりますが、全て完了することを確認します:
# cd /tmp/wp
# cf login -a https://api.ng.bluemix.net -u (IBM ID) -p (パスワード) # cf push -b https://github.com/dmikusa-pivotal/cf-php-build-pack.git wordpress :
:
:
1 of 1 instances running

App started

Showing health and status for app wordpress in org (IBM ID) / space dev as (IBM ID) ...
OK

requested state: started
instances: 1/1
usage: 512M x 1 instances
urls: wordpress.mybluemix.net

state since cpu memory disk
#0 running 2014-06-27 11:42:09 PM 0.0% 68.2M of 512M 55.1M of 1G 
 

これで wordpress.mybluemix.net サーバーに PHP アプリケーションサーバー環境と WordPress を展開したドキュメントルート以下がデプロイされました。ウェブブラウザで http:///wordpress.mybluemix.net/wordpress/ にアクセスしてみると、導入した WordPress の初期セットアップ画面が表示されるはずです:
2014062715


初期セットアップができてしまえば、WordPress として使うことができます:
2014062716


これで IBM Bluemix 上で WordPress の動くサーバー環境を作ることができました。WordPress のような、どちらかというと IaaS 向けのオープンなツールを使うことができる、という意味でも Bluemix(Cloud Foundry) という PaaS のポテンシャルの高さを感じますね。






























CentOS に Java アプリケーションサーバーである Apache Tomcat を導入します。
2014062601



手順としては、まず Java(JDK) をインストールし、その後で Tomcat を導入します。


Java(JDK) のインストール

Oracle Java でも Open Java でもいいのですが、ここでは簡単な後者の手順を紹介します。Java 7 であればこのコマンドで JDK が導入できます:
# yum install java-1.7.0-openjdk-devel

あるいは Java 実行環境だけでもよければこちら:
# yum install java-1.7.0-openjdk

これだけ。


Apache Tomcat のインストール

Apache Tomcat も yum で導入できます。インストールと、起動と、自動起動設定までを行っています:
# yum install tomcat6 tomcat6-webapps tomcat6-admin-webapps
# /etc/init.d/tomcat6 start
# chkconfig tomcat6 on

ちなみにこの方法で導入すると Apache Tomcat 6 が /var/lib/tomcat6/ 以下にインストールされます。

起動後(/etc/init.d/tomcat6 start 実行後)にブラウザで http://(サーバーアドレス):8080/ にアクセスすると Tomcat のデフォルトトップ画面が表示され、正しく導入・動作できていることが確認できます:
2014062701



Apache Tomcat の設定

設定ファイルを書き換えて管理用画面にもアクセスできるようにします:
# vi /etc/tomcat6/tomcat-users.xml

(以下を </tomcat-users> の直前に追加)
  <role rolename="manager"/>
  <user name="admin" password="(管理者用パスワード)" roles="manager"/> 

そして Tomcat サーバーを再起動します:
# /etc/init.d/tomcat6 restart

これで管理用画面のURL である http://(サーバーアドレス):8080/manager/html にもアクセスできるようになりました。ログイン時の ID とパスワードは上記 tomcat-users.xml で指定したものです:
2014062702




(おまけ)Apache Tomcat を 80 番ポートで起動する

まず設定ファイルを書き換えます。server.xml に proxyPort の部分を追加します:
# vi /etc/tomcat6/server.xml

    :
  <Connector port="8080" protocol="HTTP/1.1"
        connectionTimeout="20000"
        redirectPort="8443"
        proxyPort="80" />
:

そして iptable で 80 番ポートへのリクエストを 8080 番に転送し、この設定ルールを iptables に保存します:
# iptables -t nat -I PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080
# /sbin/service iptables save



これで Tomcat を再起動すると、Tomcat に 8080 番ポートではなく、 80 番ポートでアクセスできるようになります。
 

このページのトップヘ