CentOS と Debian の名前解決の違い

CentOS と Debian の名前解決の違い

毎秒 InetAddress.getByName("example.com") を呼び出しループする小さな Java プログラムがあります。これを CentOS 6.4 ボックスで 'strace -f' を使用して実行すると、/etc/resolv.conf が開かれ、1 回読み取られることがわかります。

$ grep /etc/resolv.conf strace.out
[pid 24810] open("/etc/resolv.conf", O_RDONLY) = 6

Debian 7 で実行すると、/etc/resolv.conf が繰り返し開かれたり stat() されたりしていることがわかります。

$ grep  /etc/resolv.conf strace.out
[pid 41821] open("/etc/resolv.conf", O_RDONLY) = 10
[pid 41821] stat("/etc/resolv.conf", {st_mode=S_IFREG|0644, st_size=92, ...}) = 0
[pid 41821] open("/etc/resolv.conf", O_RDONLY) = 10
[pid 41821] stat("/etc/resolv.conf", {st_mode=S_IFREG|0644, st_size=92, ...}) = 0
[pid 41821] stat("/etc/resolv.conf", {st_mode=S_IFREG|0644, st_size=92, ...}) = 0

どちらのシステムも/etc/nsswitch.confが次のように設定されている。

ホスト: ファイル DNS

どちらのシステムでも名前キャッシュ デーモンは実行されていません。

Java の違いを排除するために、両方のマシンで同じバージョンの Oracle HotSot Java JVM を使用しました。

CentOS 6.4 ボックスには glibc 2.12 がインストールされています。Debian 7 ボックスには glibc 2.13 がインストールされています。

/etc/resolv.conf を開いて読み取る際に、2 つのオペレーティング システム間で動作が異なるのはなぜでしょうか?

答え1

RedHat glibc 開発者は、ソフトウェア内の一部のバグをバグではないと考えています。これらのバグの 1 つは、変更後の resolv.conf の再読み込みです。glibc はそれをアプリケーションの責任と見なしているため、各アプリケーションはこれに対して独自のロジックを作成する必要があります。

これはまったくおかしなことなので、eglibc 開発者はこの問題を修正しました。そのため、eglibc 以外のシステムでは、アプリケーションに nss_dns を再初期化するための独自のロジックを持たせるか、resolv.conf の変更後に再起動する必要があります。eglibc システム (Debian および Debian ベースのもの) では、バグの少ない libc が提供されます。

resolv.conf を変更し、古い DNS サーバーを廃止し、1200 台以上の MySQL サーバーを再起動した後に、このことを痛感しました。言うまでもなく、これは楽しいことではありません。

答え2

C ライブラリのバージョンが異なるだけでなく、CentOS は GNU C ライブラリ ( glibc) を使用するのに対し、Debian は組み込み GLIBC ( eglibc) を使用するため、名前検索システム コールの実際の実装はまったく異なります。

おそらく、この 2 つのディストリビューション間でシステム コールの動作が異なるのはそのためでしょう。

InetAddress.getByNameと解釈されると思いますgetaddrinfo()。まずは、関連する C ライブラリの実装とバージョンで各システムコールのソースを読んでみてください。

実際に使用しているパッケージ バージョンのソースを必ず読んでください。EL 6.4 のパッケージは、元のアップストリーム バージョンと比較して 2 年以上にわたって改良されています。Debian パッケージでも同じことが言えると思います。

関連情報