Category: General


ASP.NET CoreとAWS CodeStarのDeep Dive

AWS CodeStar チームは最近、2つのASP.NET Coreプロジェクト テンプレートの追加を発表しました。ご存知かもしれませんが、AWS CodeStarは継続的インテグレーションと継続的デプロイメント(CI/CD)パイプラインを開発者に代わって作成し、それによって開発者は貴重な時間をインフラの構築の代わりにアプリケーションの構築に費やすことができます。新しいASP.NET Coreプロジェクトテンプレートを使用することで、.NET開発者は初日からAWSアプリケーションを構築し、展開することができます。Tara Walkerの優れたブログ記事では、AWS CodeStarでASP.NET Core アプリケーションを作成する方法について説明しています。このブログ記事では、AWS CodeStarのASP.NET Coreプロジェクトにテストを追加する方法を学ぶ中で、背後で何が起こっているのかを詳しく見ていきます。

 

Unit Test プロジェクトの追加

私たちの目標は、HelloControllerの機能を実行するシンプルなテストケースを追加することです。私はあなたが全く新しいASP.Net Core Web Service プロジェクトを持っていると仮定しています。もし、まだプロジェクトを持っていない場合は、Taraのブログ記事(上記)をたどってプロジェクトを作成することができます。ASP.NET Core Web Service テンプレートを選択していることを確認してください。ASP.NET Core for AWS CodeStarプロジェクトを作成後、Team Explorer でプロジェクト リポジトリをクローンし、AspNetCoreWebServiceソリューションをロードしたら、残りのブログ記事に沿って後を追えるようになります。Team Explorer でリポジトリをセットアップするためのガイドが必要な場合は、5月のSteve RobertのVisual StudioとCodeCommitのインテグレーションについての発表をご覧ください。

最初に、AspNetCoreWebServiceTestという名前の新しいxUnitプロジェクトをAspNetCoreWebServiceソリューションに追加します。私たちの新しいテストプロジェクトはHelloControllerクラスとJsonResultを参照するので、AspNetCoreWebServiceをプロジェクト参照として追加し、Microsoft.AspNetCore.MvcをNuGet参照として追加する必要があります。それらをテストプロジェクトに追加すると、AspNetCoreWebServiceTest.csprojに次の追加情報が表示されます。

 

<ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="1.1.3" />
    ...
</ItemGroup>
...
<ItemGroup>
    <ProjectReference Include="..\AspNetCoreWebService\AspNetCoreWebService.csproj" />
</ItemGroup>

 

これにより、HelloControllerクラスを直接参照し、JsonResultを展開することができます。次のように簡単なテストケースを追加しましょう。

using System;
using Xunit;
using Microsoft.AspNetCore.Mvc;
using AspNetCoreWebService.Controllers;

namespace AspNetCoreWebServiceTest
{
    public class HelloControllerTest
    {
        [Fact]
        public void SimpleTest()
        {
            HelloController controller = new HelloController();
            var response = controller.Get("AWS").Value as Response;
            Assert.Equal(response.output, "Hello AWS!");
        }
    }
}

 

ファイル名、名前空間、クラス名、およびメソッド名を変更したことに注意してください。テストを実行し、テストが合格することを確認します。ソリューション エクスプローラで次のように表示されます。

動作するテストプロジェクトを手に入れたので、アプリケーションをデプロイする前にテストをビルドして実行するようにパイプラインを更新します。

 

AWS CodeBuildジョブの更新

最初にプロジェクトの構築方法を見てみましょう。あなた、もしくはチームのメンバーがリポジトリに変更をプッシュすると、パイプラインは自動的に最新の変更に対してビルドプロセスを開始します。このステップでは、AWS CodeBuildはビルドプロセスを実行するためにリポジトリのルートにあるbuildspec.ymlファイルを使用します。

version: 0.2
phases:
  pre_build:
    commands:
      - echo Restore started on `date`
      - dotnet restore AspNetCoreWebService/AspNetCoreWebService.csproj
  build:
    commands:
      - echo Build started on `date`
      - dotnet publish -c release -o ./build_output AspNetCoreWebService/AspNetCoreWebService.csproj
artifacts:
  files:
    - AspNetCoreWebService/build_output/**/*
    - scripts/**/*
    - appspec.yml

 

AWS CodeBuildジョブは、AWS CodeBuildに.NET Coreイメージを使用します。これには buildspec.ymlで呼び出す.NET Core SDKとCLIが含まれています。このプロジェクトは1つのWebサービスで構成されているため、1つのbuildspec.ymlファイルで十分です。プロジェクトが拡大しビルドプロセスの複雑さが増すにつれて、いずれはシェルスクリプトまたはMSBuildの.projファイルを使用してシンプルにbuildspec.ymlでscript / buildファイルを呼び出すように、ビルドプロセスを外部で駆動したいと思うかもしれません。

 

ここでは dotnet publishコマンドに注目したいと思います。この発行のステップは、すべての依存関係をパッケージ化してホストマシン上ですぐに利用できるようにするために重要です。上記のbuildspec.ymlファイルのartifactsセクションで定義されているように、AWS CodeDeployがホストにアプリケーションを配置するために使用するファイル群が、Amazon S3バケットに格納されます。scripts/**/* には、appsec.ymlが依存するすべてのスクリプトが含まれています。appsec.ymlに慣れていない方や詳細を知りたい方のために次のセクションで説明します。

前のセクションでは、AWS CodeCommitリポジトリにテストプロジェクトを追加しました。今度は、新しいテストプロジェクトをビルドするためにbuildspec.ymlを更新する必要があります。ビルド ステージの一部として、単にdotnet vstestを実行することができますが、このエクササイズではベストプラクティスに従ってビルドとテストのステージを分けて構築します。 buildspec.ymlを修正してテスト バイナリをビルドし、その成果物をAspNetCoreWebServiceTest/test_outputディレクトリに発行しましょう。

pre_build:
    commands:
        ...
        - dotnet restore AspNetCoreWebServiceTest/AspNetCoreWebServiceTest.csproj
post_build:
    commands:
        ...
        - dotnet publish -c release -o ./test_output AspNetCoreWebServiceTest/AspNetCoreWebServiceTest.csproj  
artifacts:
    files:
        ...
        - AspNetCoreWebServiceTest/test_output/**/*

 

アーティファクトとしてAspNetCoreWebServiceTest/test_output/**/* を追加したことに注意してください。実際には、これは発行されたテストバイナリをAmazon S3にアップロードするようにAWS CodeBuildサービスに指示することになります。これにより、次に作成するテスト ジョブでそれらを参照できるようになります。

 

AWS CodePipelineの更新

前のセクションでは、テストを実行するために必要なバイナリをビルドして保存するために、新しいテストプロジェクトを追加し、buildspec.ymlを修正しました。次にテストステージをパイプラインに追加する方法について説明します。まずTestステージとUnitTestアクションをコンソールからパイプラインに追加しましょう。

残りのUIも以下のパラメータで埋めます:

  • Action category: Test
  • Action name: UnitTest
  • Test provider: AWS CodeBuild
  • Create a new build project を選択
  • Project name: <プロジェクト名>-test
  • Operating system: Ubuntu
  • Runtime: .NET Core
  • Version: aws/codebuild/dot-net:core-1
  • Build specificationInsert build Commands を選択
  • Build command: dotnet vstest AspNetCoreWebServiceTest/test_output/AspNetCoreWebServiceTest.dll
  • Role nameCodeStarWorker-<プロジェクト名>-CodeBuild をリストから選択
  • Input artifacts #1 は, <プロジェクト名>-BuildArtifact をリストから選択

 

ここでの重要な情報は、ビルドコマンドです。私たちのテストジョブは前のステージでビルドされたtest.dllに対してdotnet vstestを実行します。あなたのパイプラインはこのようになります。

これでほぼ完成です!「Release Change」を押してこのパイプラインを実行すると、パイプラインのテストステージで Error Code: AccessDeniedException  のメッセージを伴って実行が失敗します。これは、AWS CodeStarサービスに新しいテストステージを実行する権限がないためです。ここではAWS CodeStarプロジェクトへの適切なアクセスを許可する方法を確認しましょう。

 

Role ポリシーの更新

AWS CodeStarプロジェクトでは、さまざまなサービスやワーカーがアプリケーションを同期、ビルド、およびデプロイするための最小限のアクセス許可のポリシーを作成します。新しいAWS CodeBuildジョブを追加したので、新しいリソースへのアクセスをCodeStarWorkerCodePipelinePolicyで許可する必要があります。この変更を行うためにIAMコンソールに移動します。 [Role]タブで、 “codebuild”キーワードを使用して検索します。ロールはCodeStarWorker- <プロジェクト名> -CodePipelineの形式である必要があります。次に、ロールにアタッチされているポリシーを編集します。以下に示します。

変更したい内容は、ポリシー内にAWS CodeBuildアクションに関連付けられている新しいcodebuildリソースである arn:aws:codebuild:us-east-1:532345249509:project/<プロジェクト名>-test を追加することです。

