Linux OSのジッタを体系的に削減する黒魔術

  • このエントリーをはてなブックマークに追加

      2015/08/10

Linux OSのジッタを体系的に削減する黒魔術
低遅延性の求められるトレードシステムにおいて、ジッタの原因をどのように体系的に発見してひとつずつ削除するのか?この質問はmechanical-sympathyのメーリングリストで提示されました。
アズール・システムズの技術担当副社長兼CTOであり、共同創業者であるGil Tene氏はこの質問に対して豊富な実経験から生まれた、蓄積された知恵を用いて回答しました。それは広く共有されるべき回答ですので、ここに紹介します。
Linuxシステムにおける一次的中断 (“hiccup”) やジッタの原因を見つけることはほぼ魔術と言えます。人々はしばしば急なCPU使用率の上昇を見て「この原因は一体何だろう」と想像をめぐらせます。

私の場合は、経験上の証拠(これまで手掛けた数十個のサイトに共通する)や他の技術者との情報交換に基づき、私の好みに合わない設定になっていて、かつシステムレベルの一時的中断が発見された場合に原因の「常習犯」リストを作って参照しています。これらの設定を始めから行っておくことにより、多くの試行錯誤を減らすことができます。(そして、これは「優先事項」ではありません。さらなるアドバイスを探す前に、適切に設定を行っておくべきことです。)
Linuxシステムにおいて数ミリ秒レベルの一時中断瞬断を避けようとするときに、現在私が最初にやることを以下にまとめます。

  1. THP (Transparent Huge Pages)をオフにすること
  2. vm.min_free_kbytesを少なくとも1GB(大規模のシステムでは8GB)に設定すること
  3. Swappinessを0に設定すること
  4. zone_reclaim_modeを0に設定すること

上記1~4のデフォルト値はLinux上では「間違い」であって、それぞれが、(独立して)数ミリ秒単位の一時的中断を引き起こします。私がそのことを知っているのは、実際に個人的にそれらの一時的中断に遭遇したことがあるからです。(例えばTHPが不正を働いた痕跡を示すカーネルスタックトレースがある状態で現行犯逮捕するようなものです。)

加えて、私は通常次を推奨しています。

5. HT(ハイパースレッディング)をONにすること。(Vcoreの実行待ち行列 (run queues) を2倍にするとCPUを待つ可能性は数倍低くなります。)

HT=Offがしばしば推奨されていますが、それはジッタが発生する可能性を著しく増加させてしまう未熟なスピード最適化技法です(数ミリ秒の停滞をジッタと見なすのであれば)。ハイパースレッディングをOFFにすることはシステムにより引き起こされた一時的中断を減らす助けにはなりません(少なくとも20マイクロ秒レベルより大きいレベルの場合には)。HTをOFFにすることはスレッドの実行の線速度を高めることの助けになる場合とならない場合があります。しかし、それはOSについて利用可能な実行待ち行列の数を半分にするという代償のもとに起こるものであって、もし実行可能なスレッドがコアよりも多い状態が数ミリ秒でも存在すれば、スケジューラのクォンタムレベルでの一時的中断が起こる可能性を著しく増大させます。これがシステムから一時的中断がなくなるまで通常HTをONにしておく理由です。その後、HTをOFFにして実験を行うことにより(a)一時的中断が再び起こらないか(b)何か他の測定基準が良くなったかを見るために実験を行うことができます。

numactl, taskset,isolcpusを使用することは、個別のスレッドすべてでジッタや一時的中断の発生(更に、キャッシュの挙動など)を防止する助けになります。同じことが、irqbalanceについても言えます。それらはすべてより高度なものですが、私はまずシステムをクリーンアップし、その後にコアのみを割り当てるやり方が好きです。それに加えて、コアなどを割り当てたら、関心のあるコア(またはコアのセット)上の一時的中断やジッタを個々に測定し始めるべきです。例えば、プロセスをnumactlとともにノード1にロックする場合には、jHiccup(または使用している他のあらゆるツール)の実行が同じノードに制限されるようにする必要があります。

一時的中断やジッタをコントロールするためには、使用しているコアに負荷をかけないようにすることが、特定のコアにワークロードを割り当てることよりもずっと重要なことです。定番のワークロードを避けて、残りのシステムにコアを割り当てること(例えば、initの起動やそれにともないブート後に来るすべてものなど)は、注意深くどのコアがどのワークロードのスレッドを実行するかを考えることよりも決定的に重要なことなのです。

