CentOSにMySQLとHandler Socketを入れてみる

MySQL Casual Advent Calendar 2011の13日目を担当するkotaroitoです。どうぞよろしくお願いします。

普段は、Opsの方々が用意してくれたMySQLを使うのみ、Explainの読み方はわかるけどサーバの設定無理、というまさにCasualユーザです。勢いに任せてMySQL Casual Advent Calendarの参加ボタンをポチったものの、紹介できるほどのネタもない...。

ここは開き直って、自分がやりたいことをやろう、ということで「HandlerSocketをインストールして、触ってみる」というテーマで書いてみようと思います。

2日目のxaicronさんとかぶってるけど、OS違うので許してください。

HandlerSocketとは?

恐れ多くて語れないので、DeNAのEngineer Blogからそのまま引用しちゃいます!

MySQLデータベースへのアクセスを高速化するためのプラグインです。MySQLSQLパーザをすっ飛ばし、ネットワーク通信とマルチスレッド処理周辺を置き換えることによって、InnoDB等のデータベースエンジンの性能を限界まで引き出します。

Slideはこちらから見れます!
http://www.slideshare.net/akirahiguchi/handlersocket-plugin-for-mysql-4664154


MySQL本体のインストール

今回は5.1系でやってみることにします。http://www.mysql.com/downloads/mysql/ から適切なRPMをダウンロードして、インストールすればokです。

# ls /usr/src/redhat/RPMS/i386/
MySQL-client-community-5.1.60-1.rhel5.i386.rpm  MySQL-server-community-5.1.60-1.rhel5.i386.rpm
MySQL-devel-community-5.1.60-1.rhel5.i386.rpm   MySQL-shared-community-5.1.60-1.rhel5.i386.rpm

# cd /usr/src/redhat/RPMS/i386
# rpm -ivh MySQL*.rpm

MySQLソースコード入手

HandlerSocketのインストールにはソースコードが必要なので、SRPMをインストールします。

# ls /usr/src/redhat/SRPMS/
MySQL-community-5.1.60-1.rhel5.src.rpm 

# cd /usr/src/redhat/SRPM
# rpm -ivh MySQL-community-5.1.60-1.rhel5.src.rpm

# cd /usr/src/redhat/SOURCES/
# tar zxvf mysql-5.1.60.tar.gz

これでHandlerSocket Pluginをインストールする準備ができました。

HandlerSocket Pluginのインストール

いよいよここからが本番です。まずはgitから最新版のソースをとってきます。

$ cd /tmp
$ git clone git://github.com/ahiguti/HandlerSocket-Plugin-for-MySQL.git


以降はhttps://github.com/ahiguti/HandlerSocket-Plugin-for-MySQL/blob/master/docs-ja/installation.ja.txtを参考にしてやっていけばいいのですが、その前にコンパイルに必要なライブラリを入れておきます。

# yum install libtool
# yum install gcc gcc-c++


さらっと書きましたが、実際はmakeできずにエラーログと何度もにらめっこしてました >_<
ボクみたいに、ミドルウェアやライブラリのインストールに慣れてない人はたぶんここが最もハマるところです。きちんとエラーログを見て、調べるのがいいと思います。


あとはconfigureしてmakeなわけですが....、--with-mysql-source、--with-mysql-bindir、--with-mysql-plugindirあたりのオプションが、ボクレベルのMySQL Casualユーザにはつらいところ。調べ方まで詳しく書いちゃいます。

with-mysql-source

MySQLソースコードのトップディレクトリを指定します。今回の例では/usr/src/redhat/SOURCES/mysql-5.1.60になります。

with-mysql-bindir

インストール済みのMySQLmysql_configコマンドが有るディレクトリを指定します。"which mysql_config"でokですね。

with-mysql-plugindir

MySQLのpluginディレクトリを指定します。以下のコマンドから調べることができます。

# rpm -ql MySQL-server-community-5.1.60-1.rhel5 | grep plugin

/usr/lib/mysql/plugin/ha_innodb_plugin.so
/usr/lib/mysql/plugin/ha_innodb_plugin.so.0
/usr/lib/mysql/plugin/ha_innodb_plugin.so.0.0.0


これで準備OKなので、コンパイルしてインストールします。

# cd /tmp/HandlerSocket-Plugin-for-MySQL
# ./configure --with-mysql-source=/usr/src/redhat/SOURCES/mysql-5.1.60 --with-mysql-bindir=/usr/bin --with-mysql-plugindir=/usr/lib/mysql/plugin
# make
# make install


これでHandlerSocketがpluginディレクトリにインストールされているはずです。確認してみましょう。

$ ls /usr/lib/mysql/plugin/handlersocket*
/usr/lib/mysql/plugin/handlersocket.a
/usr/lib/mysql/plugin/handlersocket.so
/usr/lib/mysql/plugin/handlersocket.so.0.0.0
/usr/lib/mysql/plugin/handlersocket.la
/usr/lib/mysql/plugin/handlersocket.so.0


