1つのコアを固定するサーバー

1つのコアを固定するサーバー

私は Java で Vert.x を使用するサーバーで作業していますが、Ubuntu 12.04 を実行する専用サーバーで実行するとパフォーマンスの問題が発生することに気付きました。

サーバーは、受信した HTTP リクエストを受け取り、HMAC を使用して認証を行い、リクエスト本文を解析し、テキスト処理を行い、UDP 経由で別のサーバーにデータを送信します。ディスク I/O はなく、メモリ使用量は比較的少量です (スワップにはほど遠い)。Grinder と AWS インスタンスを使用してサーバーに対して負荷テストを行っていますが、十分に装備されたサーバーでも 1 秒あたり 10,000 を超えるリクエストを取得できません。

私が見ているのは、サーバー マシンの 1 つのコアがカーネル内で完全に固定されており、他のコアの使用率は約 20 ~ 25% しかないということです。CPU は着信 TCP 接続の受信に使用されていると推測しています。JMX は、io.netty.channel.nio.NioEventLoop.select() でほとんどの時間を報告します。これはカーネルを待機する時間をカウントしていると思われます。また、strace は futex() と epoll_wait() で多くの時間が費やされていることを示しています。サーバーのスループットを上げるためにカーネル設定をいじってみましたが、うまくいきませんでした。

プロファイラーの実行:

プロファイラーの ss 元のURL:https://i.stack.imgur.com/6wIZA.png

CPU使用率:

使用頻度 元のURL:https://i.stack.imgur.com/9mM5u.png

これを解決するにはカーネル レベルで何を調整すればよいのか考えています。TCP バッファ サイズを変更したり、ファイル ハンドルを増やしたり、TCP 機能をオフにしたりしてみましたが、効果はありませんでした。このサーバー OS は実際には Xen 上で実行されており、唯一の常駐 OS であるという点で「専用」です。

答え1

アプリケーションとそれが使用しているライブラリを精査してください。Linux カーネルに関する限り、少なくとも Sun/Oracle JVM 実装では、JVM スレッドは Linux 上のネイティブ スレッド (軽量プロセス) として実装されています。

JVM は、多数のスレッドを持つ単一のプロセスです。JVM が生成する各スレッドは、利用可能なコアのいずれかで実行できます。Linux では、単一のプロセスに多数のスレッドを含めることができます。

また、以下のリソースもご覧ください。

関連情報