mod_mrubyを使ってRaspberry Piを4台でWebサーバクラスタを組んでみた

そろそろRaspberry Piセットの日経BPムックが皆さんの所に届いていることでしょう。

僕も何台かRaspberry Piは持っていて、以前mod_mrubyをRaspberry Piで動かしてLチカしたりしていたのですが、今回はmod_mrubyRaspberry Piを4台使ってでクラスターを組んで見ました。

まずはラック作りから

まずは、Raspberry Piのラックを作りました。Raspberry Piのラックやケースをググると色々と出てくるのですが、なんとなく今回はそこら辺にあるものを使ってラックを作ってみました。Raspberry Piラックは以下の様になります。

2013-07-02 21.10.56

上から見ると、以下のような感じです。適当にニトリのキッチンラックを変な感じで組み立てました。

2013-07-02 21.14.32

買ったものとしては、

です。これらが意外と写真のようにきっちりとはまってくれて、SDカードや電源ケーブルも抜き挿ししやすくて、全体の大きさもコンパクトですし気に入っています。電源とアップリンクを挿せば、Raspberry Piが起動しだします。これだと机の横に飾りのように置いとくこともできますね。

あと、主電源とアップリンクのLANケーブルを外せば、そのままラックごと持ち運びもできて、色々な所で遊べますよ!

mod_mrubyとRaspberry Piでクラスター構築

OSはArch Linuxを使いました。imgをとってきて、ddで書き込んで、csshXで4台に接続してディスク領域をリサイズしたり、pacmanでパッケージ更新したり、githubからmod_mrubyを落としてきたりしました。

この辺りはググると沢山出てくると思うので、色々調べてやってみると楽しいと思います。

そして、mod_mrubyを入れた後は、Raspberry Piの1台をリバースプロキシ、3台をバックエンドとして以下のような設定を書きました。

今回はmod_mrubyを使って、リバースプロキシ上で外部の別のサーバで動いているRedisからバックエンドの情報をひっぱってきて、バランシングするような実装にしました。今回はRaspberry Piということでリソースが限られているので、スクリプトファイルをフックするのではなく、直接httpd.confにコードを書く昨日を使いました。

リバースプロキシのmod_mrubyのhttpd.confの設定

[program lang=’apache’ escaped=’true’]

#
# inline proxy with redis
#
#
mrubyTranslateNameFirstCode '                                         ¥
proxynum = 3;                                                         ¥
                                                                      ¥
redis      = Redis.new "192.168.12.251", 6379;                        ¥
r          = Apache::Request.new;                                     ¥
r.handler  = "proxy-server";                                          ¥
r.proxyreq = Apache::PROXYREQ_REVERSE;                                ¥
r.filename = "proxy:#{redis.get (rand(proxynum) + 1).to_s}" + r.uri;  ¥
                                                                      ¥
redis.close;                                                          ¥
                                                                      ¥
Apache::return Apache::OK;                                            ¥
'

[/program]

簡単のため、redisには、keyを数値(1とか2とか)にして、keyが1だとバックエンド1、keyが2だとバックエンド2・・・というようなデータの入れ方をしました。例えば以下です。

[program lang=’bash’ escaped=’true’]

$ redis-cli get 1
"http://192.168.12.7/"

$ redis-cli get 2
"http://192.168.12.12/"

[/program]

それにより、上記のrandメソッドによってproxynumで指定した数以下の値がランダムに得られるので、そこからランダムにバックエンドのURLをとれるようにしています。

バックエンドのhttpd.confの設定

バックエンドでも、静的ファイルを見に行くより、mod_mruby経由で文字列を表示させたほうが高速な前の記事で分かっていたので、こちらも同様httpd.confにコードを直接書きました。これによって、コンテンツのファイルをopen()させないようします。以下のような設定をしました。

[program lang=’apache’ escaped=’true’]

<Location /mruby>
  sethandler mruby-native-script
  mrubyhandlercode    "Apache.rputs 'mruby 1'; Apache.return Apache::HTTP_OK;"
</Location>

[/program]

バックエンドにキチンと振り分けられているかわかるように、バックエンドのRaspberry Piはredisのkeyが1なRaspberry Piだったら「mruby 1」、keyが2なRaspberry Piは「mruby 2」・・・とレスポンスを返すようにしました。

試してみた

実際にアクセスしてみると、以下のようになりました。

スクリーンショット 2013-07-03 18.11.21

わーい、ちゃんとプロキシできていますね!

最後に

今回はRaspberry Piを贅沢に使って、Webサーバクラスタを作って遊んでみました。今後は、GPIOを使って色々外部のデバイスを弄ってみたいと思います。