私はAWS EC2のt2インスタンスを誤解していた - CPUクレジットとベースラインパフォーマンス、そしてT2 Unlimited

スマートキャンプエンジニアの今川です。
この記事はスマートキャンプ Advent Calendar 2019 - Qiita 10日目の記事です。
別のネタで書こうと思っていましたが、ちょうど昨日今日でAWS5年やってたのに誤解してた!という経験をしたのでそれについて忘備録&人に共有するためにもまとめます。
T2 Unlimitedって何が嬉しいの?という方には読んでいただきたいです。

t2インスタンス - バースト可能なインスタンスタイプ

AWS EC2にはt2という安価なインスタンスタイプ群があります。
ベースラインから必要に応じてバースト可能な汎用インスタンスタイプ
という見出しがついており、
オンデマンドインスタンスの価格は 1 時間あたり 0.0058 USD から開始され、T2 インスタンスは最も安価な Amazon EC2 インスタンスオプションの 1 つであり、マイクロサービス、低レイテンシーのインタラクティブアプリケーション、中小規模のデータベースなどのさまざまな汎用アプリケーションに最適です。
という説明がついています。
普段t2系インスタンスを利用されている方や初めて知った方はどうイメージしたでしょうか?
普段は弱いけど、必要なときはパワーアップできる
という印象を持ったかと思います。私も 4,5年そう思っていました。だからこそ、
  • 常に高負荷になるアプリケーションには不向き
  • ユーザからのリクエストのピークタイムが決まっているようなWebアプリケーションなどには向いている
といった用途に向いている、という理解になるかと思っています
これは正解ではありますが、間違っています。 というのも、「一時的にパワーアップできる」という理解をするとT2 Unlimitedを使うべきタイミングやメトリクスをみて状況を正しく理解できなくなると思われます。

CPUクレジットとは何なのか?

ではT2系で動くCPUクレジットなるものは何なのでしょう?
1 個の CPU クレジットは、1 台の vCPU を使用率 100% で 1 分間実行することに相当します。
これに尽きます。パワーアップという概念はなくただ単に「CPUを1分100%で動かすとCPUクレジットを1消費する」というだけです。
その他の vCPU、使用率、時間数の組み合わせを CPU クレジットと同じにすることができます。たとえば、1 個の CPU クレジットは 1 台の vCPU を使用率 50% で 2 分間実行するか、または 2 台の vCPU を使用率 25% で 2 分間実行するのと等しくなります。
上記のページにも書いてありますが、CPUクレジットの会計単位はミリ秒単位であるし、CPU複数個にまたがって消費することもできます。
CloudWatchでCPUUtilization のメトリクスを見ると、上限は100%ですが、コア全部が100%のときにMAX100%になる計算であるため、 CPUUtilization * コア数分が実際のCPU使用率になります。
すなわち、CPUクレジットはCPUUtilization [%] * コア数 * 時間 [分] でつねに消費されることになります。
上図はある24時間におけるAWS EC2 t2.largeインスタンス(vCPUが2コア)のCPUUtilizationとCPUCreditUsageをCloudWatchでグラフ化したものです。
CPUUtilization[%]の値域は[0, 75]、CPUCreditUsageの値域を[0, 7.5]にすると波形がほぼ一致します。
CPUCreditUsageの値は5分の和が表示されている(下記リンク参考)ようなので、以下の式が成り立ちます
  CPUCreditUsage * 2 [コア] * 5[分]
= CPUCreditUsage * 10
= CPUUtilization[%]
これがCPUクレジットの使われ方です。

ではベースラインパフォーマンスとは何なのか?

CPUクレジットは各インスタンスタイプによって決まった速度で付与されていきます。たとえば、t2.largeは1時間にCPUクレジットが36付与されます。1分あたり0.4が付与されることになります。毎月もらえるおこづかいのようなものですね。
上記の通り、CPUクレジット1つで1分1コア100%を維持できます。もらった分より、消費する分が少なければCPUCreditBalanceとして貯めることができます。
では、もらった分より、消費する分が多いときはどうなるでしょうか?
もらった分より足りない分はCPUCreditBalanceが残っていればそこから捻出することができます。
CPUCreditBalanceがないときは、付与された分について使い尽くしてしまいます。足りない分はCPUを動かせなくなります。
たとえば、CPUCreditBalanceがないときはt2.largeにおいては1分あたり0.4しかもらえないので、1分間に1コア40%分だけしか動かすことができません。実はこれがベースラインパフォーマンスというものです。
ドキュメントを見るとt2.largeにおけるベースラインパフォーマンスは20%となっていますが、2コアフルパワーの20%なので1コア40%分です。この値は上記のCPUCreditBalanceの話と一致します。
ベースラインパフォーマンスというのは付与されるCPUクレジットに全く余裕がない時に起きる下限のCPU使用率のことでした。CPUCreditBalanceを使いまくるほど処理が多い状況だとCPUCreditBalanceが0になった瞬間に出力がおいつかなくなるようになってしまうということでした。

