まめ畑

ゆるゆると書いていきます

急なアクセスをCloudFrontに逃がす(案)

ほっとんど用途ないですが、こういうやり方もあるという程度のメモ。

急激なアクセス増加が見込まれる場合、BlogなどはS3に静的ファイルを配置して、S3直接もしくはCloudFront経由で配信することが有用ですが、都度S3にUploadする必要があります。
また、CloudFrontのカスタムオリジンにアクセス対象のサーバを設定して、DNSレコードをCloudFrontに向けておくこともいいですが、CloudFrontの料金が普段からかかってしまうのと、記事更新を即座に反映したい場合、CloudFrontのTTLを0や短い値にしておく必要があります。TTL0でもオリジンのデータ更新を確認し、更新されていない場合は実データのフェッチは行われません。

別ドメインを作って、それをCloudFrontのdistributionに向け、オリジンサーバにアクセス対象のサーバを設定すれば、アクセスが増えそうな箇所に露出する場合は、そちらのドメインをリンクに設定すれば良いのですが、もし、CSSやJSや画像などがフルパス指定されているような場合は、それらのリソース取得は直接オリジンサーバにアクセスが行ってしまいます。


そこで、かなりトリッキーですが以下のような構成を考えてみました。
Nginxでproxyをし、Nginxでコンテンツ中のドメインをCloudFront経由のドメインに変更して、CloudFrontへデータを流します。これで、使う時だけEC2インスタンスを起動し、ELBにぶら下げればアクセスのCloudFront経由で流せます。特定の時だけの使用であればTTLを長めに設定することも可能ではないでしょうか。ProxyはAMI化しておけばすぐに起動出来ます。
もっとコスト節約するのであればELBも都度起動して、distributionのOriginを都度切り替えるのもありかと思います。

f:id:con_mame:20130630183102p:plain

Nginxの設定は

  server {
    listen       80;
    server_name  cfnotice.example.com;

    proxy_set_header X-Real-IP              $remote_addr;
    proxy_set_header X-Forwarded-Host       $host;
    proxy_set_header X-Forwarded-Server     $host;
    proxy_set_header X-Forwarded-For        $proxy_add_x_forwarded_for;
    proxy_set_header Accept-Encoding        "";

    location / {
      sub_filter 'info.example.com' 'cfnotice.example.com';
      sub_filter_once off;
      proxy_pass http://upstream:80;
    }
  }

sub_filter moduleを使っています。
upstreamサーバがdeflateでコンテンツを返さないように「proxy_set_header Accept-Encoding "";」を設定します。また全てをreplaceするので「sub_filter_once off;」を設定します。

後は、cfnotice.example.comを露出させてやるだけです。


本当にどうにもならないときにしか使うことは無いと思います。CloudFrontの独自ドメインでもSSLふが使えるようになったのでSSLを使いたい場合も問題ありません($600/月かかります)
また、CloudFront経由だけProxyにアクセスさせたい場合は
https://forums.aws.amazon.com/ann.jspa?annID=910
で、CloudFrontが使うIPアドレスレンジが公開されていますが、常に最新の状態ではないのでお気をつけください。

  • S3+CloudFront
  • S3直
  • 別ドメインを設定してCloudFront経由

これらが正当だと思います。

Redshiftの管理面

最近Redshiftの需要が高まっていますが、管理面のことをあまりみないので、簡単にまとめておきます。

ドキュメントは
Amazon Redshift

接続するには

postgresqlクライアントを使います
JDBCで接続する場合のdriverは: http://jdbc.postgresql.org/download/postgresql-8.4-703.jdbc4.jar を使います(バージョン指定です。8.4)

public access

RedshiftはVPC内やClassic環境からのアクセスの他にPublic Accessを許可できます。インターネット側からアクセス出来る経路を開けますが、SGでアクセス元を絞れます。また、こちらの設定は後で変更可能です。

