ども、cloudpack の かっぱ (@inokara) です。
はじめに
複数の memcached を分散アクセスさせるためのソリューションとして twemproxy 以外のソリューションを探していたところ、mcrouter という Facebook 謹製のツールがあるようなので試してみました。
参考
- mcrouter
- Introducing mcrouter: A memcached protocol router for scaling memcached deployments
- mcrouterでElastiCache(memcached)を分散レプリケーションする
- mcrouterのインストール手順
当初は CentOS 6.5 でセットアップを進めていましたが、folly というライブラリのインストールで m4 マクロのエラーからビルドが通らずに詰んでしまいました…改めてチャレンジできればと考えています。
mcrouter のウンチク、セットアップと動作確認
mcrouter のウンチク
mcrouter は上述の通り Facebook 謹製の memcached プロトコルをスケールさせる機能を持ったミドルウェアで以下のような機能があります。(主な機能を抜粋)
- ASCII protocol(memcached プロトコルサポート)
- Connection Pool
- Multiple hashing schemes
- Prefix routing
- Replicated pools
をはじめヘルスチェックやフェイルオーバー、SSL のサポートなどの機能があります。詳しくはこちら「Features · facebook/mcrouter Wiki」やこちら「Home ·facebook/mcrouter Wiki」を御覧ください。
今回は Replicated pools を中心に触っていきたいと思います。
mcrouter のセットアップ
mcrouter には Ubuntu 環境にセットアップできるスクリプトが標準で添付されます。対象は 14.04 ということで Ubuntu 14.04 を Dockerコンテナで用意しておきます。
docker run -t -i ubuntu /bin/bash root@e75ada9a6323:~/mcrouter/mcrouter/scripts# cat /etc/lsb-release DISTRIB_ID=Ubuntu DISTRIB_RELEASE=14.04 DISTRIB_CODENAME=trusty DISTRIB_DESCRIPTION="Ubuntu 14.04.1 LTS" root@e75ada9a6323:~/mcrouter/mcrouter/scripts#
git パッケージをインストールします。
apt-get -y install git
mcrouter を git clone してきます。
git clone https://github.com/facebook/mcrouter.git
セットアップスクリプトを実行します
cd mcrouter/mcrouter/scripts ./install_ubuntu_14.04.sh /opt/mcrouter
しばし待ちましょう。
セットアップが終了したらヘルプやバージョンをちょろっと見てみます。
root@e75ada9a6323:~/mcrouter/mcrouter/scripts# /opt/mcrouter/install/bin/mcrouter --version mcrouter 1.0 root@e75ada9a6323:~/mcrouter/mcrouter/scripts# root@e75ada9a6323:~/mcrouter/mcrouter/scripts# /opt/mcrouter/install/bin/mcrouter --help mcrouter 1.0 usage: /opt/mcrouter/install/bin/mcrouter [options] -p port(s) -f config libmcrouter options: (略)
memcached のセットアップと起動
セットアップといっても大したことはしません…。CentOS 6.5 のコンテナに yum で memcached をインストールして以下のようなスクリプトを置くだけです。
#!/bin/sh /usr/bin/memcached -p 11211 -u memcached -m 64 -c 1024 -P /var/run/memcached/memcached.pid
memcached の -d
オプションにしばらく気付かずにコンテナが exit0 してしばらく悩みました。すいません。
上記で作成したコンテナを以下のように起動します。
docker run -d -i -p 11211 memcached /root/start.sh
このコマンドを二回実行して二つの memcached コンテナを起動しておきます。
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 6d36454a6a31 memcached:latest "/root/start.sh" 22 minutes ago Up 22 minutes 0.0.0.0:49164->11211/tcp romantic_fermi d7681376831a memcached:latest "/root/start.sh" 24 minutes ago Up 24 minutes 0.0.0.0:49163->11211/tcp reverent_bartik e75ada9a6323 ubuntu:latest "/bin/bash" About an hour ago Up About an hour prickly_curie
mcrouter の設定と起動
mcrouter の設定ファイルは JSON 形式をサポートしており、C++ のコメントアウトや JSONM というマクロもサポートしています。詳しくはドキュメントを御覧ください。
今回は Replication Pool の設定を以下のように行いました。
{ "pools": { "A": { "servers": [ // hosts of replicated pool, e.g.: "xxx.xxx.0.24:11211", "xxx.xxx.0.25:11211" ] } }, "route": { "type": "PrefixPolicyRoute", "operation_policies": { "delete": "AllSyncRoute|Pool|A", "add": "AllSyncRoute|Pool|A", "get": "LatestRoute|Pool|A", "set": "AllSyncRoute|Pool|A" } } }
ざっくり…
pools
でクラスタに所属するホストを設定route
で各メソッドごとの挙動を指定しています(上記の例では get は特定のノードから、それ以外は全てのノードに対して処理を行う指定です)
となります。
早速、mcrouter を起動してみます。
cd /opt/mcrouter/install/bin ./mcrouter -p 1919 -f /opt/mcrouter/conf/config.json
-f
で設定ファイルを指定、-p
で待機するポートを指定して起動すると…
以下のように出力されました。
root@e75ada9a6323:/opt/mcrouter/install/bin# ./mcrouter -p 1919 -f /opt/mcrouter/conf/config.json I1214 15:43:10.932909 6245 main.cpp:521] ./mcrouter -p 1919 -f /opt/mcrouter/conf/config.json I1214 15:43:10.933058 6245 main.cpp:638] mcrouter 1.0 startup (6245) W1214 15:43:10.933117 6245 router.cpp:505] Error while checking spooldir (/var/spool/mcrouter): No such file or directory [2] I1214 15:43:10.946666 6245 proxy.cpp:757] reconfigured 1 proxies with 2 clients and 1 pools (3c34b92c9496f2832622459f6d4a75d4) I1214 15:43:10.948510 6245 server.cpp:143] Spawning AsyncMcServer
ありゃ、どうやら spooldir
の設定が必要なようですので作成します。
mkdir /var/spool/mcrouter
気を取り直して起動しましょう。
root@e75ada9a6323:/opt/mcrouter/install/bin# ./mcrouter -p 1919 -f /opt/mcrouter/conf/config.json & [1] 6271 root@e75ada9a6323:/opt/mcrouter/install/bin# I1214 15:45:59.649950 6271 main.cpp:521] ./mcrouter -p 1919 -f /opt/mcrouter/conf/config.json I1214 15:45:59.650058 6271 main.cpp:638] mcrouter 1.0 startup (6271) I1214 15:45:59.673478 6271 proxy.cpp:757] reconfigured 1 proxies with 2 clients and 1 pools (3c34b92c9496f2832622459f6d4a75d4) I1214 15:45:59.674856 6271 server.cpp:143] Spawning AsyncMcServer
今度はちゃんと起動したようです。
動作確認
SET
以下のように mcrouter に対してデータを SET してみます。
root@e75ada9a6323:/opt/mcrouter/install/bin# telnet localhost 1919 Trying ::1... Connected to localhost. Escape character is '^]'. set foo 0 100 4 hoge I1214 16:04:54.596242 6277 ProxyDestination.cpp:223] server xxx.xxx.0.24:11211:TCP:ascii-1-0 up (1 of 2) I1214 16:04:54.596276 6277 ProxyDestination.cpp:223] server xxx.xxx.0.25:11211:TCP:ascii-1-0 up (2 of 2) STORED
上記のようにデータが格納されました。
GET
上記でセットしたデータを取得してみます。
root@e75ada9a6323:/opt/mcrouter/install/bin# echo -ne "get foorn" | nc 127.0.0.1 1919 VALUE foo 0 4 hoge END
当たり前ですがデータの取得ができています。
node に障害
試しに一台の memcached ノードを停止してみると…以下のように mcrouter からログが出力されます。
root@e75ada9a6323:/opt/mcrouter/install/bin# I1214 16:10:39.149531 6277 ProxyDestination.cpp:241] server xxx.xxx.0.25:11211:TCP:ascii-1-0 down (0 of 2)
この状態からデータの取得を行うと以下のようにデータを取得することが出来ました。
root@e75ada9a6323:/opt/mcrouter/install/bin# echo -ne "get foorn" | nc 127.0.0.1 1919I1214 16:16:13.724607 6338 ProxyDestination.cpp:241] server xxx.xxx.0.24:11211:TCP:ascii-1-0 down (1 of 2) VALUE foo 0 4 hoge END
ちゃんとデータの同期が行われてるようです。
とりあえず…
今日はここまで。
ひとまず mcrouter をセットアップしてデータの登録と同期が行われているところまでは確認することが出来ました。
正直、CentOS でセットアップ出来ていないのがちょっと残念だったりしますが、引き続き mcrouter の動作についてドキュメントを読み進めながら整理していけたらなと思います。
上記の通り、セットアップできる環境が限られてしまいますが、従来から memcached にどうやって冗長性や可用性を持たせるかの解決策の一つとして参考にしたいと思います。また、mcrouter 自体が SPOF になってしまうのをどのように解決するか(mcrouter で巻き取れるのか他のミドルに頼るのか)についても引き続き追っていければと考えています。
おやすみなさい。
元記事はこちらです。
「mcrouter で memcached へのアクセスを分散とレプリケーション Docker でちょろっと試す」