高スループットなサーバアプリケーションの為の新しいフレームワーク「seastar」...
TRANSCRIPT
What’s this?C++14
Linuxカーネルをバイパスするユーザランドネットワークスタック
シェアードナッシングなプログラムデザイン
新しいプログラミングモデル
Seastar
+
+=
+
C++14?• フレームワーク全体でC++14を使用(g++ -std=gnu++1y、clang not tested)
• C++(11|14)はCloudius Systemsの標準使用言語なので…(OSvはC++11)
• 他言語にはbindingで対応する事を検討
なぜ必要?• 従来のネットワークスタックだと…
• Zerocopyできない・やりずらい
• ソケット&プロセス側とプロトコル処理側のコンテキストが別=CPUが別の事も→キャッシュ競合
• プロトコルスタック内のロック競合
• システムコール、コンテキストスイッチのオーバヘッド
Seastarのユーザランドネットワークスタックなら…
• Zerocopy対応
• シェアードナッシングなので(※後述)
• キャッシュ競合、ロック競合しない
• 殆どユーザランドで処理するのでシステムコールは呼ばれない、プロトコルスタックとアプリは同スレッドで動くためコンテキストスイッチ回数も少ない
Seastarネットワークスタックの内容
• C++14
• Sestarのフレームワーク上にフルスクラッチで実装
• 対応プロトコル:TCPv4, UDPv4, IPv4, ARP, DHCP(IPv6やマイナーなトランスポートプロトコルは非対応)
なぜ必要?• よくあるマルチスレッドモデル
• 処理の並列度に応じてスレッドを生成、共有データはロックまたはロックフリー構造(RCUなど)で保護
• ロック競合、キャッシュ競合が発生して性能が下がることがある 特にNUMA環境だと問題が大きい
• CPU数を超えるスレッド数を持つモデルの場合はコンテキストスイッチのオーバヘッドが発生する可能性がある
• スケジューラにより空いているCPUへマイグレーションされるのでキャッシュのローカリティがいつも最適に維持出来るとは限らない
Seastarのシェアードナッシングモデルなら…
• 単一スレッドの非同期エンジンがCPUごとに稼働
• アプリやネットワークスタックから発生した小さなタスクをSeastarでスケジューリング、非同期エンジン上で実行
• データを共有しないためロックはなく、従ってロック競合、キャッシュ競合は起きない NUMAフレンドリー→より高い性能が出せる
• コア間でデータを渡すためには明示的にメッセージパッシングを行う必要がある
• この構造に従ってアプリケーションを記述する必要がある
例:TCPコネクションのステート情報
• 通常のOSでは共有データ(ロックが必要)
• Seastarでは共有しない
• 同一コネクションのパケットがいつも同じCPUに届けば他のCPUからステート情報が見える必要が無い
• L2レイヤでフォワード先CPUを固定
例:memcachedのadd• TCPコネクションの例と違ってパケットヘッダ数バイトを見てフォワード先を固定という訳にいかない
• distributed classを利用して、全コア上で別々にデータストア用クラスのインスタンスを保持
• このインスタンス上でaddメソッドを実行
• キャッシュ・ロック競合は起きないがデータが重複してもたれているのでメモリ使用量はncpus倍
どのように並列処理をプログラムするべきか
• Seastarが採用するモデル:→ futures/promises/continuations(f-p-c)
• リアクティブプログラミングのサブセット
C++11/boostのfutures/promisesとの違い
• Seastarのfutures/promisesはSeastarの実装に特化された独自実装
• ロックしない
• メモリアロケーションしない
• continuationsをサポート
Future• Futureはまだ実行されていないかもしれない計算の結果を表す
• ネットワークから受け取る予定のデータバッファ
• n分後に時間が来る予定のタイマーの発火
• (終わる予定の)ディスク書き込みの終了
future/promiseの例future<int> get(); // promises an int will be produced eventually
future<> put(int) // promises to store an int
void f() {
get().then([] (int value) {
put(value + 1).then([] {
std::cout << "value stored successfully\n";
});
});
}
Continutionsfuture<int> get(); // promises an int will be produced eventually
future<> put(int) // promises to store an int
void f() {
get().then([] (int value) {
return put(value + 1);
}).then([] {
std::cout << "value stored successfully\n";
});
}.then()による処理の継続
選べる環境• Linux(実機 or 仮想化環境)
• Seastar TCP on DPDK
• Seastar TCP on vhost-net + tap + bridge
• Linux socket
• OSv(仮想化環境)
• Sestar TCP on DPDK(work-in-progress)
• Sestar TCP on virtio-net
• Seastar TCP on Xen PV NIC
• OSv socket
• OSv on 実機??(in future)
実装済み• Socket I/O
• Timer
• File I/O
• virtio-net support
• DPDK support
• Xen support
• Basic TCP/IP stack(Ethernet, ARP, IPv4, TCP, UDP, DHCP)
URL
• http://www.seastar-project.org/
• https://github.com/cloudius-systems/seastar