クラスタの起動・削除時間

  • 双方ともに約5-10分(node数などによってそれ以上かかることもあります)
  • クラスタの削除では最大3時間程かかったこともあります。

maintenance

Redshiftにもmaintenance windowがあり、毎週こちらが指定した、曜日・時間でメンテナンスが行われます。Version UpgradeをONにしておくと、その時間に行われます。
動作詳細はまだメンテナンスを経験していないのでわかりませんが、数分Readonlyになり、新クラスタへ引き継がれるかダウンタイムになるかのどちらかなのですが、こちらは確認をしたいと思います。

Snapshot

自動Snapshotと手動Snapshotがあります。
Snapshotはクラスタを止めることなく、オンラインで取得されます。
EBSと同じで差分で取得している雰囲気がします。10−20%性能低下が見られましたが、許容範囲内かと思います。こちらは、データサイズやクエリによりますので、検証をしてみてください。

SnapshotからのRestoreは
f:id:con_mame:20130628210600p:plain
Restore From Snapshot

SnapshotからのRestoreで復元される情報ですが、上の情報を見ると分かる通りクラスタ情報も格納されます

  • ノード数
  • ノードタイプ
  • AZ
  • VPC
  • Subnet
  • User/pass
  • xDBC Endpoint

ここで便利なのは、接続先のEndpointのFQDNも復元されるため、Restoreして新しいクラスタを起動してもアプリケーションの接続情報を書き換える必要がありません。
しかし、SG情報だけが復元されないためクラスタ詳細画面のModifyから設定する必要があります。
f:id:con_mame:20130628210559p:plain

また、そのクラスタに対するEvent(クラスタ起動・停止・変更など)とノードのリソース使用状況はSnapshotに含まれますが、Queryログのパフォーマンスデータは含まれません。

アクセス権限

Redshiftは各ノードのCPUなどのリソース使用率やクエリごとの実行計画やリソース使用率がManagement Consoleから確認出来ます。
IAMに以下の権限をつけることで、Redshift readonly accessが可能になります。クエリチューニングなどの際にかなり役立つかと思います。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "redshift:Describe*",
        "redshift:get*",
        "ec2:DescribeAccountAttributes",
        "ec2:DescribeAvailabilityZones",
        "ec2:DescribeSecurityGroups",
        "ec2:DescribeSubnets",
        "ec2:DescribeVpcs",
        "ec2:DescribeInternetGateways",
        "sns:Get*",
        "sns:List*",
        "cloudwatch:Describe*",
        "cloudwatch:List*",
        "cloudwatch:Get*"
      ],
      "Effect": "Allow",
      "Resource": "*"
    }
  ]
}

リソース使用状況

Redshiftは以下の様にクエリ毎・ノード毎のリソース使用状況が確認出来ます(CPU/memory/swap/NW/Disk/latencyなどなど) また、Queryの実行計画も確認出来ます。

  • node毎

f:id:con_mame:20130628210603p:plain

  • Query毎

f:id:con_mame:20130628210558p:plain
f:id:con_mame:20130628210602p:plain
f:id:con_mame:20130628210604p:plain
f:id:con_mame:20130628210556p:plain

クラスタサイズ変更

Resizeから簡単に変更できます。
f:id:con_mame:20130628210555p:plain
注意点は1クラスタ内のノードスペックの違うものを混在できないといところだけで、オンラインでResize出来ます。

変更中はReadonlyになるためデータのインポートはできません。
仕組みは既存クラスタをReadonlyにした後、Resize後のクラスタを起動、並列にデータをコピーし、終わったらEndpointのIPアドレスDNS側で変更するという流れです。

監視

データのインポートはcopyコマンドを使うとS3やDynamoDBからノード数に応じて自動で並列化され高速に行われますが、エラーが起こった際は、SNSに対してメッセージ送ったりSQSにキューを入れることが出来ます。
そのため、形式エラーでない場合はSQSをみて再実行するスクリプトを書くことで自動リトライが可能です。