しばしばスレッドがコアに注意深く配置されているシステムを見かけます。しかし、これらのコアはシステムにおいてきちんと割り当てがされていないようなプロセスと共有されています。(そう、これは愚かなことのように見えますが、非常に一般的に見受けられることです。)私がよく最初にお勧めするのは、「全体のシステム」を一つのソケットで実行させ続ける(例えばノード0)ことです。そして、遅延に敏感なプロセスを「もう一方のソケット」(例えばノード1)で実行させます。この状態で実行が適切かつクリーンに行われるようになり、不都合で除去が必要なほど大きな一時的中断がないことが見えてくると、望んでいるソケット内でコアを選択し始めることが可能になります。ただし、大体の場合はそこまで徹底的にやらなくてもよいことの方が多いです。

Isolcpusの場合は幾分(完全にではありませんが)異なります。Isolcpusにより、誰も「偶然に」あなたのコアを共有しないことを知るという利益を得ることができます。しかし、また同時にisolcpusのコアに割り当てるスレッドに関するスケジューラのコア負荷分散機能を失ってしまいます。特定のスレッドをisolcpusのコアで使用することを選択することは時々有益ですが、残りのプロセス(例えば、「JVMの残り」のように、プロセス内でバックグラウンドワーカーとともに稼働するもの)は一時的中断の少ないシステムやノードから依然利益を得ることになります。その利益は、重要なisocpusが割り当てられたスレッドの上にまで代わりに現れることになります。例えば、JVMにおいてisolcpusが割り当てられたスレッドの最も悪い一時的中断でさえも全てのJVMスレッドをまたがるセーフポイントのタイミングのようなものがほとんどになります。そしてisolcpuが割り当てられたスレッドやコアの外部で遅延の影響を依然受けやすい状態になってしまいます。

原文:http://highscalability.com/blog/2015/4/8/the-black-magic-of-systematically-reducing-linux-os-jitter.html(2015-4-8)
※元記事の筆者には直接翻訳の許可を頂いて、翻訳・公開しております。

 -Tech, プログラミング

FAworksではプロのコンサルタントが案件をお探しします

  関連記事

Twitterはどうやって1秒に3,000もの画像を処理しているのか

Twitterはどうやって1秒に3,000もの画像を処理しているのか

現在、Twitter は1秒間あたり3,000枚の画像(約200GB)を作成し持続している。 しかし

作業用BGMは本当に仕事が捗るのか?

作業用BGMは本当に仕事が捗るのか?

みなさんは普段どんなスタイルで仕事をしていますか? エンジニアでよくヘッドホンをしながら仕事をしてる

Node vs. Go : Roadomatic の実装における比較

目次 概要 サーバ運用 ラウンド1: リクエスト処理 UDPソケット リクエストの検証 ラウンド2:

フリーランスエンジニアは田舎でも働ける?メリットや注意点は?

【関連リンク】 ❏フリーランスエンジニアなら知っておきたい単価や条件の交渉について ❏フリーランスプ

良いプログラマの条件とは?

良いプログラマの条件とは?

野球の打者は、少なくとも30%の確率でヒットを打つことに成功すれば良いとされている。ゴルファーなら、

V8はどうやってJavaScriptコードを最適化しているのか?

僕の過去記事で、NodeJSがなぜ速いかについて話した。今日は、V8について話したいと思う。 多分、

ITエンジニアならチェックしておきたいおすすめ有名企業テックブログ15選(2015年版)

情報収集にも採用にも繋がるテックブログ 今年も終わりにさしかかり、アドベントカレンダーの時期になりま

エンジニアの作業効率を一気に上げてくれる、無料Google Chrome拡張機能おすすめ20選

ちょっとした時短の積み重ねが作業時間を減らしてくれる 情報収集やブラウザチェック、ルーティーンワーク

これでもうコーディングに集中できる!デスクで暑さ対策グッツ7選

あっという間に夏も後半ですが、まだまだ暑い日が続きますね。 コーディングに集中したくてもなかなか暑く

フリーエンジニアの仕事にはどんな種類がある?

【関連リンク】 ❏副業でフリーランスエンジニアになる場合に押さえておきたいこと ❏フリーランスエンジ