Webサーバのクラスタリングとセッション、変数の永続化

PHPやRailsで提供されているセッションの機能は、セッションでの値の保存として、セッションIDをキーにして、hash table (key:value pair の変数) をサーバ内のファイルシステムに保存するという具合になっている。 この条件で、ある問題に遭遇した。


多くのHTTPリクエストに応えられるように複数台のWebサーバを導入してクラスタを組む場合、サーバ内のディスクにセッションでの値が保存されるため、クラスタ内の別のノード(サーバ)で書かれた値を取得することができない。 セッションを書く場所を NFS で共有するようにしたとしても、セッションの保存場所が一か所になり、一台のマシンに読み書きの処理が集中するかたちとなってしまうため、スケーラビリティに限界があったり、一台のマシンが故障すると全体に波及するというアベイラビリティの問題になる。 同様にセッション保存場所にMySQLを置いても同様だ。 分散DBが使えるってことならば、それでもよいのだが、今回はそっち方面で攻めない。 できればサーバ内のファイルシステムにセッション情報を書き込むのをやめる方法をとりたい。


Webアプリでのセッションってそもそも何者か、って考えたところ、「途切れとぎれ (stateless) にリクエストを送ってるHTTPにおいて、前の HTTP リクエスト・レスポンスで使われたプログラム中の変数を永続化 (persistent) すること」なんじゃないかって思ったのです。 なんだ、永続化か、ってことで。


プログラム中の変数の永続化ならば、Dumperを使えばいいんじゃない。 ってことで、Perl ならば Data::Dumper
、PHPなら var_dump、Ruby ならば Marshal なんかが使えそうです。 これらだと、各々のプログラム言語に依存しているので、JSONやXMLを使ってプログラム言語非依存にしてもいいかもしれないですね。


あとセッションの保存としての要件には、クライアントにも第三者にも見られたくない内容があったり、改変されたり偽造されたりしては困る場合もあるだろう。 そんなことで、上述の dump されたデータをIDEAやAESなどの共通鍵暗号して base64 なんかしちゃえばいいのかも。 途中でデータ圧縮で lzo なんか使ったりしてもいいし、 base64 ってそのままだと URL encode しなければならないので、base64 の map を変更してみてもいいかもしれないし。


あとはこれらの値をどこに保存するか。 HTTPとして真っ先に思いつくのが Cookie。 または POST などするフォーム中にセッションの値を入れてもいいかもね。 携帯だとCookie使えないとかページ容量の制約などがあるので、この方法だとダメっぽそうですが。


ってことで、こんなことをやるライブラリを作ってみようかどうしようか考え中。 どの言語のものを先に作るかとか考え中。 ってことでリクエストありましたら、つっこみどうぞ。

コメント

このブログの人気の投稿

大型特殊自動車免許を取った時の話。

パスワードを覚えるのも無理があるから、パスワードマネージャ使いましょう。

車両系建設機械運転者(整地) の講習