ClouwdWatchでもnode毎に監視可能です。
f:id:con_mame:20130628210601p:plain

全景

f:id:con_mame:20130628210557p:plain

S3のStatic WebSite Hostingでエラー時にリダイレクト

S3のStatic WebSite Hostingは静的ファイルをホストするにはとても便利な機能です。
S3のバケットにたいして、Static WebSite Hostingを有効にして、バケットポリシーで全公開するだけで、Webサーバなどを用意することなくサイトが公開出来ます。
S3のアクセスに対するキャパシティは非常に大きく、イベント告知やTV放映時の着地サイトなどに使うことで安く簡単に大量のトラフィックを受け止める事が可能になります。

このあたりのことは、よく書かれているのですが、実はもう1つ便利な機能があります。それは、特定の条件にマッチした時に、指定した条件でリダイレクトをさせるというものです。

特定のファイルに関しては、ファイルのプロパティでMetaタグとして、「Website Redirect Location」を設定し、リダイレクトするパスを設定します。
f:id:con_mame:20130612113921p:plain
こちらはファイルが移動したときなどに便利ですが、実は更に細かい条件が指定できる機能があります。

それが、Static WebSite Hostingの設定画面で指定出来る、Redirection Rulesというものです。
こちらを設定しておくと、特定のエラーコードをトリガーとして指定した条件でリダイレクトを行うことが出来ます。

ドキュメント: Configure a Bucket for Website Hosting - Amazon Simple Storage Service

以下の例は、バケットポリシーのコンディションで特定のIPアドレスや条件の場合のみアクセス可能にしたバケットに、このようなポリシーを設定する事で、forbiddenが出た場合にexample.comに転送し、存在しないリソースにアクセスした場合もexample.comに転送します。こちらのRuleで設定すると、レスポンスコードは301になります。こちらも変更可能です。

f:id:con_mame:20130612113931p:plain

<RoutingRules>
    <RoutingRule>
        <Condition>
            <HttpErrorCodeReturnedEquals>403</HttpErrorCodeReturnedEquals>
        </Condition>
        <Redirect>
            <HostName>example.com</HostName>
            <ReplaceKeyWith/>
        </Redirect>
    </RoutingRule>
    <RoutingRule>
        <Condition>
            <HttpErrorCodeReturnedEquals>404</HttpErrorCodeReturnedEquals>
        </Condition>
        <Redirect>
            <HostName>example.com</HostName>
            <ReplaceKeyWith/>
        </Redirect>
    </RoutingRule>
</RoutingRules>

ここでのポイントは

<ReplaceKeyWith/>

です。
こちらを指定しないと、リダイレクト時のパスは、リクエストがあったもの

のようにパスが維持され、リダイレクト先でもNot Foundが出る可能性があります。
こちらの設定を入れることで、パスを全て消してリダイレクトすることが出来ます。

他の条件はドキュメントに記載されている通りですが、

<ReplaceKeyPrefixWith/>

を使うことでリダイレクト先で、Not Foundページをキャッチオールする箇所を用意することで、どのパスにアクセスがあったかを把握するといった使い方も出来ます。


ちなみに、全公開用のバケットポリシーは

{
	"Version": "2008-10-17",
	"Id": "Policy1361774061719",
	"Statement": [
		{
			"Sid": "Stmt1361774057125",
			"Effect": "Allow",
			"Principal": {
				"AWS": "*"
			},
			"Action": "s3:GetObject",
			"Resource": "arn:aws:s3:::event.example.com/*"
		}
	]
}

こんな感じです。
event.example.comは公開予定のバケット名を指定してください。
また、独自ドメインで公開したい場合は、そのドメイン名をバケット名にする必要があります。

他にも設定出来る項目(protocolやレスポンスコード)があるので、使える場面は多いと思います。
S3で静的サイトをホスティングする場合に使ってみると便利かもしれません。

