ちょいとした用途において、カジュアルにFargateの起動/停止を繰り返して、気ままに負荷全開かけていたら、あまりの違和感にCPU割り当てについて調査することにしました。
最近こんなことばっかやってる気がしますが、気に食わんかったからムカムカ解消に書くしかないんや。半分くらいブラックボックス与太話な感じで夜露死苦です。
はじまり
とある処理を全開でFargateにやらせて、cpu=1024(100%), 2048(200%), 4096(400%) でどのくらい RPS (requests per second) でるかを計測していると、想定通りならほぼ比例でRPSが伸びるはずが、全然そうならないパティーンに遭遇。並列過剰やエラー・バグ起因ではないことをほぼ確させた上で、まさかCPUガチャじゃあるまいなと試したら、まんまCPUガチャでしたということで、EC2からある話ではありますが、現在はどーなのってことでまとめ。
CPUモデルとCPUリソース・AZの関係
ECSって素の使い方だと、TaskDefinition とかで微妙に面倒だったりするのですが、ポチポチで複数台の作成/削除をできる仕組みを用意したのでCPUモデルの出現について調べました。CPU指定数とモデル
まずは指定CPUリソース量ごとに出現したCPUモデル。CPU指定数 | CPUモデル |
1024 | Intel(R) Xeon(R) Platinum 8124M CPU @ 3.00GHz |
Intel(R) Xeon(R) CPU E5-2680 v2 @ 2.80GHz | |
Intel(R) Xeon(R) CPU E5-2686 v4 @ 2.30GHz | |
2048 | Intel(R) Xeon(R) Platinum 8124M CPU @ 3.00GHz |
Intel(R) Xeon(R) CPU E5-2666 v3 @ 2.90GHz | |
Intel(R) Xeon(R) CPU E5-2686 v4 @ 2.30GHz | |
4096 | Intel(R) Xeon(R) CPU E5-2686 v4 @ 2.30GHz |
おまけで、あまりしつこく作り直さなかったけど、CPU=512 で Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz を確認したくらい。4096 だけは、何十回やっても1モデルしか出なかったけど、たまたま……なのか。
256 でも 4096 と同じモデル出現を確認したとはいえ、数十回程度だと、CPU指定数に対してある程度のモデルが固定されている体感でした。あくまで体感。
環境の区分とモデル
特定のCPU指定数・AZで何度作り直しても、たいていは同じモデルが割り当てられます。フツーに考えれば、それが普通の仕組みではあります。空きが出ればまたそこに割り当てるだろうし、連続してタスクを起動すれば1物理サーバーに連続して割り振られる可能性が高そうだからです。あえて連続したタスクをバラバラの物理サーバーに振り分けることにもメリットはありますが、CPUモデルがバラつきやすくなったり、廃棄間近のサーバーに割り振りたくない、とか考えると整理整頓された割り振りになるのが自然……と予想。
AZ(a), AZ(c) で何度作り直しても同じだなぁと思ってるとこに AZ(d) を追加してみると、別のモデルが出現し、そこでの作り直しもやはり前と同じモデルになりました。で、時間がそれなりに経過したら変わることがある。
ということで、CPUモデルの割り振り条件(仮)は
- Region
- Availability Zone
- CPUリソース指定値
- タイミング
でそれなりに固定化される傾向にある。
ちなみに、メモリ量はCPUに対する最低値を指定したので、これを大きくすると少しは別サーバーに割り振られる可能性が高くなる気はする。
CPUモデルごとの性能差
こっからが本題。軽くベンチマークを採ってみる。CPU種類によっては処理の得意不得意があるけども、目先の取りやすい方法で採った結果。OpenSSL speed
前にもやったやつ。CPU使用率は当然100%換算で100%。
1 |
openssl speed -elapsed -evp aes-128-cbc -multi $multi |
CPU指定数 | CPUモデル | multi | Result |
1024 | Intel(R) Xeon(R) Platinum 8124M CPU @ 3.00GHz | 1 | 1285980.16k |
Intel(R) Xeon(R) CPU E5-2680 v2 @ 2.80GHz | 606863.36k | ||
Intel(R) Xeon(R) CPU E5-2686 v4 @ 2.30GHz | 605700.10k | ||
2048 | Intel(R) Xeon(R) Platinum 8124M CPU @ 3.00GHz | 1 | 1285570.56k |
2 | 2567148.89k | ||
Intel(R) Xeon(R) CPU E5-2666 v3 @ 2.90GHz | 1 | 718372.86k | |
2 | 1430607.19k | ||
4096 | Intel(R) Xeon(R) CPU E5-2686 v4 @ 2.30GHz | 1 | 606191.62k |
2 | 1211613.18k | ||
4 | 2400442.52k |
CPUモデルによっては最大で2倍の性能差があり、それによって cpu=2048 と 4096 の最大値が同じくらいになる事象が発生。
参考値として前に書いた、EC2での結果 を持ってくるとこんな感じなので、Fargateの遅いパターンはだいぶ遅いのがわかる。
タイプ | multi | Result |
c5.2xlarge | 1 | 1,284,579.33k |
r5.2xlarge | 1 | 1,169,634.65k |
c6g.2xlarge | 1 | 1,992,185.17k |
ちなみに省略したけど、外見上の vCPUs は cpu <= 1024 だと 2つ、cpu >= 2048 では 4つ になります。でもCPU使用率の最大は、256 だと 25%、512 で 50%、1024 で 100%、2048 で 200% となるように制御されています。豆。
Locust
Locustいじってたので、HTTPクライアントとして最大RPSを計測。1024なら1worker、4096なら4worker起動することでCPU使用率はMAX状態。CPU指定数 | CPUモデル | worker | req/s |
1024 | Intel(R) Xeon(R) CPU E5-2680 v2 @ 2.80GHz | 1 | 621.75 |
2048 | Intel(R) Xeon(R) CPU E5-2686 v4 @ 2.30GHz | 2 | 820.45 |
Intel(R) Xeon(R) CPU E5-2666 v3 @ 2.90GHz | 1633.09 | ||
4096 | Intel(R) Xeon(R) CPU E5-2686 v4 @ 2.30GHz | 4 | 1697.29 |
この時はたまたま 2048 と 4096 で同じCPUが出たけど、その比較だとCPU数に比例した倍々の性能。でも 2048 で出た強CPUと 4096 を比べると、ほぼ等しい性能値に。
CPUモデルの詳細確認
今回は該当CPUがいつものところに情報がなかったので、CPU benchmarks を参考に。用事があった Locust の方で見ると、倍強かった E5-2666 v3 @ 2.90GHz は 2015年産で 9core 18thread.
その半分の数値だった E5-2686 v4 @ 2.30GHz は 2016年産で 18core 36thread.
OpenSSL の方で強かった Platinum 8124M CPU @ 3.00GHz は、2018年産で 18core 36thread、ベンチマーク値が高い。
CPUは総合的な計測値や周波数よりは、シンプルに年代が新しいほうが速い、ということが多いので 2018年産が強いのはよいとして、
わりと年代が近い2015年モノと2016年モノについて考えると、Clockspeed とコア数を比較したときに、それぞれから同じ cpu = 1024 = 1vCPU として貸し出されるのは、あまりに釣り合っていない印象。近い年代ならコア数が少なくClockspeedが高い方が、1vCPUあたりは強くなるはずで、それが計測値に倍差となって現れたのではなかろうか。
性能の落差
FargateのCPUはお世辞にも良いとはいえず、それなりの型落ちを含むのは間違いない。んでもって、割り当てられるCPUモデルの性能に結構な落差があるのがわかった。処理内容によるだろうとはいえ、大雑把に2倍差とする。この2倍差というのは、どういうことかというと、
さきほどのように cpu=2048 のタスクの全力と、cpu=4096 の全力が同じ性能になることがある。
複数タスクに分散処理させたときに、グループとしての平均CPU使用率が 60% だとしても、最小値 40% , 最大値 80% になる可能性があるということ。
10台のうち1台が弱CPUの場合、平均CPU使用率50%台のときに、その1台だけ100%に到達して遅延・エラーになる可能性があるということ。
短期的なジョブでの複数台利用ならば、そこまで致命的にはならなくとも、WEBサーバーのような常駐型だとユーザーに不利益となるかもしれない。
仮に cpu=4096 で常に弱CPUになるならば、観測上は半分以上が強CPUになる cpu=2048 を選択した方がコスパが1.5倍以上良い、ということになる。
問題は落差の大きさだけでなく、cpu指定値に性能が比例しない、ということが非常に分かりづらい要素となってしまう。EC2やRDSのインスタンスだと、CPUやメモリはタイプに対してほぼほぼ倍々設定であるものの、上位にするとネットワークやストレージの性能が上がるというオマケがあるために、上げることにメリットや安心感があった。
Fargateの現状だと、1024~4096での選択に確固たる理由付けがしづらい。できない。今回採ったデータは一部の事実ではあるけど、全くもって不確かなモノだからだ。
もしかしたら今EC2を調べても、同じように倍差を観測できる可能性はゼロではないが、少なくとも最新の第6世代Graviton2 は外見上はモデル差が見られないので、性能の特徴はどうあれ不安定さを生む可能性は少ない。
Fargate登場時から今に至るまで、常に型落ちCPUの使い所、のような立ち位置だったように感じている。とはいえ、多少の弱いCPUだとしても、利便性とのトレードオフと受け取ればそう非難するものでもなく、問題は不安定さにある。システムの不安定は言うまでもなく課題であり敵だ。
おそらくあまり改善がされそうにない箇所なので、当面はこの性能差をシステム設計に折り込んで、リソース状態や処理速度の違和感を飲み込んで扱うことになるだろう。
ECS Fargateは本当に名作だと思うだけに、今後の改善に期待していきたい(チラッチラッ