AWS EC2(2)使用する上で注意すること

EC2は、AWSマネージメントコンソールからクリック1つでインスタンスを起動できる、非常に便利なクラウドサービスである。一方でとても簡単に利用できることから、全ての制限が取っ払われ、自分の思い通りのまま自由にリソースを使用できるサービスだというような錯覚に陥りがちだ。EC2も元を辿ればデータセンターの中にある物理マシンである。使用する際にはいくつかの注意すべき点が存在する。

サービスで使用する際にT2インスタンスは使わない

T2インスタンスは、AWSの公式説明によると「ベースラインを超えてバーストする能力がある CPU パフォーマンスのベースラインを提供する、バーストパフォーマンスインスタンスです」とある。しかし実際は、データセンター内の同一物理サーバ上に収納されている他のインスタンスが実験用途等で使用され、バースト上の負荷がそのインスタンスに掛かった場合は、自分のインスタンスにも影響が出る可能性がある。したがって商用サービス等の安定した運用が求められる利用方法の場合にT2インスタンスを使用することはおすすめしない。

バックアップを用意しよう

インスタンスが落ちたり、リージョンごとサービスダウンする可能性もゼロではない。24時間365日稼動しているように見えるクラウドサービスにもダウンタイムは確実に存在する。少なくともアベイラビリティゾーンを分ける、可能であれば他のリージョンにもバックアップを取るなどの障害対策はしておこう。

古いインスタンスは使わない

仮想環境、仮想OSといえど元はデータセンターにある物理サーバである。古くなれば電源やHDDなどが故障するリスクも高まる。実際にハードウェアに異常が起こり、EC2のインスタンスが急に応答しない、インスタンスが落ちるなどの現象が発生することがあるようだ。したがって、古いインスタンスはなるべく使わず、M3を使うぐらいならM4を、C3を使うくらいならC4を使おう。ちなみにインスタンスが落ちた場合、Auto Recovery機能をONにしていれば、自動で再起動してくるようである。

リソースは枯渇する

仮想環境、仮想OSといえど元はデータセンターにある物理サーバである。用意しているリソース量が全て使用されればリソースは枯渇する。実際に東京リージョンでは、年末年始などの多くの企業がイベント利用を行うシーズンに、特定のインスタンスタイプが起動できないことがあるようだ。またリソースの枯渇だけでなく、メンテナンスが原因で新たなリソースが確保できないということもあり得る。どうしてもリソースの確保が必要であれば事前に確保しておき、実際に使用するまでインスタンスをStopしておくなどの対応が必要である。リザーブドインスタンスの利用も検討したい。

バージニアリージョンは諸刃の剣

バージニアリージョンは、AWS創業の地。新しいサービスが一番に投入されるリージョンでもあり、リソース量も他のリージョンと桁違いに大きい。しかし一方で施設の老朽化が進んでいるからか異常なほどサービスダウンが多い。日本でEC2を使ったサービスを展開をする際に、わざわざバージニアリージョンを使用するメリットはあまり無いが、リソース量が大きいためバックアップリージョンとして利用する価値はあるだろう。レイテンシーを気にするのであれば、リソース量は劣るが物理距離が近い、シンガポール等のアジアパシフィック地域のリージョンも候補に入れたい。

上限引き上げはお早めに

AWSのサービスには、それぞれサービス制限(スロットリング)が適用されており、例えば、EC2は初期状態では最大20台までしかインスタンスを起動できない設定となっている。上限値以上にリソースを使用する場合はサポートプランに加入の上、サポートに必要なリソース数とその理由を付けて上限値の引き上げや撤廃を申請する必要があるが、上限値の変更が必要な理由が不明確であったり必要以上のリソースを要求すると断られる場合もあるので、少なくとも処理に3営業日以上掛かることを見越して、早めに上限引き上げを申請しておいたほうがよいだろう。

Auto Scaleは過信しない

Auto Scaleはリソース量に合わせてインスタンス量を自動で調整してくれるとても便利なサービスである。しかし、閾値を超えたことを検知して新たなインスタンスを立ち上げるまで数分を要する。したがってバースト的な負荷には対応できない。瞬間的なアクセスが予想されるのであれば、Auto Scaleは使わずにあらかじめ手動で、一定数のインスタンスを立ち上げておこう。

CPU使用率が定常的に30%を超えるのであれば代替策を考えよう

CPU使用率が定常的に30%を超えるのであればもう1つ上のインスタンスに変更するか、同じインスタンスをもう1つ用意しよう。

性能の良いインスタンスで台数少なく運用する方がラク

どのような処理をするかにもよるが、低い性能のインスタンスを大量に並べるよりかは、性能の良いインスタンスを台数少なく並べたほうが運用がラクなことが多い。場合によるけどさ。

EBSのボリュームサイズによってI/O性能は変化する

ディスク容量あまり使わないからと最小限のディスク容量しか確保していない状態で、大量のディスクアクセスが発生した場合は皆が悲しむことになる。汎用(SSD) ボリュームのパフォーマンスはボリュームサイズによって変化するように設計されており、ボリュームサイズが大きければ大きいほど、良いI/O性能が与えられる。一定量のディスクアクセスが発生する可能性がある場合は、1TBなど大きめのボリュームサイズを割り当てておくほうがよい。

とりあえずCPU利用率を見ていればOK

