本日も乙

ただの自己満足な備忘録。

repcachedをインストールして、memcachedをレプリケーションしてみる

複数台の構成の場合、WEBサーバ、データベースサーバ、キャッシュサーバと、役割別にサーバを建てることが一般的です。 役割を簡単に説明すると、下記の通りになります。

  • WEBサーバ(Apache, nginxなど)
    • ブラウザからアクセスしたときにページ表示させます
  • データベースサーバ(MySQLなど)
    • データベース
  • キャッシュサーバ(memcachedなど)
    • セッションやデータを格納するのに使います
    • キャッシュサーバにセッションを格納し、複数WEBサーバから参照できることによってユーザのセッションを維持することができます

しかし、サーバ購入や運用のコスト面などの理由により、1台のサーバに複数の役割を持たせることもあります。例えば、下記の図のように1台(サーバA)にWEBサーバとデータベースとCacheを同居させて、もう一台(サーバB)にはWEBサーバを建てて、DBとCacheを2台で共有して使う構成です。

サーバ構成図1

管理するサーバが2台で済むので楽ですが、サーバAがダウンした場合、データベースとキャッシュが使えなくなるため、システム(Webサービス)全体がダウンしてしまいます。 そのため、データベースの場合は、お互いが同期を取れる(レプリケーション)ようにすることが多いです。キャッシュもレプリケーションによってデータを同期を取れるようにできれば冗長化が図れます(下記の図を参照)。

サーバ構成図1

そこで、memcachedレプリケーションできる「repcached」を紹介し、インストール・設定できるようにします。

repcachedとは

repcachedはKLabが開発したmemcachedレプリケーション機能をつけたものです。 レプリケーション機能がついただけで基本的な機能や使い方はmemcachedと同様です。基本的にレプリケーションできるのは2台までです。3台レプリケーションできたという記事もありましたが未検証です。

repcachedのインストール

レプリケーションなので、2台(上記図のサーバA、サーバB)にインストール・設定します。

OS、バージョンなど

  • CentOS 6.4
  • repcached 2.2.1
  • memcached 1.2.8 (repcachedと一緒にインストールされます)

必要なパッケージのインストール

$ sudo yum install libevent-devel

ダウンロード・コンパイル

$ wget http://sourceforge.net/projects/repcached/files/repcached/2.2.1-1.2.8/memcached-1.2.8-repcached-2.2.1.tar.gz
$ tar zxvf memcached-1.2.8-repcached-2.2.1.tar.gz
$ cd memcached-1.2.8-repcached-2.2.1
$ ./configure --enable-replication
$ sudo make

ここで、

[plain] memcached.c:697:30: error: ‘IOV_MAX’ undeclared (first use in this function) [/plain]

というコンパイルエラーが出たので、memcached.c を修正します。

/* FreeBSD 4.x doesn't have IOV_MAX exposed. */
#ifndef IOV_MAX
#if defined(__FreeBSD__) || defined(__APPLE__)
# define IOV_MAX 1024
#endif
#endif

/* ここを追加 */
#define IOV_MAX 1024

もう一度makeする。

$ sudo make
$ sudo make install

インストールできたかの確認

$ memcached -h
memcached 1.2.8
repcached 2.2.1
-p <num>      TCP port number to listen on (default: 11211)
-U <num>      UDP port number to listen on (default: 11211, 0 is off)
-s <file>     unix socket path to listen on (disables network support)
-a <mask>     access mask for unix socket, in octal (default 0700)
-l <ip_addr>  interface to listen on, default is INDRR_ANY
-d            run as a daemon
-r            maximize core file limit
-u <username> assume identity of <username> (only when run as root)
-m <num>      max memory to use for items in megabytes, default is 64 MB
-M            return error on memory exhausted (rather than removing items)
-c <num>      max simultaneous connections, default is 1024
-k            lock down all paged memory.  Note that there is a
              limit on how much memory you may lock.  Trying to
              allocate more than that would fail, so be sure you
              set the limit correctly for the user you started
              the daemon with (not for -u <username> user;
              under sh this is done with 'ulimit -S -l NUM_KB').