T2 Unlimitedを有効にすると起きること

ではCPUクレジットが足りない!今すぐ欲しい!というとき、何ができるのでしょうか。付与は以下のタイミングで行われます。
  1. 時間による付与(先述)
  2. インスタンス起動時に一定数付与される
これ以外でCPUクレジットをより使いたい場合、 T2 Unlimitedを有効化するという方法があります。
CPUクレジットという仕組みは貯めたり消費したりすることによって「ピーク時もアイドル時も負荷をベースラインパフォーマンスに均して考えること」を可能にします。他の汎用インスタンスファミリであるM系などでは「常に一定の負荷がかかること」を前提にしているため、ピークが一定で、アイドルタイムが長い用途と勿体なくなってしまいます。
T2 UnlimitedはCPUクレジットの前借り追加購入が可能になります。普通にしていると、ベースラインパフォーマンス以上の性能をあげようとするとCPUCreditBalanceが必要になります。T2 Unlimitedが有効になっているときは「その1日中で得られる合計のCPUクレジット」と「その日中に使ったCPUクレジット」の比較で計算することができ、そのタイミングにCPUCreditBalanceがなくても必要なパフォーマンスを出せるようになります。
上記のドキュメントにある図です。実線で表されているCPU使用率のグラフの面積を均したとき、ベースラインパフォーマンスである点線の30%以下になれば問題ないのですが、実際は点線を超えて紫線の値、1日で40%分になった場合、差分の10%分のvCPU分については課金されてしまうという仕組みです。
その上で、「その日中に使ったCPUクレジット」で赤字になってしまった分についてのみ、1時間のvCPU100%単位で課金されるという仕組みです。
UnlimitedはEC2コンソールでかんたんに有効化/無効化を切り替えることができます。
T2 Unlimitedでどれだけ前借りしているのか?どれぐらい足りなくなってしまっているか?についてはメトリクスが用意されています。以下の2つのメトリクスはT2 Unlimitedを有効にすると計測されるようになります。
  • CPUSurplusCreditBalance
    • CPUCreditBalanceが0のときに消費したCPUクレジット
    • 上限は1時間あたりに付与されるCPUクレジット☓24の値
  • CPUSurplusCreditsCharged -CPUCreditBalanceが0のときに消費したCPUクレジットで、課金対象になっているもの
前借りという言葉で紹介したとおり「これからはいる収入をあてにして動かすことを可能にしている」部分があるため、やめるタイミングも重要です。 CPUSurplusCreditsCharged が増えるタイミングが3つあります。
  1. 24時間分で得られるCPUクレジットに対して、消費したCPUクレジットのほうが多くなったとき(24時間が過ぎたあとに不足分のみ精算)
  2. インスタンスのstopやshutdown時は CPUSurplusCreditBalanceCPUSurplusCreditsChargedになる
  3. Unlimitedを無効化したときもCPUSurplusCreditBalanceCPUSurplusCreditsChargedになる
前借りしたままT2 Unlimitedを無効にせず、様子をみて前借り分を返済してから無効にしたほうがよさそうです。
こちらは以下の記事で理解できました。(ありがとうございます!)
一方で常に前借りしたり常に不足分を課金し続けるのはもったいないので、ほかのインスタンスタイプに変更することのを考慮にいれることも選択肢にいれてみましょう。
上で紹介したページに損益分岐点を求める計算式があるため、それを参考にしてみてください。

T3系について

最近はT3インスタンスファミリーも登場しました。T2より数字が増えているからなにか新しいからこっちのほうが断然いいんじゃない?と思う方もいるかと思います。
実際その通りで、パフォーマンス部分での改善がなされていますが、T2との大きな違いとしてUnlimitedがデフォルトでオンになっていることがあります。
知らない間に不足分のCPUクレジットについて課金されないよう注意しましょう。

最後に

あるときCPU負荷が上がらない割にWebサーバのレイテンシが増大したことがありました。その時、ちょうどこのことを思い出して確認したところ、CPUCreditBalanceが完全に枯渇してしまっていました。そこはUnlimitedを有効にして難を逃れました。
T2系インスタンスの特性を理解することで、非常時には勇気と自信を持ってUnlimitedを有効化できます。T2系を使っているかたはたまにCPUクレジットの存在を思い出してあげてくださいね。
明日は20卒内定者としてインターンをしているジョニーくんが20卒内定者インターン生が社員から頂いた愛のムチについて書いてくれます。楽しみですね!