Cloud Programming Simplified: A Berkeley View on Serverless Computing
論文読んだのでメモ
バークレーUC校のサーバレスコンピューティングに関する調査論文 従来のServerful Serverに必要な作業
冗長性を持ち、一つのマシンの故障がサービス全体へ影響しないようにする
冗長化されたコピーで地理的に分散され災害に対する耐性がある サービスが可動しているかの監視
デバッグやパフォーマンス・チューニングのためのロギング
システムの更新やセキュリティパッチ
新しいインスタンスが使用可能になった場合のマイグレーション
Stateless Server = FaaS + BaaS
Serverlessがクラウドプロバイダにとっても魅力的なのはサーバリソースを最大限有効活用出来るため
またx86以外のコンピュータアーキテクチャも色々試せるためより領域特化型のコスト最適化を図れるかもしれないため
サーバレスの限界
shared nothing architectureのため内部状態の把握が重要になるようなアプリケーションではServerfulよりも時間やコスト面で弱い場合が多い
ビデオのリアルタイムエンコードなどはフレームに分けて部分的に並行してエンコード出来るためサーバレスは向いている
代数計算やMapReduce、機械学習パイプライン、データベースなどは内部状態の維持とその変更によって高いパフォーマンスが出せるためServerlessは弱い
またストレージへのアクセスが遅くS3も最近IOPSを変更出来るようにはなったものの高いスループットを出すには100KIOPSで$30/mほどかかる。普通にアクセスすると10ミリ秒以上かかるなどレイテンシが大きい
DynamoDBなどではIOPSを上げることで高いスループットを出せるもののやはりコストが高く、またスケールが遅い
それよりもElastiCache一台立ち上げてそこで状態を維持する方がずっと安いし高いスループットも出る。ただ可用性の点ではVMベースになるのでサーバ故障などで死ぬ可能性はある
またFunction同士の協調動作もSQSやSNSだと数百ミリ秒などのレイテンシがかかるため協調動作が必要なアプリは難しい
その場合はVMベースの通知システムを自前で作るなどする方法はある
ExCameraはVMベースのランデブーサーバで状態を維持してFunction同士の協調動作をしている
内部状態にアクセスするためのネーミングサーバなど新たな方法を探す価値があるかもしれない(Actors as a Service)
ストレージごとにレイテンシやコスト、透過的なプロビジョニング、分散や永続化など特性が異なるためユースケースにあったストレージを選ぶ必要がある
https://gyazo.com/b13808ec5af0a4df3b1f4aff440555ce
全てにおいてサーバレスに理想的なストレージはまだない
標準的なコミュニケーション方法におけるパフォーマンスの悪さもまた問題
Broadcast
Aggregation
Shuffle
以上の3つがビッグデータや分析系タスクではよくコミュニケーション・プロトコルとして用いられる
https://gyazo.com/87adf8820cb66deabd2e485a22f332ce
VMベースの場合でBroadcast, Aggregationにかかる複雑性はO(N)。NはVMの数
VMの場合BroadcastするデータやAggregationの前にVM上のメモリでデータを共有できるため、複雑性の増加はVMインスタンスの増加に比例する
Cloud Functionの場合はO(N x K)
KはVM当たりのFunction数
この場合Shuffle操作に置いて特に送るデータ量が多くなる
(N x K)^2 になりVMベースのソリューションに比べて2桁や4桁以上多いデータを送ることになる
パフォーマンスの予測のつけづらさ
コールドスタートが存在するため場合によっては初期化に時間がかかる
またクラウドプロバイダが自由にハードウェアを選べるということでたまに世代の異なるCPUを割り当てられることもありうる。そのことによりパフォーマンスの予測可能性が少なくなる
サーバレスコンピューティングはどうなるべきか
抽象化への挑戦
リソース最適化
現状は選べないがクラウドユーザがCPUなどのリソースも選べるようにするなど
しかしその場合はクラウドプロバイダのスケジューリング方法が難しくなる
より良い代案としては抽象化のレベルを上げ、クラウドプロバイダが最適なリソースを推測するというもの
前回実行時のプロファイルやコードの静的解析、ターゲットCPUの変更などにより最適なCPUとメモリを推測し自動的にプロビジョニングするという方法
ただこの方法はGCとも連携しないといけないため技術的には挑戦が必要だが、ある調査ではサーバレスプラットフォームと統合可能というものもある
データの依存関係
現状のCloud FunctionはFunction間のデータの依存関係を知る方法がない
これによりリソースの非効率な使用をしてしまう
MapReduceやNumpyの線形的な代数計算のように
一つの解決方法としてはクラウドプロバイダが計算グラフを指定するAPIを公開すること
これにより配置戦略の最適化やコミュニケーションコストを最適化する
MapReduceやApache Spark, Apache Beam, Cloud Dataflow, BigQuery, Azure Cosmos DB, Apache Airflowなどの分散処理系は内部で依存グラフを生成し計算を最適化している
基本的にそのようなシステムはCloud Functionで動作させることが可能でクラウドプロバイダに計算グラフを公開することが可能
AWS Step Functionsではこの方向性でステートマシン言語やAPIを提供している
システムへの挑戦
ハイパフォーマンスで透過的にプロビジョニングされるストレージ
一連のCloud Functionが終了するまでの一時的で高速なストレージが必要
これを提供する一つの方法はネットワークが最適化されたマイクロ秒レベルのレイテンシの分散インメモリサービスを提供すること
これを実現するにはアプリ間でメモリのアクセスコントロールやパフォーマンス分離を実現し必要に応じてキャパシティやIOPSを自動的に増やしメモリを適切に解放する仕組みが必要
RAMCloudやFaRMはそういったマイクロ秒レベルのレイテンシとインスタンス当たり数千IOPSのインメモリストレージを提供してくれる
統計的多重化をレバレジさせていくことで一時的ストレージは現状のServerfulコンピューティングよりよりメモリ効率になる
Serverfulでは必要のないメモリは無駄になる
Severlessでは使われていないメモリは別のFunctionで使用される
また一つのアプリケーションの場合でもあるVMで使われていないメモリーは別のVMで使うことは出来ない
この場合も共有インメモリサービスが有効になる
もちろんクラウドファンクションでもメモリを想定より使っていないとメモリの無駄が生じる
堅牢なストレージ
協調/シグナリングサーバ
起動時間の最小化
以下の3つが主な起動時間の影響要素
リソースのスケジューリング
アプリケーションの環境とコードのダウンロード、ロード、ライブラリの初期化
アプリケーション特有の初期化
AWSはRustなどで軽量分離環境を作成し起動時間の短縮を図っている
アプリケーション環境の初期化などはユニカーネルで短縮を図ることができる
ハードウェアを動的に検出する代わりにユーザ設定を適用し、従来のOSのようにデータ構造を割り当てる
事前にハードウェア特化で設定することや統計的にデータ構造を割り当てることで初期化コストを最適化する
またユニカーネルはアプリケーションで必要とされる最小のドライバやライブラリのみ含めることで従来のOSより小さい占有領域を提供する
また他の起動初期化コストを減らす方法としては必要とされるライブラリが実際に必要になるまで読み込まず動的に読み込む
Azure Functionでこれは共有ファイルシステムで有効にされているように
アプリケーション特有の初期化はプログラマーの責任だがクラウドプロバイダも処理を開始する前に静的解析などでスタートアップ処理をすることができる
ネットワークへの挑戦