JMongoStore - a Store class to persistent sessions of Tomcat to MongoDB.

永続化するオブジェクトグラフの構成がある程度固いようであれば、ORMを使ってRDBMSに保存するというアプローチで良いと思いますが、グラフの構成が変動しやすい場合は、変更の都度スキーマ定義を更新することになるので結構面倒です。例えばHTTPSessionのように、アプリケーションのバージョンアップと共に保存される情報が変動していきやすいものは、スキーマレスなKVSの方が扱いやすいと言えるでしょう。
そこで、MongoDBにTomcatのセッション情報を保存するモジュールを書いてみました。JMongoStoreという名前でgithubにアップしています。使い方は以下のとおりです。

1. ${CATALINA_HOME}/libに、mongo-store.jar and mongo-java-driver.jar(MongoDB標準のJavaドライバ)をコピーする
2. Tomcatの任意のContextにPersistentManagerとJMongoStoreの設定をする

<Context antiResourceLocking="false" privileged="true" useHttpOnly="true">
  <Manager className="org.apache.catalina.session.PersistentManager" 
    saveOnRestart=".." 
    maxActiveSessions=".." 
    minIdleSwap=".." 
    maxIdleSwap=".." 
    maxIdleBackup=".."
  >
    <Store className="net.wrap_trap.tomcat.session.MongoStore"
        host="localhost"
        databaseName="session_store"
        collectionName="sessions"
    />
  </Manager> 
</Context>

3. Tomcat起動
4. Sessions Example(http://localhost:8080/examples/servlets/servlet/SessionExample)より、セッション情報を格納
5. mongoシェルを起動し、sessionsコレクションにセッション情報が保存されることを確認する

  • mongoシェルによる実行の結果

JDBCStore等は一旦オブジェクトをJava SerializeしてそのバイナリをDBにそのまま保存しますが、JMongoStoreではセッションのattributesもBSONで格納され、mongoシェルを通じてどんなオブジェクトがどんな値で格納されているか確認することができます。また、MongoDBにはMapReduceの実装が組み込まれているので、例えば何かのアイテムを参照した際にセッションにその情報を格納しておき、後でmap/reduceを使って集計したり、その集計結果を使って効果の高いアイテムをレコメンドする等の使い方があると考えています。ただし、deactiveなセッション情報を集計する為に、MongoDB上のセッション情報はすぐに削除せず、一定期間保持するなどの調整が必要になるでしょう。

セッション情報をMongoDBに保存する部分で、以前使ってみたMungBeanかMorphiaを使おうと考えたのですが、色々と合わない箇所が出てきたので、結局自前で書きました。(BSONをMongoDBに格納する部分はMongoDB標準のJavaドライバに任せています。) この部分はいずれ分離させ、別のモジュールとして管理したいと考えています。