-v            verbose (print errors/warnings while in event loop)
-vv           very verbose (also print client commands/reponses)
-h            print this help and exit
-i            print memcached and libevent license
-P <file>     save PID in <file>, only used with -d option
-f <factor>   chunk size growth factor, default 1.25
-n <bytes>    minimum space allocated for key+value+flags, default 48
-R            Maximum number of requests per event
              limits the number of requests process for a given con nection
              to prevent starvation.  default 20
-b            Set the backlog queue limit (default 1024)
-x <ip_addr>  hostname or IP address of peer repcached
-X <num:num>  TCP port number for replication. <listen:connect> (default: 11212)

-x, -Xオプション以外はmemcachedと同じです。

設定

ポートを空ける

memcachedのポート番号はデフォルトで11211だが、レプリケーションするために必要なポート番号がデフォルトで11212なので、レプリケーション対象に対して11212を開けておく必要があります。

例えば、上記図のサーバAのIPアドレスが10.0.0.1, サーバBのIPアドレスが10.0.0.2の場合にiptablesを下記のように設定します。

サーバA

# /etc/sysconfig/iptables

...(省略)

# 追加
-A INPUT -m state --state NEW -m tcp -p tcp -s 10.0.0.2 --dport 11212 -j ACCEPT

...(省略)

サーバB

# /etc/sysconfig/iptables

...(省略)

# 追加
-A INPUT -m state --state NEW -m tcp -p tcp -s 10.0.0.1 --dport 11212 -j ACCEPT

...(省略)

memcachedユーザ追加

repcached(memcached)を動かすmemcachedユーザを追加します。

$ sudo useradd -M -s /sbin/nologin memcached

-M オプションでユーザ追加時に、ホームディレクトリ(/home/memcached)が作成されません。 -s オプションでユーザのログインシェルを指定しています。memcachedユーザはログインする必要が無いので、/sbin/nologin を指定しています。

起動スクリプト

こちらのサイトから拝借しました。

設定ファイル

基本的にはmemcachedと同様で、REPHOSTが追加されただけです。

# /etc/sysconfig/repcached

PORT="11211" 
USER="memcached" 
MAXCONN="1024" 
CACHESIZE="1024" 
OPTIONS="" 
REPHOST="レプリケーション先のIPアドレス" 

自動起動設定

$ sudo chkconfig add repcached
$ sudo chkconfig repcached on

起動

$ sudo service repcached start
Starting repcached(memcached):                             [  OK  ]

$ ps aux | grep memcached
220       5660  0.0  0.0  13524   872 ?        Ss   15:24   0:00 /usr/local/bin/memcached -d -x 10.0.0.1 -p 11211 -u memcached -m 1024 -c 1024 -P /var/run/memcached/repcached.pid
root      5663  0.0  0.0 103420   840 pts/0    S+   15:24   0:00 grep memcached

-x オプションでレプリケーション先サーバのIPアドレスが設定されていることを確認します。

レプリケーションされたかの確認

2台ともrepcachedをインストールしていることが前提になります。

サーバAにSSHログインして、localhostにポート11211(memcached)でtelnet接続します。

$ telnet localhost 11211

データを格納します。

> set hello 0 0 8
hogehoge

# 格納されたか確認する
> get hello
hogehoge

サーバBも同様にSSHログインして、localhostにポート11211(memcached)でtelnet接続し、先ほどのデータが格納されたか確認します。

> get hello
hogehoge

先ほどのデータが表示されれば、レプリケーションされていることになります。 もし、表示されなければどこかで設定が間違っている可能性があります。 ポートの開け忘れがよくあるのでiptablesの設定を確認してください。

最後に

repcachedをインストールして、データをレプリケーションしてみました。 memcachedにセッションを格納することで、ユーザのログイン状態を保持することができます。 今後、PHPでセッションをmemcachedに格納する設定も紹介できればと思います。

参考URL