{
    "Action": [
        "codebuild:StartBuild",
        "codebuild:BatchGetBuilds",
        "codebuild:StopBuild"
    ],
    "Resource": [
        "arn:aws:codebuild:us-east-1:532345249509:project/<your project name>"
        "arn:aws:codebuild:us-east-1:532345249509:project/<your project name>-test"
    ],
    "Effect": "Allow"
}

 

以上です。AWS CodeStarプロジェクトは新しいジョブを構築するための適切な権限を持ちました。[Release Change] を押して試してみてください。

 

ASP.NET Core アプリケーションのデプロイメント

ここまでAWS CodeStarがプロジェクトをビルドしテストする方法を見てきました。このセクションでは、デプロイメントプロセスを詳しく見ていきます。AWS CodeStarプロジェクトの作成の一部として、AWS CodeStarサービスはアプリケーションをホストするAmazon EC2インスタンスを作成します。またappspec.ymlの指示に従って、そのインスタンスにデプロイメントプロセスを実行するcode-deploy-agentもインストールされます。appspec.ymlを見てみましょう。

version: 0.0
os: linux
files:
  - source: AspNetCoreWebService/build_output
    destination: /home/ubuntu/aspnetcoreservice
  - source: scripts/virtualhost.conf
    destination: /home/ubuntu/aspnetcoreservice 
hooks:
  ApplicationStop:
    - location: scripts/stop_service
      timeout: 300
      runas: root

  BeforeInstall:
    - location: scripts/remove_application
      timeout: 300
      runas: root

  AfterInstall:
    - location: scripts/install_dotnetcore
      timeout: 500
      runas: root

    - location: scripts/install_httpd
      timeout: 300
      runas: root

  ApplicationStart:
    - location: scripts/start_service
      timeout: 300
      runas: root

 

各スクリプトは、デプロイメントプロセスのさまざまなステージで実行されます:

  • install_dotnetcore – もしまだインストールされていなければ .NET Core をインストールし、最初の実行時にパッケージ キャッシュをアップデートします。これはMicrosoftのUbuntuへの.NET Coreインストールの推奨方法です。
  • install_httpd – HTTPDデーモンとmodsをインストールし、HTTPD設定ファイルを上書きしてリバースプロキシを有効化します。
  • start_service – HTTPDサービスを再起動し、既存のASP.NETアプリケーション/サービス プロセスを再起動します。
  • scripts/stop_service – HTTPDサービスを停止し、既に実行している場合、ASP.NETアプリケーション/サービスを停止します。
  • remove_application – インスタンスからデプロイされているアプリケーションを削除します。

 

インスタンス上のcode-deploy-agentは、アプリケーションのデプロイ時にこれらのフックを実行して、サービスをインストールして開始します。イベントのアクティビティはAWS CodeDeployコンソールで監視でき、EC2インスタンスから詳細なログを取得できます。インスタンスへのSSH接続を開いたら、デプロイメントログを見るために /var/log/aws/codedeploy-agentに移動してください。

 

結論

このブログ記事では、アプリケーションのパイプラインにテストステージを追加する例を使用して、AWS CodeStarのASP.NET Core プロジェクトの構築とデプロイメントを学びました。この記事がAWS CodeStarの下で完全なCI / CDシステムを提供するために、さまざまなコンポーネントとAWSサービスがどのように相互作用するかを理解する助けになることを願っています。詳細については、AWS CodeStarユーザーガイドをご覧ください。AWS CodeStarに固有の問題が発生した場合は、AWS CodeStarのトラブルシューティング ガイドを参照してください。

 

(翻訳はSA 福井が担当しました。原文はこちらです。)

 

8 月の AWS Black Belt オンラインセミナーのご案内

【注意】セミナーの実施日程について更新がありました.最新の実施日程は,こちらをご覧ください.

こんにちは。ソリューションアーキテクトの志村です。AWS Black Belt オンラインセミナー8月の配信についてご案内させて頂きます。8月は開発者の方々に役立つ内容を多めに放送する予定です。ソリューションカットでは、デプロイをテーマにしたものと,Redshift のテーブル設計についてのものをお送りします。また今年に入って大きなアップデートがあった DynamoDB についてもお送りします。

 

8月の開催予定

 

サービスカット

8/2(水) 18:00-19:00 AWS X-ray
8/9(水) 18:00-19:00 Amazon DynamoDB
8/23(水) 18:00-19:00 AWS MobileHub
8/30(水) 18:00-19:00 AWS Key Management Service (KMS)

ソリューションカット

8/22(火) 12:00-13:00 Deployment on AWS
8/29(火) 12:00-13:00 Amazon Redshift テーブル設計詳細ガイド

お申し込みは、それぞれ上記のリンクより行って頂けます。キャンセルの際も連絡不要ですので是非お早めにご登録ください。スピーカー、スタッフ 一同みなさまのご参加をお待ちしております。

Amazon Redshift Spectrum 10 のベストプラクティス

Amazon Redshift Spectrum を使うことで、Amazon S3 に置かれたデータに対して Amazon Redshift の SQL クエリを走らせることができます。つまり Redshift Spectrum によって、データウェアハウスのローカルディスク内に保存されたデータ以外に対しても、Redshift の分析を拡張できるようになるのです。S3 の “データレイク” に貯まった大量のデータに対して、面倒で時間のかかる抽出・変換・ロード(ETL)処理を行うことなく、クエリを投げることができます。Redshift Spectrum は洗練されたクエリ最適化を用いて、数千ものノードにまでスケールして高速に処理を行います。

このブログポストでは、Redshift Spectrum の 10 の重要なベストプラクティスについて、いくつかのカテゴリにわけてご紹介します。

このガイドラインは、Redshift をお使いのお客さまとの多くのやりとりや、直接的なプロジェクトに基づいて作られています。

Amazon Redshift vs. Amazon Athena

AWS のお客さまは、私たちによく「Amazon Athena と Amazon Redshift Spectrum について、どう使い分けをすればよいのでしょうか?」と尋ねます。

Amazon Athena の利用シーン

Athena は S3 に置かれたデータに対して、SQL によるインタラクティブなアドホッククエリを投げるといったユースケースに向いています。Athena はサーバーレスアーキテクチャなので、クエリを投げるためにクラスタを立ち上げる必要はありません。クエリごとにスキャンした S3 のデータ量に基づいて料金が発生します。データを圧縮、パーティショニング、または列指向フォーマットに変換することにより、費用を節約しつつ優れたパフォーマンスを得ることができます。JDBC に対応しているすべての BI ツールや SQL クライアントから Athena を利用することができます。さらに簡単な可視化であれば Amazon QuickSight を利用することもできます。

Amazon Redshift の利用シーン

大規模な構造化データに対しては、Redshift の使用をおすすめします。Redshift Spectrum により、データを貯める場所、データのフォーマット、そして演算能力をより柔軟に活用することができます。Redshift Spectrum を使うことで、Redshift クラスターのスケーリングについて悩む必要はなくなります。ストレージとコンピュートを分離し、それぞれを独立して拡張することができるようになります。同じ S3 データレイクに対して複数の Redshift クラスターを立ち上げることで、クエリの同時実行数を増やすことができます。Redshift Spectrum は数千インスタンスにまで、自動的に拡張します。そのためテラバイト、ペタバイトそして、エクサバイトのデータに対してさえも、クエリは高速に動作します。

テスト環境の構築

Redshift Spectrum を利用するための前提条件や、開始までのステップについては、Amazon Redshift Spectrum の開始方法をご覧ください。

このブログポストでご紹介するベストプラクティスを検証するにあたって、どのようなデータでもお使いになることができます。ただひとつ大事な要件として、一番大きなテーブルについて、同じデータを 3 つのフォーマット(CSV、パーティション分けされていない Parquet フォーマット、パーティション分けされた Parquet フォーマット)に変換して S3 にファイルとしておく必要があります。どのようにファイルフォーマットを変換するかについては、このブログポストの範囲外となりますので、以下のリソースを参照してください。

外部スキーマの作成

メタデータストアとして、Athena のデータカタログを使い、以下に示すように “Spectrum” という名前の外部スキーマを作成します。

create external schema spectrum 
from data catalog 
database 'spectrumdb' 
iam_role 'arn:aws:iam::<AWS_ACCOUNT_ID>:role/aod-redshift-role'
create external database if not exists;

Redshift クラスターと S3 上のデータファイルは同じ AWS リージョンに置かれていなければいけません。また Redshift クラスターに、Athena のデータカタログと S3 上のファイルに対するアクセス権を与える必要があります。クラスターに対して、適切な IAM ロール(例えば aod-redshift-role)をアタッチします。より詳細な情報は、ステップ 1. Amazon Redshift 用の IAM ロールを作成するを参照してください。

外部テーブルの定義

例えば、パーティション分けされた parquet ファイルや CSV ファイルの Redshift Spectrum 外部テーブルは、以下のように定義されます。