CloudWatchはいろいろな項目があるので、どの項目を確認すればEC2が正常であるのか判断に困るかもしれない。そんなときは取り敢えずはCPU使用率だけでも見ておこう。

そのほかに注意すること

  • インスタンスを停止状態から実行状態に移行するたびに 1 時間分のインスタンス時間が課金される。
  • インスタンス起動後に設定変更できない項目が存在する。VPCやサブネット、Roleなどは後から変更できない。Roleは使う予定がなくても取り敢えず作成しておいたほうが良い。(参考:EC2起動後に、後からできること・できないこと

AWS Cognito(5)スロットリング

スロットリングとは

AWSは各サービスにサービス制限(スロットリングを行っており、各アカウントごとに使えるリソースの上限が設定されている。例えば、EC2は初期状態では最大20台までしかインスタンスを起動できない設定となっている。フルマネージドのサービスに対してもこれらの制限が設定されており、「フルマネージド」という名称でありながら負荷に合わせて際限なくスケールするわけではない。また、サービスによっては、サービス制限一覧にこの上限値が明記されていないものもある。

上限値以上にリソースを使用する場合はサポートプランに加入の上、サポートに必要なリソース数とその理由を付けて上限値の引き上げや撤廃を申請する必要がある。上限値の変更が必要な理由が不明確であったり必要以上のリソースを要求すると、要望が叶えられないこともあるので注意が必要である。理由を明確にした上で申請する必要がある。

なお基本的にAWSのマネージドサービスは、「定常的な利用」や「一時的なサービスを簡単に作成するため」に提供するシステムであるという考え方のようで、バースト的なアクセスや複雑な処理、定常的に大きな負荷が掛かる処理については、EC2上にシステムを構築して利用すべきであるというのがAmazonの方針のようである。大きな負荷の掛かる処理の場合は、上限引き上げ申請するだけでなく、EC2を用いて実現できないかについても検討すべきであろう。

Cognitoのスロットリング

AWSのサービスは日々拡張されていっているので、スロットリングの値は随時変更されている可能性がある。その前提のもと現時点で、

  • Cognito Identity: 数百/毎秒程度
  • Cognito Sync : 数千/毎秒程度

でスロットリングされており、それ以上の負荷が掛かる可能性があったりそれ以上のリソースを必要とする場合は、サポートに上限引き上げの申請を行う必要があるようだ。また、申請を行ったとしても標準値の数倍程度までしか拡張できないようである。Cognitoは昨年の9月に東京リージョンにきたばかりのサービスであるので、用意されているリソースにも限りがあるのかもしれない。今後のリソース拡張に期待したい。

AWS Lambda(2)LambdaでKinesis Recordを取得する

Kinesis Process Records

Kinesis Event 発生毎にLambdaを実行し、Kinesis Recordを取得することが可能である。AWS マネジメントコンソールから関数を作成する場合は、kinesis-process-recordを選択。

Kinesis関数の設定

Stream名など必要事項を記入しプログラムをアップロードすることでLambdaを実行することが可能となる。

lambda_kinesis_function_2

Eclipseで開発する場合は、EclipseのAWSプラグインから直接アップロードや設定を行うことも可能である。Eclipseプロジェクトを右クリックして、「Amazon Web Services」から「Upload function to AWS Lambda…」を選択、「アップロードするリージョン」と「関数名」を指定し、

Kinesis関数の設定

「Description」や「Role」、プログラム一式を格納する「S3バケット」を指定して「Finish」を押すとEclipseで作成したLambda関数がAWS上にアップロードされる。

Eclipse設定

JavaによるLambda関数の実装

RequestHandler<KinesisEvent, Object>を実装することで、Kinesisからデータを取得し処理を行うことが可能となる。1回の処理で複数のKinesis Recordを取得するのでfor文で廻してそれぞれのRecordの値を取得することができる。Kinesis Recordには、ApproximateArrivalTimestampというRecord入力時に自動付与されるタイムスタンプが存在し、この値を取得するためのgetApproximateArrivalTimestamp()というメソッドも用意されているが、現時点では値の取得に対応していおらず、このメソッドを実行してもnullしか返えらないので注意が必要である。

public class KinesisEventHandler implements RequestHandler<KinesisEvent, Object> {

    @Override
    public Object handleRequest(KinesisEvent input, Context context) {
    	    	
        context.getLogger().log("Input: " + input);
        
        for(KinesisEventRecord rec : input.getRecords()) {
        	// Recordを取得
        	Record record = rec.getKinesis();
        	// JSONを取得
        	byte[] byteArray = new byte[record.getData().remaining()];
        	record.getData().get(byteArray);
        	String json = new String(byteArray);
        	// タイムスタンプが取得できない
        	String timestamp = rec.getKinesis().getApproximateArrivalTimestamp();
        }
    }
}

Lambdaのスロットリング

Lambdaは、1つの関数につき1秒あたり同時処理数100でスロットリングされている。また、上限値の引き上げを申請しても1秒あたり同時接続数1000程度が限界のようである。したがって、Kinesisに大量のRecordが入力された場合はLambdaの上限を超えてしまいRecordを取りこぼしてしまう可能性がある。Kinesis Recordを確実に取得し処理する必要がある場合は、EC2上でKinesis Client Libraryを用いてKinesis Appを実装する必要がある。