AWS Summit Tokyo2013でLTしてきました

AWS Summit Tokyo2013 2日間フルで参加して来ました。
Techセッションばかり出ていたのですが、会場も立ち見が出るくらいの盛況で、改めて、AWSへの関心の高さを感じました。
HPCインスタンスやRedshiftのTokyoリージョンでのサービスインも発表されて、中々盛り上がったとおいもいます。

また、JAWS-UGのイベントでも、LTをさせていたただ来ました。



Video streaming by Ustream



Video streaming by Ustream

また、AWSウルトラクイズで3位入賞したり、AWS認定ソリューションアーキテクト- アソシエイトレベル合格なども個人的なイベントとしてありました。

今年のAWSウルトラクイズの問題は
https://docs.google.com/spreadsheet/ccc?key=0AqoD_5v0fAIvdGZZRmVVcjJiT3ZiNVV1czBEYUlTNWc&usp=sharing
こちら

あの会場で、このLTをするのは中々どきどきだったのですが、言いたいことは1つ、ECUはあくまでも基準であって、使うときにはきちんと計測しようと言うことです。

運営の方々お疲れ様でした!

Route53のHealth CheckターゲットをELBで試してみた

先日、Amazon Web Services Blog: Amazon Route 53 Adds ELB Integration for DNS Failover で、Route53のHealth CheckターゲットにELBが指定できるようになりました。

今までも、Route53にはHealth Check機能がありましたが、ELBはHealth Checkターゲットに指定出来ませんでした。それが今回ELBのステータスに連動してDNS Failoverが出来るようになりました。

今回の大きなポイントはRoute53からHealth Checkを行うのではなく、AWS内部でELBとRoute53が連携し、ユーザがHealth Check項目をRoute53に指定するのではなく、ELB配下にインスタンスがいなくなった場合などにDNS Failoverが行われるところです。

設定

実際に設定して、どの位の時間でFailoverするか確認してみました。
Failover先は、S3のStatic Website Hostingです。こちらの設定の説明は割愛しますが、様々なパスでアクセスされてくるので、S3のStatic Website Hostingの設定中の、Error DocumentとIndex Dcoumentで同じメンテナンスページ用のファイルを設定することで、トップへのアクセスも、それ以外のアクセスはNot Foundをトリガーとして指定のメンテナンスページを表示する事が出来ます。

ELBのHealth Checkは
f:id:con_mame:20130602141844p:plain
のように設定しました。health checkの最小時間をセットしました。

Route53のレコードはA(Alias)で設定し、以下のように設定しています。

  • Primary

f:id:con_mame:20130602141839p:plain
Alias TargetはELBのAレコードです

  • Secondary

f:id:con_mame:20130602141841p:plain
Alias TargetはS3のStatic Website Hostingのエンドポイントです。しかし、S3側で表示されるものではないので、このフィールドにフォーカスをすると出てくる物の中から選択します。

この2つの設定でのポイントは、Associate with Health Checkの項目をNOに設定していますが、自動的にELBと連携してくれます。

確認

ELBにぶら下がっているインスタンスすべてのhttpdを止めてどのくらいの時間でFailoverするか確認しました。
ELBのHealth Checkは先の設定で6秒で切り離しと切り戻しが行われるようになっています。

  • 平常時
;; QUESTION SECTION:
;test.conma.me.                 IN      A

;; ANSWER SECTION:
test.conma.me.          60      IN      A       54.xxx.xxx.xxx

ELBのIPアドレスが返ってきています。
f:id:con_mame:20130602141846p:plain
サイトもVPCインスタンスから返ってきています。


ここで、ELB配下のインスタンスすべてのhttpdを停止しました。設定通り約6秒程でELBからの切り離しが行われました。
しかし、実際にDNSから返却されるIPアドレスが変わったのでは2分ほど経過した後でした。