CREATE  external table spectrum.LINEITEM_PART_PARQ ( 
 L_ORDERKEY BIGINT,
 L_PARTKEY BIGINT,
 L_SUPPKEY BIGINT,
 L_LINENUMBER INT,
 L_QUANTITY DECIMAL(12,2),
 L_EXTENDEDPRICE DECIMAL(12,2),
 L_DISCOUNT DECIMAL(12,2),
 L_TAX DECIMAL(12,2),
 L_RETURNFLAG VARCHAR(128),
 L_LINESTATUS VARCHAR(128),
 L_COMMITDATE VARCHAR(128),
 L_RECEIPTDATE VARCHAR(128),
 L_SHIPINSTRUCT VARCHAR(128),
 L_SHIPMODE VARCHAR(128),
 L_COMMENT VARCHAR(128))
partitioned by (L_SHIPDATE VARCHAR(128))
stored as PARQUET
location 's3://<your-bucket>/<xyz>/lineitem_partition/'
;

CREATE  external table spectrum.LINEITEM_CSV ( 
 L_ORDERKEY BIGINT,
 L_PARTKEY INT,
 L_SUPPKEY INT,
 L_LINENUMBER INT,
 L_QUANTITY DECIMAL(12,2),
 L_EXTENDEDPRICE DECIMAL(12,2),
 L_DISCOUNT DECIMAL(12,2),
 L_TAX DECIMAL(12,2),
 L_RETURNFLAG VARCHAR(128),
 L_LINESTATUS VARCHAR(128),
 L_SHIPDATE VARCHAR(128) ,
 L_COMMITDATE VARCHAR(128),
 L_RECEIPTDATE VARCHAR(128),
 L_SHIPINSTRUCT VARCHAR(128),
 L_SHIPMODE VARCHAR(128),
 L_COMMENT VARCHAR(128))
row format delimited
fields terminated by '|'
stored as textfile
location 's3://<your-bucket>/<xyz>/lineitem_csv/'

Redshift クラスターと S3 上のデータファイルは同じ AWS リージョンに置かれていなければいけません。また Redshift クラスターに、Athena のデータカタログと S3 上のファイルに対するアクセス権を与える必要があります。クラスターに対して、適切な IAM ロール(例えば aod-redshift-role)をアタッチします。より詳細な情報は、ステップ 1. Amazon Redshift 用の IAM ロールを作成するを参照してください。

クエリの実行

つまり Redshift Spectrum は、S3 に置かれたデータにクエリを投げるために、外部テーブルを用います。Redshift テーブルと同様に、 SELECT 文で外部テーブルにクエリを投げられます。外部テーブルは読み込み専用であり、書き込むことはできません。

まず、Athena や(Amazon EMR などの)Apache Hive メタストアに構築されているデータカタログを参照するために、Redshift Spectrum で外部スキーマを作成します。続いて外部スキーマに対して外部テーブルを作成します。Redshift 内にテーブルを作成・ロードしないようにするために、外部テーブルに対して SELECT 文を発行する際には、 必ず “外部スキーマ.外部テーブル” と記述する必要があります。

外部スキーマは、外部のデータカタログを参照します。そのため Redshift クラスターに対して、IAM によって S3 と Athena へのアクセス権を付与する必要があります。

Redshift Spectrum のテストを始めるにあたっては、まず以下のクエリを実行するとよいでしょう。

QUERY 1:

SELECT l_returnflag,
       l_linestatus,
       sum(l_quantity) as sum_qty,
       sum(l_extendedprice) as sum_base_price,
       sum(l_extendedprice*(1-l_discount)) as sum_disc_price,
       sum(l_extendedprice*(1-l_discount)*(1+l_tax)) as sum_charge,
       avg(l_quantity) as avg_qty,
       avg(l_extendedprice) as avg_price,
       avg(l_discount) as avg_disc,
       count(*) as count_order
FROM lineitem
WHERE l_shipdate <= '1998-09-01'
GROUP BY l_returnflag, l_linestatus
ORDER BY l_returnflag, l_linestatus;

このクエリは 1 つのテーブルだけにアクセスしており、Redshift Spectrum 層によって追加されるコンピューティングを活用できます。

QUERY 2:

SELECT  l_orderkey,
       sum(l_extendedprice * (1 - l_discount)) as revenue,
       o_orderdate,
       o_shippriority
FROM	customer, orders, lineitem
WHERE	c_mktsegment = 'BUILDING'
       AND c_custkey = o_custkey
       AND l_orderkey = o_orderkey
       AND o_orderdate < date '1995-03-15'
       AND l_shipdate > date '1995-03-15'
GROUP BY l_orderkey, o_orderdate, o_shippriority
ORDER BY revenue desc, o_orderdate
LIMIT 20;

このクエリは 3 つのテーブルを結合しており、Redshift Spectrum と素の Redshift のパフォーマンスを比較するのに向いています。

並行性に関するベストプラクティス

これらのおすすめプラクティスは、Redshift Spectrum による並行ワークロードのパフォーマンスを最適化するのに役立ちます。

1. Amazon Redshift Spectrum をスキャンインテンシブな並行ワークロード改善に活用する

Redshift Spectrum は、利用している Redshift クラスターとは独立した専用のサーバー群にあります。フィルター処理や集約処理といった、多くのコンピュートインテンシブな処理を Redshift Spectrum 層で行うことで、クエリが使用する Redshift クラスターの処理キャパシティは大きく削減されます。加えて Amazon Redshift Spectrum は賢くスケールします。MPP(Massively Parallel Processing)の利点を活かすために、Redshift Spectrum はクエリで必要な量に応じて、最大数千のインスタンスで処理を行います。

スキャンや集約インテンシブなワークロードを並行で実行するようなユースケースでは、平均的な Redshift Spectrum のパフォーマンスは、素の Redshift を上回ります。

MPP システムで最もリソースインテンシブな処理は、データロードのプロセスです。これはアクティブな分析クエリによって、コンピュートリソースだけでなく、MVCC(Multi Version Concurrency Control)によるテーブルロックによる競合が引き起こされるためです。対照的に S3 に追加され、新しいパーティションとしてメタデータも更新されたファイルを、外部テーブルを通じて Redshift Spectrum で認識する形をとることで、こうしたデータ更新のワークロードを Redshift クラスター の外に追いやることができるようになります。これはクエリの同時実行性能に対して、大きなプラスの効果をもたらします。

2. 同時実行性をスケールさせるために、複数のオンデマンド Amazon Redshift クラスターを使用する

複数の Redshift クラスターが、Redshift Spectrum 経由で S3 に保存されたデータにアクセスすることにより、並行ワークロードのパフォーマンスを改善させることができます。Redshift を使うお客さまの一般的なユースケースには、季節的なスパイクや、非常に同時実行クエリ数の多いワークロードがあります。Redshift Spectrum が登場する前は、増加する同時実行クエリ数に対処するために、お客さまはスナップショットからの復元によって、複数の “読み取り専用” Redshift クラスターを立ち上げる必要がありました。このやり方をとった場合、数百テラバイトにもおよぶデータを含む巨大な Redshift クラスターをお持ちのお客さまだと、クラスターの復元に非常に長い時間がかかるため、データレイテンシーの問題が生じてしまいました。

Redshift Spectrum の登場により、最も大きなテーブルを S3 に移動させ、Redshift クラスターには小さなサイズのデータのみを置く、という形を取れるようになりました。クラスターで保持するデータ量が減ったことにより、複数の “読み取り専用” Redshift クラスターを従来よりはるかに高速に立ち上げられるようになり、季節性のあるスパイク的なクエリワークロードに対応できるようになりました(図 1)。コストを削減するためには、ジョブが終わったらすぐに “オンデマンド” な Redshift クラスターをシャットダウンしてください。

Figure 1: 複数の “読み取り専用” Amazon Redshift クラスターからの共有 Redshift Spectrum 層へのアクセス

pgbouncer-rr をお使いいただくことで、複数の Redshift クラスターを立ち上げてクエリのルーティングを行う処理を簡単に行うことができます。詳細については以下のブログ記事を参照してください。

Query Routing and Rewrite: Introducing pgbouncer-rr for Amazon Redshift and PostgreSQL.

ストレージのベストプラクティス

ストレージの最適化を考える際には、あらゆるステップで I/O を削減することを考える必要があります。列指向フォーマットを使用する、圧縮によって各ストレージブロックにより多くのデータを詰め込む、データのパーティショニングをサポートしているファイルフォーマットを使用する、といったことが挙げられます。Redshift Spectrum でサポートされているファイルフォーマットは、CSV、TSV、Parquet、Sequence、そして RCFile です。また圧縮に関しては、Gzip、Snappy、BZ2 がサポートされています。

3. パフォーマンス向上とコスト削減のために Apache Parquet ファイルを使用する

Apache Parquet は、Apache Hadoop エコシステムのあらゆるプロジェクトで、データ処理フレームワークやデータモデル、プログラミング言語に依らず利用可能な列指向フォーマットです。詳細については、Apache Prquet の公式サイトをご覧ください。

