山下寛人オフィシャルブログ

オイシックス株式会社 執行役員 システム本部長 山下寛人の公式ブログです。

JavaでMemcachedを使う意味

今までJavaではMemcachedいらない派でしたがやっぱりいろいろメリットが見えてきたので使う価値があるかもと思えてきました。PHPだとキャッシュの仕組みが作りづらいので(多分)必要性が明確でした。Javaだとstatic変数にHashMapを使えば簡単にできるのでわざわざmemcachedを別に動かして使い方を覚えてまでする必要性が感じられませんでした。

一つは排他制御です。HashMapはスレッドセーフではありません。絶妙なタイミングで同時に1つのインスタンス複数スレッドでアクセスすると無限ループになることがあったりします。そうするとsynchronizeしたりして排他制御をする必要がありますがこれが意外にちゃんと実装するには結構なスキルが必要です。ロックのかけかたによっては全く排他制御になっていないこともありますし、逆にロックの粒度が大きくてデッドロックを引き起こしたりなどします。ConcurrentHashMapなんかもありますが挙動をよく理解して使わないとやっぱりトラブルを引き起こしそうです。

それからメモリの使いすぎの制御が必要です。何も考えずにキャッシュをためこむとメモリを食い過ぎる可能性があります。一定時間で破棄したり一定容量で破棄したりといったロジックを作りこまないといけません。メモリが足りなくなってきたら破棄するようSoftReferenceにしておくなどしたほうがよいです。そういう作り込みをやっていくと結構工数がかかってきます。

そしてクラスタ構成にしたときのメモリ効率です。JVMはメモリがたくさんあればあるほどいいかというとそうではありません。ガベージコレクションにかかるコストが指数関数的に増えていくので全体パフォーマンスが落ちてしまいます。そのため1個のJVMを大きくしていくよりJVMをたくさん立ち上げてクラスタ構成にすることになります。そうするとJVMごとにキャッシュを持つとメモリが無駄遣いになります。memcachedを別にして共有すると効率的です。

小規模なシステムやスタンドアロンのソフトならいいですが大規模なサーバーシステムだとmemcachedを使うメリットがありそうです。