/dev/null

(◞‸◟)

MongoDB + JavaでToo Many Open Files が出た場合の対処

この前ギョームでMongoDBがやたら落ちていた。

そのMongoはJavaからInsertなりUpdateが走っている。

エラーログをゴリゴリ読んでると

ERROR: connect invalid socket errno:24 Too many open files

で落ちてる。

MongoDB公式のオススメ設定!!なのを見ると

http://docs.mongodb.org/manual/reference/ulimit/

そもそも明示的にしない場合はOSのulimit値に依存するらしい。

で、もしOSの値と違う設定値を使いたいならば個別に指定する必要がありそれのオススメが

mongod and mongos deployments:

-f (file size): unlimited -t (cpu time): unlimited -v (virtual memory): unlimited [1] -n (open files): 64000 -m (memory size): unlimited [1] -u (processes/threads): 32000

ってな感じ。

落ちる環境のを見ると、OSのulimit値が1024だった。まぁ落ちやすそう。

しかし、とりあえずJavaのコード側から見なおそう運動

具体的なコードはまぁギョーム内なので見せられないけど、insertなりupdateする際に毎度MongoClientインスタンスを生成してcloseもしてない感じ。

これ嫌な予感するね?

ってことで調べる。

MongoClient

http://api.mongodb.org/java/current/com/mongodb/MongoClient.html

A MongoDB client with internal connection pooling. For most applications, you should have one MongoClient instance for the entire JVM.

_人人人人人人人人人人人人人人_

> one MongoClient instance <

 ̄YYYYYYYYYYYYY

ってなわけで一々MongoClientクラスを生成するのではなく、シングルトンとして保持するように変えたら死ななくなりました。

ここにも載っておりました

http://stackoverflow.com/questions/5043277/mongo-java-too-many-open-files

フレームワークによっては簡単にシングルトン実装出来るのもありますね

InstanceType.SINGLETON とかね。

フレームワーク的にできなさそうとかでも実装は簡単。

コンストラクタをprivateにしちまえってやつ。で、インスタンスはstaticメソッドで取得っと。

ただ最近はEnumでシングルトン実装するのが簡単かつオシャレと評判(EffectiveJava参照

なんにせよ、MongoClientクラス、Mongoクラスのインスタンスは一つだけにしよう!!!