Redshift Spectrum は、クエリ実行のために必要なカラムを含んだファイルだけを、S3 から読み出します。Redshift Spectrum はプレディケイトプッシュダウン(プレディケイトフィルタリングとも呼ばれます)をサポートしています(訳注:プレディケイトプッシュダウンとは、WHERE 句や GROUP BY 句などの処理を効率的に行うための手法です。例えば GROUP BY に対するプレディケイトプッシュダウンでは、各リーダーで読み込んだデータについて、全データで GROUP BY を行う前に、各ワーカー内であらかじめ GROUP BY をしておき、その結果を集約ワーカーに転送する、といったプロセスをとります。各ワーカーで先に集約を行うことでデータの転送コストが下がり、結果的にパフォーマンスが向上します。このように、クエリの実行パイプラインの最後で行う処理を、効率化のためにあらかじめ各プロセスでおこなっておく(= プッシュダウン)のが、プレディケイトプッシュダウンの役割となります)。

Redshift Spectrum は、クエリ単位で S3 からスキャンしたデータ量ごとに課金されます。Parquet フォーマットは列指向フォーマットでデータを保持するため、Redshift Spectrum は不必要なカラムを除いた形でスキャンを行うことができます。例として、CSV 形式のテキストファイルと、パーティション分けされた Parquet ファイルのクエリパフォーマンスの違いをみてみるとよいでしょう。

Parquet ファイルの利用によって、パフォーマンスが向上するだけでなく、パーティション分けされていない行指向の CSV ファイルよりはるかにコスト効率がよくなることが、さまざまな検証によって示されています。

SVL_S3QUERY_SUMMARY テーブルを調べることで、パーティション分けされた Parquet ファイルを使う際の、S3 に関するさまざまな興味深いメトリクスを確認することができます。

select * from SVL_S3QUERY_SUMMARY where query=<Query-ID>;

s3_scanned_rowss3query_returned_rows という 2 つのメトリクスに、特に注目してみましょう。CSV ファイルを処理するときと比べて、Redshift Spectrum から Redshift クラスターに送られるデータ総量が驚異的に削減されていることがわかります。

4. 頻繁に使われるカラムをパーティションとした Parquet ファイルをつくる

パーティションとして利用する最適なカラムを決める際には、以下の点に注目しましょう

  • フィルタとして頻繁に使われるカラムは、パーティションカラムの良い候補と考えられます
  • 過度に細かいパーティショニングは、パーティションの情報を取得するのに時間を要します。一方で、必要なパーティションの選択により、S3 からスキャンするデータを減らすのに役立ちます
  • 実際のパフォーマンスは、ファイルの置き方、クエリのパターン、ファイルサイズの分布、ひとつのパーティションに含まれるファイル数、対象となるパーティション数などによって異なります
  • パーティションカカラムの偏りを避けましょう
  • ファイルサイズの分布ができる限り均等になるようにしましょう。つまり、すべて 256MB の Parquet ファイル 10 個の方が、1GB 超のファイル 1 個と 256MB のファイル 6 個より望ましいということです

パーティションによる枝借りが素晴らしい効果を発揮するのを確認するために、2 つの外部テーブルを Parquet ファイルで作成してみましょう。ひとつはパーティション分けされていないもの、もうひとつは日単位でパーティション分けされているものです。

パーティション分けされた外部テーブルは、そうでないものより 2-4 倍程度高速にスキャンできます。

“パーティションの枝借り” の効果をどのように確認すれば良いでしょうか。以下に示す SQL を用いることで、パーティションの枝借りの効果を分析することができます。クエリが数個のパーティションにのみアクセスするような場合には、期待通りの効果が得られていることを確認することができます。

SELECT query,
	segment,
	max(assigned_partitions) as total_partitions,
	max(qualified_partitions) as qualified_partitions 
FROM svl_s3partition 
WHERE query=<Query-ID>
GROUP BY 1,2;

クラスター設定のベストプラクティス

5. 正しい Redshift のクラスター設定により Redshift Spectrum のパフォーマンスを最適化する

Redshift Spectrum クエリの同時実行性能は、以下の 2 つのレベルで制御することが可能です

  • クエリレベル(クエリごと 1 スライスにつき最大 10 の同時実行数)
    • いくつのクエリが同時に実行されているかによって、同時実行数が変わる
    • 割りあてられた同時実行数によって、S3 をスキャンするスレッド数が制限される
  • ノードレベル(ノード状で動作するすべての S3 をスキャンするクエリに適用される。ノードタイプによって数が異なる)
    • より大きなノードタイプを選択するほど、上限数も高くなる

ファイル総数 <= クエリごとの同時実行性能 (例えば 10) * クラスターのスライス数、といった簡単な計算ができます。。ただしクラスターのノード数を増やしても、必ずしもパフォーマンスが向上するとは限りません。最適なクラスターのノード数は、以下のようにして決めてください。まず Redshift Spectrum の外部テーブルに、いくつのファイルが含まれているかを確認してください。続いてクラスターのサイズを大きくしていって(クラスターに含まれるスライス数を増やすということです)、ノード数が増えてもパフォーマンスがこれ以上伸びなくなるというポイントを探してください。そのときのノードタイプにおける、最適な Redshift のクラスターサイズは、それ以上のパフォーマンス向上が起こらなくなるところです。

クエリパフォーマンスのベストプラクティス

S3 に対するクエリのパフォーマンスを改善するための、簡単な方法をいくつかご紹介します。

6. Redshift Spectrum でスキャン・集約インテンシブなクエリを実行する

Query 1 のように結合処理が含まれないクエリでは、物理的な I/O のコストがスキャン速度の大半を占めます。これらのクエリでは、Redshift Spectrum は素の Redshift よりも高速に動作します。その一方で複数の結合処理が含まれる Query 2 のようなクエリでは、ローカルストレージ上できちんと最適化されている素の Redshift テーブルの方が、当然よいパフォーマンスを発揮します。

7. プレディケイトプッシュダウンによって S3 に対するクエリのパフォーマンスを改善する

Redshift Spectrum 層で行われる処理(S3 に対するスキャン、カラム抽出、フィルタリング、集約)は Redshift クラスターとは独立して行われます。もちろん Redshift クラスターのリソースを消費することはありません。

SQL に含まれるある種の処理は Redshift Spectrum 層にプッシュダウンすることができ、可能な場合は常にその恩恵を受けることができます。例えば以下のような処理が挙げられます。

  • GROUP BY 句と、いくつかの文字列関数
  • イコール 条件や LIKE のようなパターンマッチング条件
  • COUNT、SUM、AVG、MIN、MAX、その他の一般的な集約関数
  • regex_replace やその他の関数

DISTINCTORDER BY といった演算子は、Redshift Spectrum にプッシュダウンすることができないため、Amazon Redshift で実行されます。可能ならば、これらの処理の利用を最小化するか、もしくは利用を避けるのが望ましいです。

次に示す 2 つのクエリを実行してみると、両者の間でパフォーマンスが大きく異なることがわかります。なぜでしょうか?

Select MIN(L_SHIPDATE), MAX(L_SHIPDATE), count(*)
	from spectrum.LINEITEM_NPART_PARQ;
Select MIN(DATE(L_SHIPDATE)), MAX(DATE(L_SHIPDATE)), count(*)
        from spectrum.LINEITEM_NPART_PARQ;

最初のクエリの実行計画では、S3 データに対する集約処理が Redshift Spectrum にプッシュダウンされ、集約された結果のみが Redshift に送られます。

一方、2 つめのクエリの実行計画では、Redshift Spectrum が DATE 型を標準のデータ型としてサポートしていないことや、DATE 変換関数をサポートしていないことによって、Redshift Spectrum 層でS3 データに対する集約処理がまったく行われません。結果として S3 から読み出された大量のデータが、Redshift 上で変換処理を行うために送られてくることになります。

また、SVL_S3QUERY_SUMMARY システムビュー(の s3query_returned_rows カラム)に対して、2 つの SQL ステートメントの詳細を確認するクエリを投げることもできます。クエリの結果をみると、Redshift Spectrum から Redshift に送られる行数が両者で大きく異なっていことがわかるでしょう。

8. DISTINCT を GROUP BY で置き換える

GROUP BYMIN/MAX/COUNT といった演算子は、Redshift Spectrum 層に処理をプッシュダウンすることができます。その他の DISTINCTORDER BY のような SQL 演算子は、プッシュダウンできません。一般的に、Redshift Spectrum 層にプッシュダウン可能なすべての演算子は、Redshift Spectrum が動作するパワフルなインフラにより、プッシュダウンによるパフォーマンスの向上が期待できます。

例えば、以下の 2 つの機能的に等価な SQL ステートメントを試してみましょう。

SELECT DISTINCT l_returnflag,
        l_linestatus 
FROM 	spectrum.LINEITEM_PART_PARQ 
WHERE 	EXTRACT(YEAR from l_shipdate::DATE) BETWEEN '1995' AND  '1998' 
ORDER BY l_returnflag, l_linestatus
;


SELECT l_returnflag,l_linestatus 
FROM 	spectrum.LINEITEM_PART_PARQ 
WHERE EXTRACT(YEAR from l_shipdate::DATE) BETWEEN '1995' AND  '1998' 
GROUP BY l_returnflag, l_linestatus 
ORDER BY l_returnflag, l_linestatus
;