;; QUESTION SECTION:
;test.conma.me.                 IN      A

;; ANSWER SECTION:
test.conma.me.          37      IN      A       27.xxx.xxx.xxx

S3のIPアドレスが返ってきています。
f:id:con_mame:20130602141851p:plain
S3からデータが返ってきています。


ここで、ELB配下のインスタンスを1台でも元に戻すと、やはり6秒程で切り戻されます。しかし、実際にDNSが返却するIPアドレスがELBのものに変わるまで、1-2分程かかりました。

まとめ

数回Failoverを試してみましたが平均して、1−2分ほどDNSからの返却IPアドレスが変わるまで時間がかかります。また、Failover先をS3ではなくInstanceにしても変わりありませんでした。
A(Alias)レコードで設定しているため、CNAMEではなくAレコードが返ってきていますが、A(Alias)はTTLが60秒に自動的に設定されます。IPアドレスが変更されるまで、大体このTTL程かかります。

ISPのDNSではなくRoute53のDNSで名前解決するように変更しても同じくです。

今回の機能拡張で、ELBを用いてサービスを提供しているものに対してもRoute53を用いてSorryサーバへのアクセス振り分けが可能になりました。
しかし、すぐに切り替わるのではく1−2分はアクセスが出来ない時間が発生するので注意が必要です。また、行儀悪くDNSレスポンスをキャッシュするDNSサーバを使っていると上手く切り替えが行えないこともあります。

ELBにSorryサーバが設定出来たり、ELBからStaticなSorryページを返せたら嬉しいですね。

今一度Provisoed IOPS EBSのベンチをとってみた

4,000IOPS EBSのベンチをとってみた - まめ畑 の記事で4,000IOPS EBSのベンチマークを簡単にとってみました。

他の高IOPS EBSと比較するとどうだろうということで、久しぶりにベンチマークをとってみました。
IOPSはBlock Size 16kでの性能ということになっています。

今回は前回のエントリ同様
m2.4xlarge (EBS Optimized Instance)を使用しました。
ファイルシステムext4
fioでDIRECTIOをONにして測定しました
fioのパラメータは

bs=4k,8k,16k,32k
size=5G
numjobs=64
runtime=16

でIOPS性能を測定しました。

結果

  • Read
Standard 1000 2000 4000
4k read 17000 1909 3797 7353
8k read 9979 1904 3435 6246
16k read 5369 1645 2470 4143
32k read 3025 1035 1326 2071
4k random read 1186 1041 2086 4177
8k random read 890 1035 2071 4141
16k random read 640 1035 2071 4142
32k random read 735 1035 1325 2071

f:id:con_mame:20130514173104p:plain

  • Write
Standard 1000 2000 4000
4k write 4932 1035 1605 2365
8k write 1148 1035 1510 2056
16k write 898 1035 1366 1648
32k write 648 1034 1182 1404
4k random write 1261 1039 1618 2211
8k random write 1037 1035 1477 1935
16k random write 884 1035 1315 1617
32k random write 637 1035 1168 1385

f:id:con_mame:20130514173101p:plain


結果を見ていただくと一目瞭然なのですが、Standard EBSはバーストはかなりするのですが、結果のブレが大きくなっています。
今回は10回の平均をとっているのですが、Standard EBSはブレが大きく、sequential writeにおいてはBlock Sizeにかかわらず200-1,000の間で結果がぶれました。
しかし、Provisioned IOPS EBSではきっちり安定した性能が出ています。バーストは少なく、設定したIOPSで綺麗に頭打ちになっているのが見えます。


安定した性能が必要な場面ではProvisioned IOPS EBSを使って、ベストエフォートでバーストしてほしい場面ではStandard EBSを使うといいのではないでしょうか。
Provisioned IOPS EBSの良さは、IO速度もありますが、安定した性能を維持するという方が大きい気が実際にProduction環境で使って思っています。

