起きたこと
EC2(インスタンスタイプ:t2.micro)で重たい処理を走らせた所、途中までは下図①のようにCPU使用率が100 %まで上がるものの、その先で下図②のように10 %から上がらず処理に時間がかかりました。
プロセスも終了していないし、メモリやネットワーク、RDSなどの使用率も確認したがボトルネックになっているような箇所は見受けられませんでした。
キーワード
- CPUクレジット
- ベースライン使用率
- Unlimitedモード
t2の挙動
公式説明
t2の説明文にはこのように書いてあります。
ベースラインから必要に応じてバースト可能な汎用インスタンスタイプ
私はこの一文を「ベースライン = CPU使用率100 %」と解釈したため、通常使用でもCPU使用率100 %を発揮でき、必要に応じてオートスケール可能なのだという思い込みをしていました。
CPUクレジットとベースライン
t2およびt3インスタンスにはCPUクレジットという概念があります。
CPUクレジット残高が0のとき、各インスタンスごとに決められたベースライン使用率で稼働します。
例としてt2.microではベースライン使用率が10 %なので、
CPUクレジット残高が0のとき起きたことに掲載した画像の②のように10 %を超えた稼働ができなくなります。
CPUクレジット1つは、1vCPUのCPU使用率を1分間100%まで上げることができます。
例として、
- 1vCPUのCPU使用率50% -> 2分間で1クレジットを消費
- 2vCPUのCPU使用率50% -> 1分間で1クレジットを消費
※ 実際にはCPUクレジットは整数値ではなくミリ秒単位で消費計算がされます。
Unlimitedモード
t3ではデフォルトでUnlimitedモードがONにされています。
これはCPUクレジットが枯渇してもベースライン使用率を超えた稼働を可能にするものですが、当然その分は課金が必要になります。
CPUクレジットの獲得
CPUクレジットは2つの方法で獲得することができます。
- 起動クレジット (t2のみ)
- 経時獲得クレジット
t2インスタンスは停止・再起動によってCPUクレジットの持ち越しができません。
その代わり、起動時に起動クレジットがもらえます。
t2.microの場合は30クレジットです。
一方で経時獲得クレジットは起動している間、インスタンスタイプによって決められた割合だけ時間経過でもらえるクレジットです。
t2.microの場合は6クレジット/時です。
※ 消費と同様に、実際にはCPUクレジットは整数値ではなくミリ秒単位で獲得計算がされます。
CPUクレジットの保有と消費
CPUクレジットは経時獲得量が消費量を上回る時、残高が増えていきますが保有できる上限が決まっています。
上限数はインスタンスタイプによって異なりますが、 24時間で獲得可能なクレジット数 と同値です。
また、t2の起動クレジットと経時獲得クレジットは見た目上区別されていませんが、消費の優先度や獲得上限などでは区別されています。
区別1 保有可能上限は別管理
上記でCPUクレジットの保有可能上限を24時間で獲得可能なクレジット数と述べましたが、これは経時獲得クレジットの上限で起動クレジットは別カウントされます。
そのため、起動してからクレジットを一切消費しなかった場合、保有できる最大値は
保有できる最大値 = 起動クレジット + 経時獲得クレジットの上限
になります。
区別2 起動クレジットから消費される
起動クレジットと経時獲得クレジットの両方が存在しているとき、起動クレジットを消費し、起動クレジットが枯渇してから経時獲得クレジットを消費し始めます。
おまけ:ベースライン使用率の本質と計算方法
ベースライン使用率は本質的には 「CPUクレジットの獲得数と消費数が釣り合うCPU使用率」 です。
ためしにt2.microとt2.largeを例にベースライン使用率を計算してみましょう。
t2.microのベースライン使用率
t2.microは1vCPUで1時間に6クレジットを獲得できます。
そのため1vCPUが1時間で6クレジットを消費するようなCPU使用率を計算すればOKです。
60分あたり6クレジット消費可能
-> 1分あたり0.1クレジット消費可能
-> 0.1 = 10%(ベースライン使用率)
ということで、10%の使用率が算出されました。
t2.largeのベースライン使用率
t2.largeは2vCPUで1時間に36クレジットを獲得できます。
t2.microと同様に計算をしますが、複数vCPUなためベースライン使用率の算出のためにはvCPU数で割る必要があります。
60分あたり36クレジット消費可能 / 2vCPU
-> 1分あたり0.6クレジット消費可能 / 2vCPU
-> 0.6 / 2vCPU = 60% / 2vCPU
-> 1vCPUあたり30%(ベースライン使用率)
最後に
t2インスタンスは気軽に使えて便利ではありますが、制約も大きく、できることには限りがありますね。
AWSはこのあたりのバランス感覚が非常に優れているな、と改めて痛感しました。