ひとつめのクエリでは(DISTINCT 演算子のせいで)プッシュダウンが行われません。そのため Redshift 上でソートおよび重複除去を行うために、大量のレコードが送られます。ふたつめのクエリでは、重たい処理や集約の大半を行う HashAggregate が Redshift Spectrum で行われます。SVL_S3QUERY_SUMMARY にクエリを投げることで、実行計画の違いを確認することができます。

ここでの学びは、可能なときは常に “DISTINCT” を “GROUP BY” で置き換えるべきだということです。

テーブル配置のベストプラクティス

このシンプルなガイドラインでは、最高のパフォーマンスを得るためのテーブルの置き方について述べます。

9. 大きなファクトテーブルを S3 におき、それ以外を Redshift で持つ

Query 2 では、3 つのテーブルに対して結合処理を行っています。自然な疑問として「もし 3 つのテーブルすべてを、パーティション分けした Parquet ファイルとして、S3 においたらどうなるでしょうか?」と思うでしょう。素の Redshift に 3 つのテーブルがすべて置かれているときと比べて、パフォーマンスは良くなるでしょうか、それとも悪くなるでしょうか?

結合処理に対して最適化を行なった(適切な分散キー、ソートキーを設定済みの)Redshift テーブルは、Redshift Spectrum よりも高いパフォーマンスを発揮します。Redshift Spectrum の外部テーブルは、統計情報をサポートしていません

データベースエンジンはヒューリスティクス、もしくは単純な行数カウントによって結合の順番を決定します。この方法だと、必ずしも最適なパフォーマンスは得られません。AWS では、最も大きいファクトテーブルのみを S3 上に置いて、それ以外の小中規模のディメンジョンテーブルは Redshift に持つことを推奨しています。この場合に、オプティマイザーのヒューリスティクスが最もうまく働きます。

CREATE EXTERNAL TABLE および ALTER TABLE コマンドでは、TABLE PROPERTIES 節の中で (numRows) をテーブル統計情報として設定することができます。この情報によって、オプティマイザーがより良い実行計画を生成するのを手助けすることができます。より詳細な情報については、Redshift のドキュメント内の CREATE EXTERNAL TABLE を参照してください。

少なくとも 3 つのテーブルの結合処理を含むクエリを、それらが正しい順番で結合されるように記述してみてください(Explain 文で確認することができます)これによって、 Redshift Spectrum では複数テーブルの結合を行なってはいけない、といった間違った考えに陥らないようにすることができます。

10 頻繁に結合処理の対象となる大きなテーブルを S3 上に置くときに注意する

素の Redshift は Query 2 のようなクエリについて、大概の同時実行クエリ数において、Redshift Spectrum より約 3 倍のパフォーマンスを発揮します。Query 1 と 2 の違いは、Query 1 では 1 テーブルに対する集約処理しか行なっていないのに対して、Query 2 では 3 つの比較的大きなテーブルの結合処理が含まれている点です。

より明確に言うとすれば、このようなパフォーマンスの違いが生じるのは、結合処理が Redshift の中で行われているためです。結合に必要なデータはまず S3 から読み込まれ、そして Redshift クラスターの各スライスに転送される必要があります。その結果、Redshift のローカルストレージにアクセスするのと比べて、Redshift Spectrum 経由の場合は非常に高いレイテンシーが発生します。

そのため、大きな Redshift テーブルに対して結合を頻繁に行い、かつクエリのワークロードに対して厳しい SLA が設定されている場合には、これらのテーブルを S3 に置くべきではありません。

結論

このブログポストでは、Redshift Spectrum のパフォーマンスを改善するための重要なベストプラクティスについて述べてきました。もちろん各ユースケースで異なる点があるため、ここで示したおすすめの方法をどの程度取り入れるかについて、考える必要があります。

原文: 10 Best Practices for Amazon Redshift Spectrum (翻訳: SA志村)

Amazon Redshiftクエリーモニタリングルールでクエリーワークロードを管理する

データウェアハウスのワークロードは多様性で知られています。これは、季節性や、往々にして高コストになりがちな探索的クエリー、SQL開発者のスキルレベルのばらつきなどによるものです。

Amazon Redshiftワークロード管理機能(WLM)を用いて優先度やリソース使用量を柔軟に管理することで、極めて多様なワークロード環境でも高い性能を得ることが可能となります。WLMによって、短時間で完了するクエリーが長時間実行されるクエリーのせいでキューに滞留するような状況を避けることができます。にも拘わらず、あるクエリーが不釣り合いな量のリソースを独占し、システム内のその他のクエリーを圧迫することが依然として起こり得ます。こうしたクエリーは、一般にrogue queryやrunaway queryと呼ばれます(訳者註:rogueはならず者、面倒を起こすといった意味、runawayは暴走の意で、ここでは一方的にリソースを占有し他のクエリーに影響を及ぼすクエリーを指します)

WLMは、メモリー使用量を制限し、タイムアウトを用いてクエリーを別のキューに移動させる機能を持ちますが、ずっと粒度の細かいコントロールができることが望ましいことは論を俟ちません。クエリーモニタリングルールを用いて、リソース使用量のルールを作成し、クエリーのリソース使用量を監視し、それらがルールを犯した時のアクションを決めることが可能になりました。

ワークロード管理における同時並列性とクエリーモニタリングルール

Amazon Redshift環境では、単一クラスターに対し最大500まで同時接続することができます。性能指標であるスループットは一般に一時間あたりのクエリー数として表現されますが、MySQLのような行指向データベースであれば、同時接続数を増やすことによってスケールします。Amazon Redshift環境では、ワークロード管理(WLM)によって、同時接続数とは異なる方法でスループットを最大化します。WLMは二つの部分があります。キューと同時並列性です。キューはユーザーグループまたはクエリーグループのレベルでのメモリー割り当てを可能にします。同時並列性(またはメモリースロット)は、この割り当てをさらにどのように分割し、個々のクエリーにメモリーを割り当てるかを制御します。

例えば、同時並列性10の1つのキューがある(メモリー割り当て100%)と仮定しましょう。これは、個々のクエリーは最大10%のメモリーの割り当てを受けることを意味します。もしクエリーの大半が20%メモリーを必要とした場合、これらのクエリーはディスクにスワップアウトし、スループットの劣化をもたらします。しかし、もし同時並列性を5に下げた場合、個々のクエリーは20%のメモリー割り当てを受けることができるため、トータルのスループットは高くなり、SQLクライアントへのレスポンスも全体的に高速になります。高い同時並列性がよりよいパフォーマンスに繋がると考えてしまうことは、行指向のデータベースを列指向に切り替える時に陥りがちな典型的な落とし穴の一つです。

同時並列性について理解したところで、クエリーモニタリングルールについて掘り下げていきましょう。リソース使用量に基づくルールと、それに違反した場合に取るアクションを定義します。当該クエリーによるCPU使用量、クエリー実行時間、スキャンされた行数、返された行数、ネステッドループ(Nested loop)結合など、12の異なるリソース使用量メトリクスを利用できます。

それぞれのルールは最大3つの条件(述語)と、一つのアクションを持ちます。

述語は、メトリック、比較演算子(=、<または>)、値で構成されます。あるルール内の全ての述語がマッチすると、そのルールのアクションがトリガーされます。ルールアクションには、ログ(記録)、ホップ(次のキューへの移動)、アボート(終了)があります。

これにより、はた迷惑なクエリーを、より深刻な問題が出来する前に捕捉することが可能になります。ルールはアクションをトリガーしてキューを解放し、スループットと応答性を改善します。

例えば、短時間実行クエリー専用のキューのために、60秒を超えて実行し続けるクエリーをアボートするルールを作ることができます。設計のよくないクエリーを追跡するために、ネステッドループを含むクエリーを記録する別のルールを作ることもできます。Amazon Redshiftコンソールには、簡単に始められるよういくつかのテンプレートが事前定義されています。

シナリオ

クエリーモニタリングルールを使って、単純なロギングからクエリーのアボートまで、幅広いクエリーレベルアクションを行うことができます。また、全てのアクションはSTL_WLM_RULE_ACTIONテーブルに記録されます。

それでは、以下の三つのシナリオを用いて、クエリーモニタリングルールをどのように使うかを見ていきましょう。

シナリオ1:アドホッククエリーに潜む非効率なクエリーを制御するには?

二つの大きなテーブルを結合するようなクエリーは、何十億、あるいはそれ以上の行を返す可能性があります。十億行を超える行を返すクエリーをアボートさせるルールを設定することで、アドホッククエリーの安全性を担保することができます。このルールは、論理的には以下のようになります。

IF return_row_count > 1B rows then ABORT

以下のスクリーンショットの設定では、十億行を超える行を返すBI_USERグループ内のクエリーはすべてアボートします。

シナリオ 2: 非効率で、CPUインテンシブなクエリーを制御するには?

