OutOfMemory でスレッドの起動に失敗する件

十分なメモリを割り当てているにもかかわらず Hadoop や Thrift ゲートウェイで OutOfMemoryError が発生しスレッド生成に失敗する事案。

2012-01-18 19:54:16,620 ERROR org.apache.hadoop.hdfs.server.datanode.DataNode: DatanodeRegistration(192.168.121.93:50010, storageID=DS-1008921043-xxx.xxx.xxx.xxx-xxxxxx-xxxxxxxxxxxxxxx, infoPort=50075, ipcPort=50020):DataXceiverServer: Exiting due to:java.lang.OutOfMemoryError: unable to create new native thread
        at java.lang.Thread.start0(Native Method)
        at java.lang.Thread.start(Thread.java:640)
        at org.apache.hadoop.hdfs.server.datanode.DataXceiverServer.run(DataXceiverServer.java:131)
        at java.lang.Thread.run(Thread.java:662)

2012-01-18 19:54:16,620 INFO org.apache.hadoop.hdfs.server.datanode.DataNode: PacketResponder 0 for block blk_5441514272352034349_78759 terminating
2012-01-18 19:54:16,620 INFO org.apache.hadoop.hdfs.server.datanode.DataNode: Exiting DataXceiverServer
2012-01-18 19:54:16,623 INFO org.apache.hadoop.hdfs.server.datanode.DataNode: PacketResponder 0 for block blk_4867391491560614348_78761 terminating
2012-01-18 19:54:16,624 INFO org.apache.hadoop.hdfs.server.datanode.DataNode: Deleted block blk_6316283104492897854_78701 at file /var/lib/hadoop/dfs/data/sdb1/current/blk_6316283104492897854
…

GC 時に出力される空きメモリ量は余裕があるし、OS に割り当てているメモリ量も該当 Java VM のネイティブ使用量コミで十分収まる見積もりなのに何故? と悩んでいましたが、単に ulimit で設定している起動プロセス数の上限に達したというオチでした。まぁ HadoopJava VM に限った話ではなかったですが。

torao@clove$ ulimit -a
…
max user processes              (-u) 1024

Hadoop のデータノードで起きると自動的にシャットダウンしようとして七転八倒するし、Thrift でも通信不能の接続が残ってしまってプロセス再起動が必要と後始末が大変。