2015年3月23日
システムのI/Oに必要な時間の大部分はカーネルにあった
本記事は、原著者の許諾のもとに翻訳・掲載しております。
Key-Valueストアからロックサーバに至る、あらゆる実行中のサイトのシステムパフォーマンスは、今なお、主に レイテンシ や スループット で測定されています。
サーバのI/Oパフォーマンスでは、これが重要となります。高性能なI/Oサブシステムなくしては、これらのメトリクスのどちらにおいても良いパフォーマンスを行うことはできません。
奇妙なことに、この10年間で一般的なハードウェアのI/Oパフォーマンスは驚くほど向上しているにも関わらず、システムのI/Oパフォーマンスはあまり大きな変化を遂げていません。そこで、私はこのような疑問を持ちました。 「一般的なスタンダードなOSでは、I/Oパフォーマンスの向上は期待できないのだろうか?」
一般的なLinuxハードウェア上のシンプルなI/O
これは、Simon Peterらによって発表された 最新のOSDIレポート の裏に隠された重大な課題です。
私がこのレポートから学んだことの中で最も興味深かったことは、私の疑問に対する答えが“ノー”であったことです。 今日では、I/Oのレイテンシを悪化させる主な要因は、OSカーネルそのものであるというのです。
特筆すべき実験の1つは、一般的なハードウェアに一般的なLinuxを載せ、Redisでのシンプルな読み込みと書き込みのレイテンシを分類別に測定したことです。
(注意: この後に出てくる“レイテンシ”はとても重要です。マルチスレッドを使ってスループットを向上させることは可能です。しかし重要なのは、ある特定のリクエストのレイテンシには、向上の余地があるということです。特にこういったことに多額の費用を投じるだけの価値があるデータセンターのレベルではなおさらです。)
実験の詳細:
- 有線から1KBのパケットを受信する。
- Redisでデータの読み込みもしくは書き込みを行う(テストによって異なる)。
- これを1,000回繰り返し、消費時間の平均を取る(読み込み、書き込み、両方の実験を1度だけ行う)。
- これら全てを一般的なLinuxとサーバで起動させる。
- 例えば、Intel x520 10G NIC、Intel RS3 RAID 1GBフラッシュキャッシュ、Sandy bridge CPU、6コア、2.2GHzを搭載した、14万円ほどの価値のDell PowerEdge R520を使用。
- 全てのデータを シングルスレッド で処理する。
結果は非常に興味深いものでした。
読み込み(インメモリ)
書き込み(永続データ構造)
それぞれのケースにおいて、カーネルで費やされている時間の約70%はネットワークスタック内でのものであるということを付け加えると、より分かりやすいかもしれません。このネットワークスタックは各パケットのために呼び出されるので、さらに大きなペイロードの場合でも、これらの数値はほぼ一定のオーバーヘッドを持つと考えられます。とはいえ、もしアプリケーションが単にメモリにパケットを書き込むような場合よりも負荷が高いものなら、アプリケーションの消費時間は増加するでしょう。一方、ネットワークの消費時間には大きな変化はないはずです。
私が興味深く感じたのは(といっても私はネットワークやOSに関しては初心者ですが)、コアの測定にスループットではなくシングルスレッドのレイテンシを用いるという慎重な選択です。
これらのレイテンシの数値はカーネルが消費する時間を明確にしていますが、もしこれがスループットとマルチスレッドを用いていたとすると、カーネルの存在自体を忘れてしまっていたかもしれません。それぞれのクエリに掛かる時間のうちの84%がカーネルにおいてのものであるという事実を全く考慮せず、単に1秒あたりのクエリの増加だけを測定してしまうということは簡単に起こり得るでしょう。
測定していないものを最適化するのは非常に難しいのだということを頭に入れ、目的を持ったアプローチをすることが大切です。
I/OレスのOS、そしてさらにその上を目指して
リクエストがカーネルで処理される大体の時間を把握することは、一般的にWebスケールのサービスを設計、維持するために役立ちます。
これまでずっと、レイテンシに対する主な武器はパイプライン処理やマルチスレッドなどでした。もしレイテンシをそれほど気にしなくてよいとしたら、どんな可能性があるだろうと考えるのも面白いでしょう。例えば私(ネットワークの初心者)には、SPDYではパイプライン処理のスタックなどがよりシンプルなのかどうかという疑問が湧いてきます。
いずれにしても、このレポートの他の部分では、 Arrakis と呼ばれるOSを研究するモチベーションとしてこの実験を用いて、このようなレイテンシの削減につながる方法を探っています。
私が理解した限りでは、Arrakisの核となるアイデアは、カーネルがI/Oに提供している機能の多くは一般的なハードウェアでも提供できるということのようです。例えば、保護、多重化、スケジューリングなどです。
つまり、Arrakisが目指すのは、「コントロールプレーン」からI/Oを取り出して(例: 可能な限りカーネルから多くのI/Oを取り出す)、ユーザ空間「データプレーン」に配置する(例: 多重化などが直接ハードウェア上で実行されるが、カーネルでは実行されない)ということであるとも考えられるのです。
結果もまた良好のようです。著者らは、書き込みでのレイテンシは81%、読み込みでは65%削減できると主張しています。
これはエキサイティングな話ではありますが、やはり向上の余地はあるようです。例えば、特にデータセンターレベルにおいては、特定のハードウェアに対して手動によるコンフィギュレーションが必要なOSを持つことは好ましくないかもしれません。サービスレベルの停止を引き起こす原因は、今なお大半がコンフィギュレーションエラーであり、その原因をさらに不透明にすることは賢明ではないと言えるでしょう。
この懸念が現実になるかどうかは、時が経ってみないと分かりません。結局のところ、私は全くのOS初心者なのですから。
株式会社リクルート プロダクト統括本部 プロダクト開発統括室 グループマネジャー 株式会社ニジボックス デベロップメント室 室長 Node.js 日本ユーザーグループ代表
- Twitter: @yosuke_furukawa
- Github: yosuke-furukawa