CPUスパイクをもたらすクエリーが、必ずしも問題というわけではありません。しかし、高いCPU使用量と長いクエリー実行時間を併せ持ったクエリーは、実行中の他のクエリーのレイテンシーを悪化させます。例えば、高いCPU使用率を示し続ける非効率なクエリーが長時間実行されている場合、それは誤ったネステッドループ結合のせいかも知れません。

こうしたケースでは、10分間にわたって80%以上のCPU使用率を示しているクエリーをアボートさせるルールを作成することで、クラスターのスループットと応答性を上げることができます。このルールは、論理的には以下のようになります。

IF cpu_usage > 80% AND query_exec_time > 10m then ABORT

以下のスクリーンショットの設定では、10分間にわたってCPU使用率が80%を超えているクエリーはすべてアボートします。

80%以上のCPU使用率を5分以上続けるクエリーを記録し、10分以上続いた場合はアボートするよう、ルールを拡張することもできます。このルールは、論理的には以下のようになります。

IF cpu_usage > 80% AND query_exec_time > 5m then LOG and IF cpu_usage > 80% AND query_exec_time > 10m then ABORT

以下のスクリーンショットの設定では、5分間にわたってCPU使用率が80%を超えているクエリーは記録され、10分間にわたってCPU使用率が80%を超えているクエリーはすべてアボートします。

シナリオ 3:

進捗していないクエリーを監視し、記録するには?

例えば、ミックスワークロード環境では、ETLジョブがS3から大量のデータを抽出し、Amazon Redshiftにロードしているケースがあります。データ抽出中、キューでスタックして、全く進捗していないように見えるCOPYコマンドが見つかるかも知れません。このようなクエリーはデータ抽出を遅延させ、ビジネス上のSLAに悪影響を与える可能性もあります。

クエリーを追跡し記録するルールを作ることで、こうしたクエリーを捕捉することができます。低いCPU使用率のまま長時間実行されているクエリーを見つけ出すルール、例えば1%のCPU使用率で10分間動作しているようなクエリーを記録するルールを作成します。このルールは、論理的には以下のようになります。

IF cpu_usage < 1% AND query_exec_time > 10m then LOG

以下のスクリーンショットの設定では、10分間にわたってCPU使用率が1%未満であるクエリーが記録されます。

まとめ

Amazon Redshiftは強力かつフルマネージドなデータウェアハウスであり、高いパフォーマンスと低いコストの双方をクラウド上でご提供します。しかしながら、クラスターリソースを独り占めするクエリー(rogue queries)はユーザーエクスペリエンスに悪影響を及ぼします。

このポストでは、クエリーモニタリングルールがこの種のクエリーにどのように対処可能かを見てきました。これらの内容は、ミックスワークロード環境でのクラスター性能とスループットを最大化し、円滑なビジネス遂行を実現する上で役立つはずです。

ご質問やご提案がありましたら、以下にコメントを残していただけますと幸いです。

(翻訳はAWS Japanプロフェッショナルサービス仲谷が担当しました。原文はこちら

DynamoDB Accelerator (DAX) が正式にサービス開始しました

今年の初め頃 Amazon DynamoDB AcceleratorDAX)について紹介をしました。DAXはフルマネージドのキャッシュサービスでDynamoDBテーブルの前段(論理的に)に置かれます。DAXはキャッシュされたデータに対するリクエストをマイクロ秒単位で返すため、読み込みワークロードに最適です。DAXはアプリケーションコード内ではDynamoDB APIと互換性を保つ様にサポートしており、シームレスで使いやすいようにデザインしています。管理することはDAXクラスタを作成して既存の読み取りと書き込みのターゲットとして使用するだけです。パッチ適用、クラスタメンテナンス、キャッシュデータの複製、または障害管理について心配する必要はありません。

本日から利用可能
今日DAXが正式に利用可能になったことをお知らせします。DAXが利用可能なAWSリージョンを追加拡張し、プレビューの期間にパフォーマンスと可用性をチューニングしました。

5つのリージョンで利用可能 – 現在 DAXはUS East (Northern Virginia)、EU (Ireland)、US West (Oregon)、Asia Pacific (Tokyo)、US West (Northern California) の5つの地域で利用可能です。

In Production – プレビュー期間内にDAXを本番で使用しているユーザーもおり、DAXをアプリケーションに追加するのが楽で今ではアプリケーションの速度が10倍速くなってたという声を頂いています。

Getting Started with DAX
以前の記事(翻訳版はこちら)で紹介したように、DAXを使用して既存のDynamoDBアプリケーションを高速化するのは簡単です。必要なリージョンにDAXクラスタを作成し、 DAX SDK for Javaを利用するようにアプリケーションを更新します(コード内の呼び出し方は同じですが、ライブラリの置き換えを行う事です)。SDKを構成してクラスタにエンドポイントを使用するようにします。リードスルー/ライトスルーキャッシュとして、DAXはすべてのDynamoDB読み取り/書き込みAPIをシームレスに処理します。

私たちは他の言語のSDKのサポートも取り組んでおり、利用可能になった時点で追加情報を共有します。

価格について

US East (Northern Virginia) と US West (Oregon) の各地域で、時間あたり$ 0.269から始まる料金
でクラスター内の各ノード(詳細については、 DynamoDBの価格を参照)を1時間単位でお支払いいただきます。DAXでは、クラスタ内の各ノードが高可用性のための読み取りターゲットおよびフェールオーバーターゲットとして機能します。DAX SDKはクラスタを認識しており、クラスタ内のすべてのノードに対してラウンドロビンで要求を発行し、クラスタのキャッシュリソースを最大限に活用できるようにします。

DAXは読み取りトラフィックの急激な急上昇を容易に処理できるため、テーブルのプロビジョニングされたスループットの量を減らすことができ、結果としてマイクロ秒で結果を返しながら全体のコストを削減できます。

最後にAmazon.comのCTOであるWerner Vogelsが書いたブログを紹介させて頂きます。

Amazon DynamoDB Accelerator (DAX): Speed Up DynamoDB Response Times from Milliseconds to Microseconds without Application Rewrite.

Tinder、Careem、そしてCanon INC. の事例についてもご紹介していますので、ぜひご覧ください。

Jeff;