ばっちりです!

HandlerSocketを有効にする

まずは/etc/my.cnfに以下の設定を記述します。インストールガイドそのままです。

[mysqld]
handlersocket_port = 9998
handlersocket_port_wr = 9999
handlersocket_address =
handlersocket_verbose = 0
handlersocket_timeout = 300
handlersocket_threads = 16
thread_concurrency = 128
open_files_limit = 65535


次にmysql_upgradeをしたんですが、この理由は...忘れました&よくわかってません。もしかしたら環境によっては不要かも...。

# mysql_upgrade -p root

そして、HandlerSocket Pluginを有効にします。mysqlに接続して以下のコマンドを打ちます。

install plugin handlersocket soname 'handlersocket.so';


どきどきしながら確認です。

mysql> show plugin;
+---------------+----------+----------------+------------------+---------+
| Name          | Status   | Type           | Library          | License |
+---------------+----------+----------------+------------------+---------+
| binlog        | ACTIVE   | STORAGE ENGINE | NULL             | GPL     |
| partition     | ACTIVE   | STORAGE ENGINE | NULL             | GPL     |
| ARCHIVE       | ACTIVE   | STORAGE ENGINE | NULL             | GPL     |
| BLACKHOLE     | ACTIVE   | STORAGE ENGINE | NULL             | GPL     |
| CSV           | ACTIVE   | STORAGE ENGINE | NULL             | GPL     |
| FEDERATED     | DISABLED | STORAGE ENGINE | NULL             | GPL     |
| MEMORY        | ACTIVE   | STORAGE ENGINE | NULL             | GPL     |
| InnoDB        | ACTIVE   | STORAGE ENGINE | NULL             | GPL     |
| MyISAM        | ACTIVE   | STORAGE ENGINE | NULL             | GPL     |
| MRG_MYISAM    | ACTIVE   | STORAGE ENGINE | NULL             | GPL     |
| handlersocket | ACTIVE   | DAEMON         | handlersocket.so | BSD     |
+---------------+----------+----------------+------------------+---------+

おおおおお、ばっちりですね!!

クライアントのインストール

Perlなら、デフォルトでついてくるNet::HandlerSocket or nekokakさんのNet::HandlerSocket::Simpleという選択肢があります@現時点。それぞれかんたんに(というかそのまま転記ですけど)紹介します。

Net::HandlerSocket
$ cd /tmp/HandlerSocket-Plugin-for-MySQL
$ ./autogen.sh
$ ./configure --disable-handlersocket-server
$ make
$ sudo make install
$ cd perl-Net-HandlerSocket
$ perl Makefile.PL
$ make
$ sudo make install
Net::HandlerSocket::Simple
$ cd /tmp/; git clone https://github.com/nekokak/p5-net-handlersocket-simple
$ cd p5-net-handlersocket-simple
$ perl Makefile.PL
$ make && make install

HandlerSocketを使ってみよう

まずはテーブルをつくる。スキーマはCasualなんでこんな感じ。

use test;

CREATE TABLE `user` (
  `id` int(11) unsigned NOT NULL,
  `name` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
;


では、insertを試してみましょう。

usestrict;
usewarnings;

useNet::HandlerSocket::Simple;

my$hs=Net::HandlerSocket::Simple->new(+{
    host=>'localhost',
    port=>9998,
    wo_host=>'localhost',
    wo_port=>9999,
});

for(1..10){
    $hs->insert('test.user',+{id=>$_,name=>"kotaroito$_"});
}

確認してみると...

mysql> select * from user;
+----+-------------+
| id | name        |
+----+-------------+
|  1 | kotaroito1  |
|  2 | kotaroito2  |
|  3 | kotaroito3  |
|  4 | kotaroito4  |
|  5 | kotaroito5  |
|  6 | kotaroito6  |
|  7 | kotaroito7  |
|  8 | kotaroito8  |
|  9 | kotaroito9  |
| 10 | kotaroito10 |
+----+-------------+
10 rows in set (0.00 sec)

おおおお、ばっちりです!

次にid=1の行をselectしてみます。

use strict;
use warnings;

use Data::Dump qw(dump);
use Net::HandlerSocket::Simple;

my $hs = Net::HandlerSocket::Simple->new(+{
    host    => 'localhost',
    port    => 9998,
    wo_host => 'localhost',
    wo_port => 9999,
});

print dump $hs->select('test.user', +{ fields => [qw/id name/], where => [1] });


[1, "kotaroito1"]

これもばっちりですね!

まとめ

HandlerSocket Pluginのインストール方法について、けっこう詳しく書いてみました。この記事を読んでHandlerSocketを試してみよう、と思った人がいれば幸いです。