4,000IOPS EBSのベンチをとってみた

今日、Amazon Web Services Blog: Provision Up to 4,000 IOPS per EBS Volume, New Marketplace Supportで発表があったとおり、EBSで設定できるIOPSが4,000IOPSまで、Disk容量も1TBまで使えるようになりました。
今までは、2,000IOPSが最大値でしたが、2倍のIOPSまで使えるようになりました。


そこで、簡単ですが、通常のEBS・2,000IOPS EBS・4,000IOPS EBSでベンチを取ってみました。
実際に使用したベンチマークは後でまとめたいと思いますが、とあるサービスの本番データを使ったMySQLベンチマークでは2,000IOPS EBSよりも良い結果になりましたが、1.5倍程度の向上に落ち着いていました。あくまで、参考ということで。

また、
Amazon EBS の性能ベンチマーク その1 (Standard編) - 元RX-7乗りの適当な日々
こちらのシリーズでEBSの詳細なベンチマーク結果が掲載されています。


今回は
m2.4xlarge (EBS Optimized Instance)を使用しました。
ファイルシステムext4
fioでDIRECTIOをONにして測定しました
fioのパラメータは先程のエントリと同じ物を使用し

bs=4k
size=5G
numjobs=64
runtime=16

と

bs=32MB
size=5G
numjobs=8
runtime=16

で測定しました。

結果

  • IOPS
Normal 2,000 4,000
sequential read 16,500 3,792 7,476
sequential write 1,202 2,065 1,953
random read 1,149 2,050 4,177
random write 1,097 2,069 1,885

f:id:con_mame:20130508203947p:plain

  • Bandwidth(MB/sec)
Normal 2,000 4,000
sequential read 70 42.2 66
sequential write 44.5 42.1 65.9

f:id:con_mame:20130508203950p:plain


sequential readはノーマルEBSが圧倒的なIOPS性能を出していました。実際のDisk前にキャッシュがあると思います。しかし、その他のベンチマークでは、Provisioned IOPS EBSが良い結果となりました。
スタンダードEBSでは結果のぶれ幅が大きくあまりIOPS、帯域ともに安定しにくかったのですが、Provisioned IOPS EBSにおいては安定した結果を毎回出していました。

Provisioned IOPS EBSの場合、設定値を少し飛び出る程度まではバーストしますが、ほとんど設定値までしかでません。

スタンダードEBSの説明として

基準点として、スタンダードEBSボリューム(従来のEBSボリューム)は一般的に平均約100 IOPS程度の
性能で、ベストエフォート方式で数百IOPSまでバーストする能力をもっています。
スタンダードEBSボリュームは中程度またはバーストすることのあるI/O要求がある、
ブートボリュームに最適です。

と書かれている通り、普段使用していても、バーストが起こる場面が多く。700IOPSを超えている場面も多いです。

Provisioned IOPS EBSだから一重に性能がいいと使うのではなく、用途によっては通常EBSのほうが性能が出るというのを頭の片隅に入れてパフォーマンステストを行い、使用するのがいいと思います。
また、重要なポイントとして、スタンダードEBSはベストエフォートでバーストしますが、性能のブレが大きいというところです。Provisioned IOPS EBSはピーク性能が安定して期待値を出してくれますが、スタンダードEBSほどのバーストは起こりません。

その他のProvisioned IOPS EBSの利点として、パフォーマンスの他にIOでの課金がないため、IOが大量に発生する環境で、パフォーマンスをそこまで要求しないような場合IOPSを低めに設定したProvisioned IOPS EBSを使うことで、少しコストが安くなるかもしれません。Provisioned IOPS EBSはGB単価もIOPSでの上乗せもあるので稀な場合だとは思いますが。


その他の詳細なベンチマークなどは後日掲載したいと思います。
続き 今一度Provisoed IOPS EBSのベンチをとってみた - まめ畑