(翻訳はSA成田が行いました。原文はこちら

7 月の AWS Black Belt オンラインセミナーのご案内

こんにちは。ソリューションアーキテクトの岡本です。AWS Black Belt オンラインセミナー 7 月の配信についてご案内させて頂きます。今月はAmazon Connect, AWS Shield, AWS Step Functions と Black Belt 初開催となるサービスの紹介が多く予定されておりますので、是非とも最新情報の習得にお役立ていただければと思います。またその他にも AWS Lambda, AWSの運用監視といった実用的な技術情報をお届けいたします。

サービスカット
7/5(水) 18:00-19:00 Amazon Connect
7/18(火) 12:00-13:00 AWS Shield   ※ 通常の開催日時と異なりますのでご注意ください
7/19(水) 18:00-19:00 AWS Lambda
7/26(水) 18:00-19:00 AWS Step Functions

ソリューションカット
7/25(火) 12:00-13:00 Monitoring on AWS -AWS運用監視-

お申し込みは、それぞれ上記のリンクより行って頂けます。キャンセルの際も連絡不要ですので是非お早めにご登録ください。Speaker、Staff 一同みなさまのご参加をお待ちしております。

Amazon EC2 スポットインスタンスを利用した Amazon ECSクラスターの起動

この記事は気前よく次の方から寄贈されました。

Chad Schmutzer, Solutions Architect Shawn O'Conner, Enterprise Solutions Architect
Chad Schmutzer
Solutions Architect
Shawn O’Connor
Solutions Architect

 

本日、Amazon EC2 Container Service(Amazon ECS)が、ECSコンソール上から直接 Amazon EC2 Spot Instances上に ECSクラスターを起動させる機能をサポートする事を発表しました。

スポットインスタンスを利用すると、Amazon EC2の余剰コンピュートキャパシティに入札することが出来ます。スポットインスタンスは通常、オンデマンドインスタンスよりも50-90%安い価格です。スポットインスタンス上でECSクラスターを起動することで、既存のコンテナ化されたワークロードの実行コストを削減したり、同じ予算を維持しながら、コンピュートキャパシティを2倍から10倍に増やすことが可能です。もしくは、その両方を実現することもできます!

スポットインスタンスを利用する場合、インスタンス時間あたりに支払う価格を指定します。現在のスポットプライスを上回る価格で入札している間、スポットインスタンスは起動します。スポットプライスの上昇によりインスタンスが回収された場合、インスタンスが実行された分の時間は請求されません。

ECSコンソールはスポットインスタンスをデプロイするために、 Spot Fleetを利用します。Spot Fleetは、利用者にとって最も良い価格となる様にスポットインスタンスを起動し、コンテナ化したアプリケーションの為にリクエストしたターゲットキャパシティ(インスタンスやvCPUの数で表現される)をデプロイしようします。スポットプライスや、空き容量の変化によってスポットインスタンスが回収された場合、Spot Fleetはターゲットキャパシティを維持しようとします。

コンテナはSpot Fleetが大きくなる多様なリソースプールに適してします。Spot Fleetを利用すると複数のスポットインスタンスプール(インスタンスタイプとアベイラビリティゾーンの組み合わせ)に渡ってキャパシティをプロビジョニング出来き、アプリケーションの可用性を向上させ、時間経過と共に運用コストを削減できます。ECSが提供する拡張性と柔軟性を備えたコンテナ配置システムとSpot Fleetとの組み合わせはコンテナ化されたワークロードを効率的にデプロイし、わずかなコストであらゆる規模のクラスタを容易に管理できます。

従来は、スポットインスタン上へのECSクラスタのデプロイは手動で行われてました。この記事では、ECSコンソール上からのSpot Fleetとの新しいインテグレーションによって、高い可用性とスケーラビリティをどの様に実現し、コンテナ化したワークロードをどの様にコストを削減するのかを紹介します。また、AWS CloudFormationを利用し、スポットインスタンス上にECSクラスターを構築する方法も紹介します。

 

スポットインスタンスで実行するECSクラスタの作成

AWS マネージメントコンソールを利用してECSクラスタを作成することが可能です。

  1. Amazon ECSコンソールを開きます。 https://console.aws.amazon.com/ecs/
  2. ナビゲーションパネル上でClustersを選択します。
  3. Clustersページでは、Create Clusterを選択します。
  4. Cluster nameに名前を入力します。
  5. インスタンス設定では、プロビジョニングモデルとしてSpotを選択します。

ECS Create Cluster - Spot Fleet

配置戦略の選択

2つの利用可能なSpet Fleet配置戦略はDiversified戦略かLower price戦略です。

ECS Spot Allocation Strategies

Spot Fleetで選択した配置戦略は、利用可能なスポットインスタンスプールからSpot Fleetをどの様に満たすかを決定します。diversified戦略を使用すると、スポットインスタンスは全てのプールにわたって分散されます。lowest price戦略を選択した場合、リクエストで指定された最低価格のプールから取得されます。

各インスタンスタイプ(各インスタンスファミリ内のインスタンスサイズ、例えばc4.4xlarge)、各アベイラビリティゾーン、各リージョンで、キャパシティで別れたプールであり、別々のスポットマーケットであることに注意してください。可能な限り異なったインスタンスタイプとアベイラビリティゾーンにまたがって多様にすることで、fleetの可用性を向上することができます。また、時間の経過とともにスポットプライスが上昇することに対しての反応を低くすることができます。

Spot Fleet Market

Spot Fleetに利用するインスタンスタイプを6種類まで選択可能です。この例では、m3,m4,c3,c4,r3,そしてr4のxlargeを選択しています。

Spot Instance Selection

インスタンスの為に入札価格を入力する必要があります。一般的には、オンデマンドインスタンス価格かそれに近い価格で入札するが良い出発点です。そのスポットプールのインスタンスタイプに支払うつもりがある最大価格が入札価格になります。スポット価格が入札価格と同じ、または下回っている間、スポット価格を支払います。低い価格での入札はコストを低減させ、高い価格での入札はインスタンスの中断の確率を下げます。

クラスターに所属するインスタンスの数を設定します。Spot Fleetはリクエストで特定されたターゲットキャパシティを満たす様にスポットインスタンスを起動しようとします。

最新のECS最適化AMIがSpot Fleetがインスタンス時に使用されます。

ストレージとネットワークの設定を行います。多様性と高可用性を実現する為に、複数のアベイラビリティゾーンとなる様にsubnetを選択する様にします。singleのSpot Fleetでは、同じアベイラビリティゾーンにある複数のサブネットを選択する事はできません。

ECSコンテナエージェントがECSのAPIをコールします。エージェントが実行されるコンテナインスタンスはに、エージェントの所有者を知るためにecsInstanceRole IAMポリシーとロールが必要です。

Spot Fleetを利用するマネージドコンピュート環境を作成した場合、入札、起動、インスタンスの終了するためのSpot Fleet権限を付与したロールを作成しなくてはなりません。このロールはECSコンソールから作成できます。

ECSコンソールでの作用はこれだけです!Spot Instance上で稼働するるECSクラスターを起動する為に作成を選択してください。

スポットインスタンス上で稼働するECSクラスターのデプロイにAWS CloudFormationを利用する

リファレンスアーキテクチャとなるAWS CloudFormationテンプレートを公開しています。このテンプレートはCloudFormationスタックの起動や、スポットインスタンス上でのECSクラスタのデプロイがどれくらい簡単をデモンストレーションします。

CloudFormationテンプレートには 以前投稿したSpotインスタンスの終了通知スクリプトだけではなく、いくつかの追加のロギングやその他のサンプル機能が含まれています。Amazon EC2 Spot Instance GitHub上のレポジトリからCloudFormationテンプレートを見つけることができます。

環境に応じてカスタマイズを実施して試してみてください!

Spot Fleet Architecture

終了のハンドリング

スポットインスタンスでは、指定した価格以上を支払う必要はありません。もしスポット価格があるインスタンスで入札を上回った場合、そのインスタンスは自動的に終了されます。

スポットインスタンスの終了を防ぐための最も良い方法は、コンテナ化されたアプリケーションをフォールトトレラントなアーキテクチャにすることです。加えて、スポットインスタンスの終了通知機能を利用することもできます。それはEC2がスポットインスタンスを終了する前に2分間の警告を提供します。

この警告は、インスタンスメタデータ内の項目を使用して、スポットインスタンス上のアプリケーションで使用可能になります。コンソールを利用してスポットインスタンス上にECSクラスターをデプロイした場合、AWSはインスタンス終了通知を5秒毎に確認するスクリプトをインストールします。通知を検知した場合、スクリプトはコンテナインスタンスの状態をDRAININGにただちにに更新します。

簡略したバージョンのスポットインスタンス終了通知は次の様になります。

#!/bin/bash

while sleep 5; do
  if [ -z $(curl -Isf http://169.254.169.254/latest/meta-data/spot/termination-time) ]; then
    /bin/false
  else
    ECS_CLUSTER=$(curl -s http://localhost:51678/v1/metadata | jq .Cluster | tr -d \")
    CONTAINER_INSTANCE=$(curl -s http://localhost:51678/v1/metadata \
      | jq .ContainerInstanceArn | tr -d \")
    aws ecs update-container-instances-state --cluster $ECS_CLUSTER \
      --container-instances $CONTAINER_INSTANCE --status DRAINING
  fi
done

コンテナインスタンスをDRAININGにセットすると、ECSによって、新しいタスクのコンテナインスタンスへの配置がスケジュールされなくなります。リソースが利用可能な場合、代替サービスタスクはクラスター内の別のコンテナインスタンスで開始されます。コンテナインスタンスのドレイニングにより、クラスタ内のタスクに影響を与えない様にクラスターからコンテナインスタンスを削除することができます。PENDING状態にあるコンテナインスタンス上のサービスタスクは直ちに停止します。

コンテナインスタンス上でRUNNING状態にあるサービスタスクは停止し、サービスデプロイ設定パラメータであるminimumHealthyPercentとmaximumPercentに従い、再配置されます。

実際のスポットインスタンス上のECS

どの様にお客様がスポットインスタンス上でECSクラスターをすでに起動しているか知りたいですか?Mapboxにいる友人はこの様にしています。

Mapboxはカスタムマップをデザインし、公開するためのプラットフォームです。同社はマップを作成する為に1日に1億マイルを超えるセンサーデータの収集と実行するバッチプロセッシングアーキテクチャー全体の実行にECSを利用しています。彼らはスポットインスタンスを使用したECSを利用することでバッチプロセッシングアーキテクチャを最適化しています。

Mapboxプラットフォームは5000を超えるアプリケーションを起動し、各月で2億ユーザ以上に達しようとしています。それらのバックエンドはECS上で動いていて、1日あたり13億リクエスト以上を処理しています。Mapbox社の最近のECSへのマイグレーションについてより学びたい場合は、同社のブログである、We Switched to Amazon ECS, and You Won’t Believe What Happened Next. を読んでください。そして、フォローアップ記事である、 Caches to Cashでは、EC2のコストを50-90%節約しながら、同社がスポットインスタンス上でどの様にプラットフォーム全体を動かしているのかを学んでください。

結論

スポットインスタンスを利用してスケールし、コスト効率よくコンテナ化したアプリケーションを動かす事について、私たちと同じ様に読者の方も興奮している事を願います。さらなる情報については、次のページを確認してください。

コメントや提案があるかたは下記よりコメントをください。

原文:Powering your Amazon ECS Cluster with Amazon EC2 Spot Instances(翻訳:SA浅野)
 

AWS が 7 年連続でガートナーのサービスとしてのインフラストラクチャ (IaaS) に関するマジッククアドラントでリーダーとして認定される

AWS での各製品計画セッションはお客様を中心に進められています。当社は最善を尽くしてお客様の声に耳を傾け、それに基づいて将来の開発のロードマップを構築しています。ロードマップの項目の約 90% はお客様のリクエストに基づくものであり、お客様から寄せられた特定のニーズや要件を満たすよう設計されています。

このお客様主導のイノベーションにより、7 年連続でガートナーのサービスとしてのインフラストラクチャ (IaaS) に関するマジッククアドラントで当社が「リーダー」クアドラントで最上位の地位を確保し、最も高い実行力と先見性のあるビジョンを持っていると評価されたものと確信しています。

詳細については、レポートの全文をお読みください。このレポートには多くの詳細が含まれており、お客様がクラウドプロバイダーを選ぶときに確認する機能や要素がよくまとめられています。

Jeff;

新機能 – Auto Scaling for Amazon DynamoDBについて

Amazon DynamoDBには幅広い業界やユースケースを含む10万人以上の多くのお客様がいます。 お客様は世界中の16の地域で、DynamoDBの一貫性のあるパフォーマンスを利用する事が出来ます。 最近の傾向は、DynamoDBを使用してサーバレスアプリケーションと組み合わせるお客様です。 この使い方は非常にマッチします:DynamoDBでは、サーバーのプロビジョニング、OSとデータベースのソフトウェアパッチ適用、または高可用性を確保するためのAZゾーン間のレプリケーションの設定などを考える必要はありません。テーブルを作成してデータを追加するだけでDynamoDBが処理するようにします。

DynamoDBにはプロビジョニングキャパシティーユニットモデルが用意されており、アプリケーションで必要とされる読み書き容量を設定できます。 これによりサーバの考え方から解放され、簡単なAPIコールまたはAWS Management Consoleのボタンをクリックしてテーブルのプロビジョニングを変更できるようになりましたが、多くのお客様はDynamoDBの容量をさらに簡単に管理できるように望んでいました。

本日、DynamoDBのAuto Scalingを導入して、テーブルとグローバルセカンダリインデックス(GSI)の容量管理を自動化できるようになりました。 維持をしたい使用率を指定し、読み書き容量の上限と下限を指定するだけです。 DynamoDBは、Amazon CloudWatchアラームを使用して消費量を監視し、必要に応じてプロビジョニングされた容量を調整します。 Auto Scalingは、すべての新しいテーブルとインデックスに対してデフォルトでオンに出来ます(但しIAM権限の事前準備が必要です)。また、既存のテーブルやインデックスに対しても設定できます。

あなたが常にマネジメントコンソールに張り付いていなくても、DynamoDB Auto Scalingはテーブルとインデックスを監視して、アプリケーショントラフィックの変化に応じて自動的にスループットを調整します。 これによりDynamoDBデータの管理が容易になり、アプリケーションの可用性を最大化しDynamoDBのコストを削減するのに役立ちます。

どのような機能か早速御覧ください。

Using Auto Scaling

新しいテーブルを作成するときに、DynamoDB Consoleにデフォルトパラメータセットが提示されるようになりました。 あなたはそのまま利用する事も、「Use default settings」のチェックを外して独自のパラメータを入力することもできます

独自にパラメータを設定する方法は以下の通りです。

Target utilizationは、消費容量とプロビジョニングされた容量の比率で表されます。 上記のパラメータは、読み取りまたは書き込み要求が増えた時でも消費される容量の2倍になるように十分な空き容量を確保します(DynamoDBの読み書き操作とプロビジョニングされた容量の関係の詳細については容量単位の計算を参照してください)。 プロビジョニングされた容量の変更は、バックグラウンドで行われます。

Auto Scaling in Action

この重要な新機能が実際に動作するのを見るために、「Getting Started Guide」の指示に従いました。 私は、新しくEC2インスタンス起動し、AWS SDK for Pythonを設定(sudo pip install boto3)を実行し利用するための設定(aws configure)を行いました。 次に、PythonとDynamoDBのコードを使用していくつかのデータを含むテーブルを作成し、読み込みと書き込みの各容量を5ずつ手動で設定しました。

CloudWatchメトリクスで綺麗な直線を得るために私は急いで休憩を取ったので、AutoScalingの効果を示すことができました。 負荷を適用する前のメトリクスは次のとおりです。

私はステップ3のコードを変更して、1920年から2007年の範囲でランダムにクエリを発行し、1〜2分後に読み取りメトリクスを確認しました。

消費された容量はプロビジョニングされた容量よりも多く、その結果多くの読み込みリクエストに対してスロットルが発生します。 AutoScalingが実行される!

私はコンソールに戻ってテーブルのCapacityタブをクリックした。 Read capacityをクリックし、デフォルト値を受け入れ、Saveをクリックしました

DynamoDBは新しいIAMロール(DynamoDBAutoscaleRole)とCloudWatchアラームのペアを作成して、読み取り容量のAuto Scalingを設定しました。

DynamoDB Auto Scalingはアラームのしきい値を管理し、スケーリングプロセスの一部としてアラームのしきい値を上下に調整します。 最初のアラームがトリガーされ追加の読み取り容量がプロビジョニングされている間にテーブルの状態が[Updating]に変更されました。

この変更は、数分で読み取りメトリクスに表示されました。

私は変更されたクエリスクリプトをいくつか実行し、追加の容量がプロビジョニングされているのを見てみました。

私はすべてのスクリプトを停止しスケールダウンアラームが発生するのを待ちました。:

翌朝Scaling activitiesを確認し、アラームが夜の間に何度かトリガされたことを確認しました:

これはメトリクスにも表示されていました。

これまでは、あなたが期待した使用量についてプロビジョンキャパシティユニットを十分に設定し、余裕を持たせる設定(青い線と赤い線の間のスペース)を行うことで、このような状況に備えることができました。若しくはプロビジョンキャパシティユニットを少なくしすぎ、監視するのを忘れてトラフィックが増えた時に容量が使い果たされる可能性がありました。 Auto Scalingを使用すると、リクエストが増加し必要な場合は自動的に増やし、もう不要な時は自動的に下げる事が可能です。

Things to Know

DynamoDB Auto Scalingは、ある程度予測可能である程度定期的に変化する要求レートに対応するように設計されています。予期せぬバーストした読み取りアクティビティに対応する必要がある場合は、Auto ScalingをDAXと組み合わせて使用​​する必要があります(詳細は、Amazon DynamoDB Accelerator(DAX) – Read heavyなワークロード向けインメモリ型キャッシュクラスタを参照してください)。また、AWS SDKを利用したアプリケーションは、スロットリングされた読み込み要求と書き込み要求を検出し、適切な遅延の後に再試行します。

(補足:Auto Scaling実行され実際に使える容量が増えるまでにはどうしても時間が掛かります。その為瞬間的なリクエスト増加に対応するのは難しいケースがあります。その為、瞬間的なリクエスト増加に対応するにはDAXなどのソリューションと組み合わせる事や、瞬間的にスロットリングが発生してもリトライで処理を継続させる事により影響を最小限にする処理が必要です。)

 

私はDynamoDBAutoscaleRoleを先に述べました。このロールは、テーブルとインデックスのスケールを上下させるために必要な権限をAuto Scalingに提供します。このロールと権限の詳細については、「Grant User Permissions for DynamoDB Auto Scaling」を参照してください。

Auto ScalingにはAuto Scalingポリシーを有効または無効にする機能を含むCLIとAPIの完全なサポートがあります。トラフィックに予測可能な時間的なスパイクがある場合(ゲームなどであれば決まった時間に発生するイベントなど)は、プログラムによって自動スケーリングポリシーを無効にし、一定期間高いスループットをプロビジョニングしてから、後でAuto Scalingを再度有効にすることができます。

DynamoDBの制限ページに記載されているように、プロビジョニングされた容量は、必要に応じて必要なだけ増やすことができます(アカウントごとに設定されている上限内にて)。各テーブルまたはグローバルセカンダリインデックスごとに1日に最大9回まで容量を減らすことができます。(その為、あまり頻繁に容量を下げる設定にしてしまうとこの回数を使い切ってしまいその後下げる事が一時的に出来なくなる可能性があります。)

実際に実行された容量は通常のDynamoDBの価格が掛かります。さらに節約するためにDynamoDBのリザーブドキャパシティユニットを購入することもできます。

今すぐ利用可能
この機能は現在すべての地域で利用可能で、今すぐ使用することができます!

Jeff;

(この記事はSA 成田が翻訳しました。原文はこちら

 

 

 

AWS CodeBuild と HashiCorp Packer を用いた AMI ビルダーの構築方法

独自の アマゾン マシン イメージ を作成し維持することは、運用とセキュリティにおけるベストプラクティスです。インフラストラクチャをコードとして維持することもまたベストプラクティスの1つです。そのため、Amazon EC2 インスタンスを素早く起動するために AMI を作成し設定する、といったことをスクリプト化するための自動化ツールを利用することには価値があります。

公開する2つの記事の最初にあたるこの記事では、AWS においてプログラマブルに AMI を作成するために AWS CodeBuild を使用します。AMI 生成の一部として、OS のパッチを適用し、バナーステートメントを設定し、よく使うソフトのいくつかをインストールし、将来的な Amazon EC2 ベースのデプロイメントへの基盤を形成します。

(more…)