たごもりすメモ

コードとかその他の話とか。

Hadoopクラスタでulimitを設定するときの注意点

Hadoopクラスタを運用する際に ulimit で nofile (プロセスがopenできるファイルディスクリプタ数の上限)の設定を変更しておくべき*1というのはもはや常識的なお話ですが、そこには実は罠がある。たぶんRHELのデフォルト通りならハマらないんだろうけど、手を入れている環境だとハマる。ので、その話。

要するにハマった。のを解決したよ多分! まだ最終的な確認できてないけど!

各書籍での解説

とりあえず、国内で売られているHadoop関連書籍の記述を確認しておこう。まずHadoop徹底入門。

ファイディスクリプタの設定は、/etc/security/limits.conf に記述します。エディタを利用して、limits.conf に以下のように記述します。ここでは、Hadoopの各種ノードを起動するユーザーを hadoop とします[12]。

hadoop soft nofile 32768
hadoop hard nofile 32768

limits.confには、ソフトリミットとハードリミットの両方を記述します。この設定は、Hadoopのノードを起動するすべてのサーバーで設定します。異常の設定を終えたのち、全サーバーをOSごと再起動してください[13]。

※[13] limits.conf 自体は、設定を追加したユーザーにて再ログインすることで有効になります。

Hadoop徹底入門 10.3.2 OSチューニング「ファイルディスクリプタ設定」p368

ふむ。で、Hadoop Hacks。

Hadoop や HBase を使用すると、1つのJavaプロセスから大量のファイル/ソケットを作成するケースがあります。そのため、最大ファイルディスクリプタ数を引き上げておく必要があります(デフォルトは1024)。/etc/security/limits.conf に以下の記述を追加してください。

(設定例は省略)

記述の追加後一旦ログアウトします。再度ログインした後、ulimitコマンドで正しく設定が行われている事を確認し、Hadoopを再起動します。

Hadoop Hacks 「HACK #2 Hadoop用ノードのLinux OS設定」p5

こんな感じでした。んー。結論から言うと、記述として不十分ですね。

ssh経由 ulimitの話

普通に /etc/security/limits.conf を更新してログインし直すと適用される、というのは正確ではない。SSH経由でログインするユーザの場合は sshd 側で制限をかけるケースがある。セキュリティを保つため、ということでデフォルトではそのようになっているようだ。

どのようなケースかというと、PAMを経由しないでログインする場合。このとき sshd はログインユーザに対してシステムデフォルトの nofile を強制する(つまり ulimit -n してみると 1024 と表示される)。これはsshで直接ログインしたユーザだけであり su - したりすると limits.conf に設定した値になる。

RHELではデフォルトでPAMを経由するようになっているので limits.conf を更新してログインしなおしただけで変更が有効になるように書籍では記述されているが、これは実は PAM を使うようsshdが設定されている(また pam.d にそのように設定がされている)場合に限る、という条件が隠れているのだ! し、しらなかったー!

Hadoop slaveの各デーモンは master node からssh経由でログインして起動されるようになっているため、sshで直接ログインしたときの ulimit が適用されることになり、PAMが有効でない sshd を使用している場合は limits.conf の値が適用されずに起動していることに気付けないまま、ということになってしまうことがあるので注意したい。したい。したかった。

どうするか

まず sshd_config を確認し、そこで UsePAM yes が指定されているかどうかを確認する。指定されていればOK。されていない場合はPAMを有効にするため以下の手順を踏む。

  1. 'UsePAM yes' を指定して sshd を再起動する
    • このときsshdのログに「そんな設定名は知らん」という内容のものが出ている場合は openssh がPAM無効でコンパイルされている
    • configure のオプションに --with-pam を指定して(pam-develパッケージを入れた状態で)ビルドしなおしてインストールし直そう
  2. /etc/pam.d/sshd をきちんと設定する
    • 認証を通すための設定をひととおりやる
    • 特に、読み込まれる一連の設定のどこかで 'session required pam_limits.so' が読み込まれるように注意すること
  3. master nodeからssh loginして ulimit -n をきちんと確認する

結論

自分が使ってるサーバはPAM無効でopensshがビルドされてて知らないうちにハマってたよ! という話でした! みんなも気をつけよう!

*1:Hadoop Hacks によるとRHEL6では noproc の変更も指定するようにある