Rustls:継続的なベンチマーキング事例研究
Everett Pompeii
Rustlsとは何ですか?
Rustlsは、OpenSSLのようなメモリ非安全な代替手段を置き換えることを目指して Rustで書かれた現代的なTransport Layer Security (TLS) ライブラリです。 TLSプロトコルは、通常、ウェブサーバーとクライアント間の安全な通信を提供するために使用されます。 TLSは以前はSecure Socket Layer (SSL)と呼ばれていました。 それは2つのパーティ間で送信されるデータが暗号化され、 傍受や改ざんから安全であることを保証します。 したがって、RustlsのようなTLSライブラリが早く、安全であることが非常に重要です。
🐰
https
のs
は、このページを表示するためにTLSを使用していることを示しています!
Rustlsのベンチマークテスト
Rustlsの最初のコミットは、プロジェクトの作成者Joseph Birr-Pixtonが2016年5月2日に行いました。 最初の成功したTLS接続が実際に行われたのは、同月の27日でした。 その年の9月には、彼は既にRustlsのベンチマークテストを行っていました。 彼が手にした大幅なパフォーマンスの向上を元に、 彼は2019年7月にRustlsとOpenSSLのヘッドツーヘッドのベンチマーク比較を行いました。
そのベンチマーク比較の結果は以下の通りでした:
- Rustlsはデータ送信が15%速かった。
- Rustlsはデータ受信が5%高速でした。
- Rustlsはクライアント接続の設定が20-40%速かった。
- Rustlsはサーバー接続の設定が10%速かった。
- Rustlsはクライアント接続の再開が30-70%速かった。
- Rustlsはサーバー接続の再開が10-20%速かった。
- RustlsはOpenSSLの半分以下のメモリを使用した。
2023年に、Internet Security Research GroupはRustlsプロジェクトのパフォーマンスベンチマークを資金提供し、 それがRustlsとOpenSSLの最新のヘッドツーヘッドのベンチマーク比較を生み出しました。 これらの更新結果はRustlsプロジェクトにとって 強みのエリアと改善が必要なエリアの両方に対して有益でしたが、 最も大きなパフォーマンス上の懸念は、_新しい_コードがパフォーマンスの低下を引き起こさないことを保証することにあります。
Rustlsのための継続的ベンチマーキング
リリース前にパフォーマンスの後退を検出するために、Rustlsプロジェクトは継続的ベンチマーキングに投資することにしました。
継続的ベンチマーキングとは、チームのメンバーが自分たちの作業を頻繁にベンチマークし、 通常は一人一日に少なくとも一度ベンチマークを行うというソフトウェア開発の実践です。 これにより、一日に複数回のベンチマークが行われます。 各ベンチマークは自動ビルドにより検証され、パフォーマンスの後退をできるだけ早く検出します。 このアプローチを採用することで、多くのチームはパフォーマンスの後退が大幅に減少し、 パフォーマントなソフトウェアをより迅速に開発できると感じています。
Rustlsプロジェクトの継続的ベンチマーキングの解決策は主に2つのコンポーネントから構成されています:
- CI Bench: CIでベンチマークを実行するために特別に設計されたカスタムベンチマーキングハーネス
- Bench Runner: カスタム、ベアメタルの継続的ベンチマーキングサーバーとパートナーのGitHub App
Rustls CI Bench
CI Benchは、連続的なベンチマーク用の最高のハーネスです。 それは、命令数モードと壁時間モードの2つの異なるモードで正確に同じベンチマークを実行します。 これは、独自の巧妙なカスタム非同期ランタイムを使用して実現されます。 命令数モードでは、入出力は実際にはまだブロッキングしています。 内部的には、タスクは単一のポーリングで完了するだけです。 その後、壁時間モードでは入出力は実際に非ブロックです。 これにより、共有メモリバッファのシミュレーションが可能になります。 サーバーとクライアントは交互にポーリングされます。 これにより、CI Benchは非同期ランタイムのノイズと非決定性をベンチマークから排除することができます。
Rustlsは、cachegrindを使用してCPU命令を追跡することを選択しました。 この決定は、Rustコンパイラの連続ベンチマーク解決策に模範されました。 命令数は、同じソフトウェアの2つのバージョンを比較する非常に一貫した方法を提供します。 これにより、継続的なベンチマークに適しています。 ただし、命令数の増加の実際のランタイムコストを推測することはできません。 命令数が10%増加しても、ランタイム性能が10%増加するわけではありません。 しかし、命令数の大幅な増加は、ランタイム性能がある程度上昇していることを意味します。 このため、CI Benchは壁時間も測定します。
壁時間は、Rustlsプロジェクトが本当に気にしているものです。 命令数の測定は単に便利なプロクシーです。 命令数ベースのベンチマークでは、同じ数の命令を使用するが壁時間性能が大幅に異なる変更を識別できません。 たとえば、新しいアルゴリズムは偶然にも命令数がまったく同じであるかもしれませんが、実行速度は2倍になるかもしれません。
Rustls Bench Runner
Rustls Bench Runnerは、独自の連続的なベンチマークサーバーです。
無加工のホスト上で実行するために設計されており、
GitHubアプリの同伴者からwebhooksを通じてイベントを受信します。
main
ブランチへの各pushごとに、
Bench Runnerは命令数と壁時刻の両方のベンチマークを実行します。
結果はローカルに保存され、
Bencher APIを用いてBencher上のRustlsプロジェクトに送られます。
プルリクエストが承認された場合、
またはRustlsのメンテナが @rustls-benchmarking bench
を含むコメントを残した場合、
ベンチマークスイートが実行されます。
Bench RunnerはGitHubからwebhookを受け取り、
プルリクエストのコードを取得し、
命令数のベンチマークを実行し、
壁時刻のベンチマークを実行し、
プルリクエストの結果を目標とする main
ブランチの結果と比較し、
その後、結果をプルリクエストへのコメントとして投稿します。
Bench Runnerは統計的な閾値としてDelta Interquartile Range modelを用いて、
性能低下が発生したかどうかを判断します。
この閾値を超える結果はプルリクエストのコメントでハイライト表示されます。
ベアメタルサーバ
Rustlsプロジェクトは、ウォールタイムベンチマークで1%の解像度を得るために、特別に設定されたベアメタルの継続的ベンチマーキングサーバに投資しました。 このサーバは、最近のほとんどのCIランナーとは異なり、一時的ではありません。 つまり、各実行には同じ基本的なサーバハードウェアとオペレーティングシステムが使用されます。 仮想化はありません。
ベアメタルサーバは、可能な限り一貫した結果を生成するように特別に設定されています。
周波数スケーリング(IntelのTurboBoost)や同時マルチスレッディング(IntelのHyper-Threading)は、BIOSでどちらも無効化されています。
CPUスケーリングはperformance
に設定されています。
アドレススペースレイアウトランダム化(ASLR)とNon-Maskable Interrupt(NMI)ウォッチドッグは、それぞれkernel.randomize_va_space=0
とkernel.nmi_watchdog=0
をsysctl.conf
に設定することで無効化されています。
ベアメタルサーバはOHVcloudがホスティングしています。
トロフィーケース
- PR #1640: Rustlsの連続ベンチマークインテグレーションを初めて使用し、
write_vectored
からwrite
への遷移を評価しました。この変更により、Rustlsの送信方向転送ベンチマークが一部のケースでほぼ20%向上しました。 - PR #1730: TLS ClientHello拡張の順序をランダム化したときのパフォーマンスの後退を見つけました。これにより開発の別のイテレーションが行われ、より効率的なアプローチが使用されました。
- PR #1834: クリティカルなセキュリティ修正がパフォーマンスの後退をもたらさなかったことを素早く確認しました。これにより、チームは複数のセキュリティパッチ版の迅速なリリースに集中することができました。
まとめ
プロジェクトの創始者によって設定された基盤を基に、Adolfo Ochagavía氏は、Rustlsプロジェクトのための印象的な連続ベンチマーキングソリューションを構築しました。これには、同じテストの指示数とウォールタイムベンチマークを実行するカスタムベンチマーキングハーネス、カスタムベンチマークランナー、カスタムGitHubアプリ、およびカスタム専用ベアメタルサーバーが含まれます。これは、最も印象的なプロジェクト固有の連続ベンチマーキングソリューションの一つです。プロジェクトが特製の連続ベンチマーキングソリューションを構築し維持するための時間とリソースを持っている場合、Rustlsプロジェクトは目指すべき高いバーを設定します。
このケーススタディをレビューしてくれたAdolfo Ochagavíaに非常に特別な感謝を申し上げます。彼のブログ投稿、Rustlsのための連続ベンチマーキングとRustlsのパフォーマンスがその内容の基礎でした。
Bencher: 連続ベンチマーキング
Bencherは、連続ベンチマーキングツールのスイートです。 パフォーマンスの後退があなたのユーザーに影響を与えたことはありますか? Bencherなら、それが起こるのを防げた可能性があります。 Bencherは、パフォーマンスの低下を_productionに到達する_前に検出し、防止することを可能にします。
- 実行: お気に入りのベンチマーキングツールを使用してベンチマークをローカルまたはCIで実行します。
bencher
CLIは単にあなたの既存のベンチマークハーネスをラップし、その結果を保存します。 - 追跡: ベンチマークの結果を時間と共に追跡します。ソースブランチ、テストベッド、測定基準に基づいてBencherのWebコンソールを使用して結果を監視、クエリ、グラフ化します。
- キャッチ: CIでパフォーマンスの後退をキャッチします。Bencherは最先端のカスタマイズ可能な分析を使用して、パフォーマンスの後退がProductionに到達する前にそれを検出します。
機能の後退を防ぐためにユニットテストがCIで実行されるのと同じ理由で、Bencherを使用してCIでベンチマークを実行してパフォーマンスの後退を防ぐべきです。パフォーマンスのバグはバグです!
CIでパフォーマンスの回帰を捉えるのを開始してください - Bencher Cloudを無料で試す。