Quantcast
Channel: プログラミング
Viewing all articles
Browse latest Browse all 8171

Solid Cache から派生してセッション管理の話 - hidekatsu-izuno 日々の記録

$
0
0

Rails方面で 37signalsが開発した Solid Cacheの話が出ていて、読んだらなかなか興味深い話だったのでいろいろ調べていた。

  • キャッシュには通常 Redis や Memcache のような高速なメモリストアが使われる
  • とはいえ、メモリは高価だし、実際調べてみるとキャッシュの入出力にかかる時間は全体の処理時間のほんの少しに過ぎず、RDBでも十分
  • むしろ、キャッシュが長期間保存できるようになってより効率的になった
  • Solid Cache では LRU ではなく FIFOなので読み取りアクセスの記録が不要でパフォーマンスも悪くないよ

ということのようだ。

当初はセッション・ストアに RDBを使う話かと勘違いしていたのだけど、これはあくまでキャッシュ・ストア限定の話で残念ながらセッション・ストアには使えない。セッション・ストアに使うには読み取りアクセスの記録が不可欠(最後にアクセスした時間から n 分間有効)だから、高速な書き込みが必要でそう考えるとメモリストアがどうしても必要になる。残念。

 

Web系システムを商用向けに実際に組んだことのある人はわかると思うけれど、Redis をクラスタ構成にするには最低3台(マスタースレーブ構成でも2台)が必要となる。DBに同居させるならともかく、AWSだとDBはRDSを使うのが一般的だから、セッションを管理するためだけのために Elasticache 2台をさらに追加することになる。なかなかに豪華な構成だ。

構成が増えるとシステムとしても複雑になるからできることならば RDBだけでなんとかしたいというのが本音だったりする。現実問題、ユーザー数が少なければ RDBにセッション情報を格納しても問題ない気がするけども。

 

セッション管理はメモリストアで行うのがベストプラクティスではあるけれど、一時期 JWT を使うのが流行していた。

あくまで個人的な設計指針だが、セッションに紐づける情報はユーザーIDだけにしてその他の情報はDB上のデータをキャッシュして取得するようにしている。様々な情報をセッションに持つのは便利ではあるが、設計変更がしにくくいし、ユーザー情報取得時に合わせて権限チェックもできる。

たかだかユーザーIDしか持たないのであれば JWT に格納して Cookieに置いた方がスケールしやすいし一見優れていように思えるのだが、これが意外に厄介だったりする。

まず、サーバー側でセッションを無効化できないし、現在誰がログイン中なのかログを集計しない限り見ることもできない。セッションの有効期間を延ばすためには Refresh token を発行する必要があるが、画像や画面遷移などAjaxを介さないアクセスとの相性が悪い。さらに暗号キーが漏れた場合、セッションを個別に無効にするということはできず、全セッションを無効にせざるを得ない。

現実的には、旧来のセッション管理の仕組みの方が簡潔かつ安全であるし、日本を代表するようなシステム規模でも Redis でセッション管理をしているわけだから、様々な困難を乗り越えてまで JWT でセッション管理を行う必要はないという認識をしている。

 

このように考えていくと、小規模なうちは RDBでセッション管理しサービスが軌道に乗った段階で Redis に切り替えていくでもいいようには思う。個人的には、RDBにもInnoDB memcached Pluginのように高速処理できる仕組みがあっても良いと思うのだけど、このプラグイン自体も廃止される方向だし、PostgreSQLにはそもそもない(もしかすると hstore plugin がその役割を果たすのかもしれないけれど調べた限り、速いとかそういうものではないようだ)。

 

【追記】いまいち信頼性にかけるが、Redis と PostgreSQL では書き込みでせいぜい2倍になる程度で思ったほど差がないようだ。


Viewing all articles
Browse latest Browse all 8171

Trending Articles