CentOS 6.4(仮想環境)にMySQL 5.5 と Groonga 4.0 を環境構築、Web アプリケーションから接続する。

※ 2014/09/27 内容を全面的に改定しました。
(以前の内容 → https://gist.github.com/komiyak/1eba77ac07cca2a8ee78

全文検索エンジン Groonga(グルンガ)を、CentOS 6.4 に構築した時のメモです。

今回、下記のような構成にしました。

ホストOS から、ゲストOS上に構築された MySQL, Groonga へ接続するようなイメージです。
仮想環境の構築には、VirtualBox, VMWare 等をお使いください。Vagrant を利用すると便利です。

※ ホストOS ... 手元の PC 上で動いている OS
※ ゲストOS ... ホストOS上で動作している、仮想環境

シェルスクリプトで環境構築を自動化する

仮想環境の構築には、Vagrant を利用します。
Vagrant には、自分で起動した仮想マシンの環境構築(プロビジョニング)を行うための機能が備わっています。
今回は、シェルスクリプトを例にして紹介します。

Shell Scripts - Provisioning - Vagrant Documentation


詳しい使い方は、公式ドキュメントを参照いただきたいですが、ひとまず Vagrantfile に下記の設定を追加すると、ゲストOSの初期化時に任意のシェルスクリプトを実行できます

config.vm.provision "shell", path: "./bootstrap.sh"

「./bootstrap.sh」は自分で用意します。このスクリプトには、仮想マシンの初回起動時に実行したい処理を記述します。


bootstrap.sh の内容と関連ファイルについて

bootstrap.sh は下記のようなレシピとなります。

bootstrap.sh
#!/bin/sh

# MySQL のバージョン
MYSQL_VERSION="5.5.39-2"
# MySQL のユーザー
MYSQL_USER="appuser"
# MySQL のパスワード
MYSQL_PASSWORD="password"

# Groonga の DB名
GROONGA_DB_NAME="example.db"
# Groonga の起動ポート番号
GROONGA_PORT="10041"
# Groonga のバージョン
GROONGA_VERSION="4.0.5"

# -----------------------------------------------------------------------------
# start process
# -----------------------------------------------------------------------------

# おまじない
yum -y install gcc gcc-c++ make zlib zlib-devel openssl openssl-devel apr-devel readline readline-devel curl-devel libxml2 libxml2-devel libxslt libxslt-devel

# -----------------------------------------------------------------------------
# settings
# -----------------------------------------------------------------------------

# ローカル環境で、開発目的のみに利用するため、ファイアーウォール系は OFF に

# Stop postfix
chkconfig postfix off
postfix stop

# Stop iptables
/etc/init.d/iptables stop
/etc/init.d/ip6tables stop
chkconfig iptables off
chkconfig ip6tables off

# -----------------------------------------------------------------------------
# mysql install.
# -----------------------------------------------------------------------------

# Install MySQL
yum -y localinstall http://ftp.jaist.ac.jp/pub/mysql/Downloads/MySQL-5.5/MySQL-shared-compat-${MYSQL_VERSION}.linux2.6.x86_64.rpm
yum -y localinstall http://ftp.jaist.ac.jp/pub/mysql/Downloads/MySQL-5.5/MySQL-server-${MYSQL_VERSION}.linux2.6.x86_64.rpm
yum -y localinstall http://ftp.jaist.ac.jp/pub/mysql/Downloads/MySQL-5.5/MySQL-client-${MYSQL_VERSION}.linux2.6.x86_64.rpm
yum -y localinstall http://ftp.jaist.ac.jp/pub/mysql/Downloads/MySQL-5.5/MySQL-devel-${MYSQL_VERSION}.linux2.6.x86_64.rpm

# MySQL auto launch.
chkconfig mysql on

/etc/init.d/mysql stop
rm /var/lib/mysql/ib_logfile0; rm /var/lib/mysql/ib_logfile1

# Rewirte my.cnf
/bin/cp -f /vagrant/vagrant/config/my.cnf /etc/my.cnf

# make logfile.
mkdir /var/log/mysql
touch /var/log/mysql/error.log; touch /var/log/mysql/general.log; touch /var/log/mysql/slow.log; touch /var/log/mysql/mysqld_safe_error.log
chmod -R 775 /var/log/mysql; chown -R mysql:mysql /var/log/mysql

# restart
/etc/init.d/mysql start

# アプリケーション用のユーザーを作成
mysql -u root -e "\
GRANT ALL PRIVILEGES ON *.* TO ${MYSQL_USER}@localhost IDENTIFIED BY '${MYSQL_PASSWORD}'; \
GRANT ALL PRIVILEGES ON *.* TO ${MYSQL_USER}@'%' IDENTIFIED BY '${MYSQL_PASSWORD}'; \
FLUSH PRIVILEGES;"

# -----------------------------------------------------------------------------
# groonga install.
# -----------------------------------------------------------------------------

# register repository.
rpm -ivh http://packages.groonga.org/centos/groonga-release-1.1.0-1.noarch.rpm

yum install -y wget
yum install -y mecab mecab-devel mecab-ipadic

# install.
su -c -l vagrant "\
cd ~; \
wget http://packages.groonga.org/source/groonga/groonga-${GROONGA_VERSION}.tar.gz; \
tar xvzf groonga-${GROONGA_VERSION}.tar.gz; \
\
cd groonga-${GROONGA_VERSION}; \
./configure --prefix=/usr/local --with-mecab --with-mecab-config=/usr/bin/mecab-config; \
make -j$(grep '^processor' /proc/cpuinfo | wc -l); \
sudo make install; \
\
cd ~; \
rm -rf groonga-${GROONGA_VERSION}; \
rm -rf groonga-${GROONGA_VERSION}.tar.gz;"

# create db & start http server
sudo -u vagrant /usr/local/bin/groonga -n ./${GROONGA_DB_NAME} quit
/usr/local/bin/groonga -p ${GROONGA_PORT} -d --protocol http ./${GROONGA_DB_NAME}

# autorun setting.
/bin/cp -f /vagrant/vagrant/config/initd_groonga_httpd.sh /etc/init.d/groonga
chmod 755 /etc/init.d/groonga

# register chkconfig
chkconfig --add groonga
chkconfig groonga on

# -----------------------------------------------------------------------------
# groonga create schema.
#
# 今回は、プロビジョニング時に、Groonga のスキーマも一気に作ってしまうことにします。
# スキーマは、タイトルと本文を持つブログのようなものと、その転置インデックスです。
# 
# トークナイザ は MeCab を使います。
# -----------------------------------------------------------------------------

# create table
sudo -u vagrant /usr/local/bin/groonga /home/vagrant/${GROONGA_DB_NAME} \
"table_create Articles --flag TABLE_HASH_KEY --key_type UInt32"

# create table
sudo -u vagrant /usr/local/bin/groonga /home/vagrant/${GROONGA_DB_NAME} \
"table_create ArticleIndex --flag TABLE_PAT_KEY --key_type ShortText --default_tokenizer TokenMecab --normalizer NormalizerAuto"


# add column
sudo -u vagrant /usr/local/bin/groonga /home/vagrant/${GROONGA_DB_NAME} \
"column_create --table Articles --name title --flags COLUMN_SCALAR --type ShortText"

sudo -u vagrant /usr/local/bin/groonga /home/vagrant/${GROONGA_DB_NAME} \
"column_create --table Articles --name body --flags COLUMN_SCALAR --type LongText"

# add column
sudo -u vagrant /usr/local/bin/groonga /home/vagrant/${GROONGA_DB_NAME} \
"column_create --table ArticleIndex --name index_title --flags COLUMN_INDEX|WITH_POSITION --type Articles --source title"

sudo -u vagrant /usr/local/bin/groonga /home/vagrant/${GROONGA_DB_NAME} \
"column_create --table ArticleIndex --name index_body --flags COLUMN_INDEX|WITH_POSITION --type Articles --source body"

# EOF
initd_groonga_httpd.sh

bootstrap.sh から参照されているスクリプトで、groonga の http サーバーの起動スクリプトです。bootstrap.sh では、この起動スクリプトを「/etc/init.d/groonga」へ配置し、chkconfig を設定しています。

#!/bin/bash
#
# chkconfig: 345 80 20
# description: groonga httpd
# processname: groonga

# Get function from functions library
. /etc/init.d/functions

start() {
    echo -n "Starting groonga httpd: "
    /usr/local/bin/groonga -p 10041 -d --protocol http /home/vagrant/example.db
    return 0
}

stop() {
    echo -n "Stopping groonga httpd: "
    killproc /usr/local/bin/groonga
    return 0
}

case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
esac
my.cnf

MySQL の設定ファイル、bootstrap.sh で 「/etc/my.cnf」 に配置しています。



環境構築を実行する

上記の設定ができている状態で、「vagrant up」を実行すると環境構築が自動的に行われます。
Groonga のコンパイルなどに少し時間がかかりますが、しばらく待っていると仮想マシンが立ち上がります。

環境構築が完了したら、Groonga の管理ツールへアクセスしてみましょう。

仮想サーバーの IP が 192.168.1.1 とした場合、「http://192.168.1.1:10041/」へアクセスすると、下記のようなページが表示されると思います。

これで、ゲストOSの MySQL・Groonga を利用することができます。


参考URL

公式サイトのドキュメントが、非常に懇切丁寧です。今後のバージョンアップにともなって、いろいろと手法が変化する可能性もありますので、一度目を通されることをお勧めいたします。
http://groonga.org/ja/
http://groonga.org/ja/docs/


以下、余談(チラシの裏

現在(2014/09/27 時点)では、全文検索エンジンといってもたくさんの種類・ソリューションがあります。

  • 現在 世界的に流行している「Elasticsearch」
  • AWS によるフルマネージドなAmazon CloudSearch」
  • Apache Solr」
  • 「Groonga」(もしくは Mroonga、Rroonga など)

選定の際、下記の記事がとても参考になりました。

全文検索システムの比較 - Elasticsearch vs Solr vs Amazon CloudSearch

今回、開発中のエンタープライズ向けWiki「Hinata」に、全文検索機能を追加する上で、どれを使うのが一番良いのか、すごく迷いました。できるだけ導入コストが低く、ある程度スケールする技術がいいなと考えていて、「Amazon CloudSearch」がよさそうだなと思いました。

しかし「Amazon CloudSearch」... 現状、値段が少し張ります。

Amazon CloudSearch 料金表

現時点(2014年9月22日)で一番安価なインスタンスが「スモール検索インスタンス」となっており、Tokyo リージョンで、「$0.130 /1 時間」です。1ヶ月利用したとして、現在の為替($1=109円)で、約「10,200円」の月の維持費がかかります。。

維持費は少し抑えたかったので、次に検討したのは「Mroonga(Groonga の MySQL のストレージエンジン実装)」でした。

「Mroonga」はMySQL を利用する感覚で、全文検索を使うことができるようなので、すごくそれは魅力的でした。

しかし、MySQL バージョンの組み合わせ問題に始まり、考慮することが多すぎて、自分はちょっと萎えてしまいました...。公式ドキュメントのチュートリアル通りに進めても、インストールがなぜかうまく出来なかったですし...。(MySQL がなぜか起動出来ない問題が起きてしまった)

使いたいMySQLに応じてどのmroongaリポジトリを利用すべきか (2013/07/25)

その結果、Groonga を直接利用することにしました。

Ruby on RailsRuby)から Groonga を利用する

Ruby on RailsRuby)からリモート接続で Groonga を利用するには、URI クエリの組み立てや、HTTPレスポンスのパーサーを自分で書く必要があります。(そんな大した実装ではないですが)

下記のポストにて、詳細を説明いたします。

関連記事:Ruby(または Ruby on Rails)から、リモート(HTTP)接続で Groonga を利用する