tag:crieit.net,2005:https://crieit.net/boards/aws-master/feed
「AWS完全に理解する」の投稿 - Crieit
Crieitで「AWS完全に理解する」ボードに投稿された最近の投稿
2022-03-20T00:05:09+09:00
https://crieit.net/boards/aws-master/feed
tag:crieit.net,2005:PublicArticle/AWS-Organizations
2022-03-20T00:05:09+09:00
2022-03-20T00:05:09+09:00
https://crieit.net/boards/aws-master/AWS-Organizations
AWS Organizations 完全に理解した
<h1>AWS Organizations とは</h1>
<p>複数のAWSアカウントを一括で管理するためのサービスです。<br />
次の機能があります。</p>
<ul>
<li>グループ単位でのポリシー適用による複数AWSアカウントの一元管理</li>
<li>AWSアカウント新規作成の自動化</li>
<li>請求の簡素化</li>
</ul>
<p><a target="_blank" rel="nofollow noopener" href="https://docs.aws.amazon.com/ja_jp/organizations/latest/userguide/orgs_introduction.html">AWS Organizations とは - AWS Organizations</a></p>
<h1>学習成果</h1>
<p>ほぼ下記資料のまとめです。</p>
<p><a target="_blank" rel="nofollow noopener" href="https://d1.awsstatic.com/webinars/jp/pdf/services/20180214_AWS-Blackbelt-Organizations.pdf">20180214 AWS Black Belt Online Seminar AWS Organizations (PDF)</a></p>
<h2>AWS Organizations の構成要素</h2>
<ul>
<li>AWSアカウント or アカウント
<ul>
<li>AWS契約の単位</li>
<li>AWSOrganizationsで管理する最小単位</li>
</ul></li>
<li>組織 (Organization)
<ul>
<li>一元管理する対象の全体</li>
<li>複数AWSアカウントのセット</li>
</ul></li>
<li>マスターアカウント
<ul>
<li>組織の全体を管理する権限を持つAWSアカウント</li>
</ul></li>
<li>メンバーアカウント
<ul>
<li>組織内のマスターアカウント以外のAWSアカウント</li>
</ul></li>
<li>OU: 組織単位
<ul>
<li>組織内の複数AWSアカウントのグループ</li>
</ul></li>
<li>管理用ルート (root)
<ul>
<li>OU階層の開始点</li>
</ul></li>
<li>組織ポリシー
<ul>
<li>組織内で適用してAWSアカウントを管理する仕組み</li>
<li>現在サポートされている組織ポリシーのタイプ
<ul>
<li>承認ポリシー
<ul>
<li>SCP: サービスコントロールポリシー
<ul>
<li>利用できるAWSサービスとアクションを制御する</li>
<li>組織ルート、OU、アカウント単位でアタッチが可能</li>
<li>アタッチしたアカウント内のIAMユーザー、IAMロールレベルでの制御が可能
<ul>
<li>ルートユーザーも適用対象</li>
</ul></li>
<li>マスターアカウントは適用対象外</li>
<li>ポリシーの構文は通常のIAMポリシーと同じ
<ul>
<li>リソース制御は不可</li>
<li>プリンシパルは利用不可</li>
</ul></li>
</ul></li>
</ul></li>
<li>管理ポリシー
<ul>
<li>AIサービスのオプトアウトポリシー</li>
<li>バックアップポリシー</li>
<li>タグポリシー</li>
</ul></li>
</ul></li>
</ul></li>
</ul>
<h2>構成図</h2>
<ul>
<li>組織
<ul>
<li>アカウント
<ul>
<li>マスターアカウント</li>
<li>メンバーアカウント1</li>
</ul></li>
<li>ポリシー</li>
<li>管理用ルート
<ul>
<li>開発環境OU
<ul>
<li>アカウント
<ul>
<li>メンバーアカウント2</li>
<li>メンバーアカウント3</li>
</ul></li>
</ul></li>
<li>本番環境OU
<ul>
<li>アカウント
<ul>
<li>メンバーアカウント4</li>
<li>メンバーアカウント5</li>
<li>メンバーアカウント6
<ul>
<li>ポリシー</li>
</ul></li>
</ul></li>
<li>ポリシー</li>
</ul></li>
</ul></li>
</ul></li>
</ul>
<h2>機能セットの選択</h2>
<ul>
<li>Consolidated Billing Only
<ul>
<li>支払いの一括請求やアカウントの新規作成/招待/削除を実施したいだけならこっち</li>
</ul></li>
<li>All Feature
<ul>
<li>複数アカウントを統制したい場合はこっち</li>
</ul></li>
</ul>
<h2>一括請求 (Consolidated Billing)</h2>
<ul>
<li>AWSOrganizations 提供前の一括請求と同じ</li>
<li>ボリュームディスカウントが合算して計算される</li>
<li>リザーブドインスタンスによる割引がデフォルトで共有される</li>
<li>割引を共有しない場合の料金 (Unblended Rate) も確認できる</li>
</ul>
Morichan
tag:crieit.net,2005:PublicArticle/Amazon-Route-53
2022-03-19T19:21:44+09:00
2022-03-19T19:21:44+09:00
https://crieit.net/boards/aws-master/Amazon-Route-53
Amazon Route 53 完全に理解した
<h1>Amazon Route 53 とは</h1>
<p>AWSで提供しているDNSサービスです。<br />
購入したドメインを登録することで、世界中にドメインとIPアドレスを公開し、購入したドメインでサービスを展開できるようになります。</p>
<p><a target="_blank" rel="nofollow noopener" href="https://docs.aws.amazon.com/ja_jp/Route53/latest/DeveloperGuide/Welcome.html">Amazon Route 53 とは? - Amazon Route 53</a></p>
<h1>学習成果</h1>
<p>だいたいは以下資料のまとめです。<br />
一般的には、グローバルなDNSサービスを思い浮かべると思いますが、ローカルなDNSサービスも担っており、説明資料としては2種類を分けています。</p>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://d1.awsstatic.com/webinars/jp/pdf/services/20191016_AWS_Blackbelt_Route53_Resolver.pdf">20191016 AWS Black Belt Online Seminar Amazon Route 53 Resolver (PDF)</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://d1.awsstatic.com/webinars/jp/pdf/services/20191105_AWS_Blackbelt_Route53_Hosted_Zone_A.pdf">20191105 AWS Black Belt Online Seminar Amazon Route 53 Hosted Zone (PDF)</a></li>
</ul>
<h2>DNSサーバーの4つの機能</h2>
<ul>
<li>フォワーダー、フルサービスリゾルバー、ネームサーバーが同居して、1つのDNSサーバーを構成する</li>
<li>著名なDNSサーバー実証のいくつかは、これら複数の機能を有していることが多い</li>
</ul>
<h3>ネームサーバー</h3>
<ul>
<li>ルートを起点にして全てのFQDNを探索できるように構成された分散データベース
<ul>
<li>また、これを成す各々のネームサーバー</li>
</ul></li>
<li>権威DNSサーバー/Authoritative Serverとも</li>
</ul>
<h3>フルサービスリゾルバー</h3>
<ul>
<li>ルートから順にネームサーバーに問合せた回答を、問い合わせもとに返す実装
<ul>
<li>経路
<ul>
<li>E.g.)
<ul>
<li>ユーザー: request www.example.com To フルサービスリゾルバー</li>
<li>フルサービスリゾルバー: request www.example.com To ルートネームサーバー</li>
<li>ルートネームサーバー: response .comネームサーバー To フルサービスリゾルバー</li>
<li>フルサービスリゾルバー: request www.example.com To .comネームサーバー</li>
<li>ルートネームサーバー: response .example.comネームサーバー To フルサービスリゾルバー</li>
<li>フルサービスリゾルバー: request www.example.com To .example.comネームサーバー</li>
<li>ルートネームサーバー: response 192.0.2.3 To フルサービスリゾルバー</li>
<li>フルサービスリゾルバー: response 192.0.2.3 To User</li>
</ul></li>
<li>上記の例のうち、ユーザー・フルサービスリゾルバー間の通信を再帰的問合せと呼ぶ</li>
<li>上記の例のうち、フルサービスリゾルバー・各ネームサーバー間の通信を反復問合せと呼ぶ</li>
</ul></li>
</ul></li>
<li>効率化のため所定の期間 (TTL) キャッシュを保持する</li>
</ul>
<h3>スタブリゾルバー</h3>
<ul>
<li>DNSクライアント実装
<ul>
<li>基本的にOSに組込まれていることが多い</li>
</ul></li>
<li>常に再帰的問合せ
<ul>
<li>キャッシュの有無は実装に依存</li>
</ul></li>
<li>複数のDNSサーバーに対し、ドメインごとに振分けたり、同時に利用したりする機能は無い
<ul>
<li>サーバーを複数指定するのは障害時のフォールバックのため</li>
</ul></li>
</ul>
<h3>フォワーダー</h3>
<ul>
<li>受取った問合せを、ルールに基づいて中継する実装</li>
<li>常に再帰的問合せ</li>
<li>効率化のため所定の期間 (TTL) キャッシュを保持する</li>
</ul>
<h2>ドメイン名とは</h2>
<h3>ドメイン名の基本</h3>
<ul>
<li>レジストラント(登録者): ドメイン名を登録し、使用するユーザー</li>
<li>レジストラ(登録取次事業者): レジストリと契約し、ドメイン名登録の窓口となる事業者</li>
<li>レジストリ(登録管理機関): TLDネームサーバーとWHOISデータベースの管理主体
<ul>
<li>TLD: トップレベルドメイン</li>
<li>WHOIS: ドメイン名の情報を参照可能なデータベース</li>
</ul></li>
<li>全体像
<ol>
<li>レジストラントがレジストラを操作して登録する</li>
<li>レジストラがレジストリのWHOISに登録データを連携する</li>
<li>レジストリがWHOISとTLDを同期する</li>
</ol></li>
</ul>
<h3>ドメイン名管理者が認識しておきたいトラブル</h3>
<ul>
<li>事例
<ul>
<li>ドメイン名ハイジャック
<ul>
<li>登録情報の書換え、ネームサーバーの侵害などによる乗取り</li>
</ul></li>
<li>スラミング
<ul>
<li>ドメイン名移転スキームの悪用による所有権の乗取り</li>
</ul></li>
<li>ドロップキャッチング
<ul>
<li>更新漏れ、あるいは廃止したドメインの横取り</li>
</ul></li>
</ul></li>
<li>対応策
<ul>
<li>レジストラ/レジストリからの連絡を見逃さない</li>
<li>レジストリロック/レジストラロックの活用</li>
<li>多要素認証などによるコントロールパネルの認証強化</li>
<li>ドメイン名を手放す際の影響の考慮</li>
</ul></li>
</ul>
<h2>AWSが提供するDNSサービスと機能</h2>
<h3>Amazon Route 53 (Hosted Zone)</h3>
<ul>
<li>ネームサーバーをマネージドで提供するサービス
<ul>
<li>エイリアスレコード
<ul>
<li>CNAMEレコードを返すのではなく、CNAMEレコードが最終的に保持するAレコードのIPアドレスをAレコードとして直接返答するRoute 53固有の機能</li>
</ul></li>
<li>トラフィックルーティング
<ul>
<li>クライアントからのトラフィックをより適したリソースにルーティングする</li>
<li>クエリに応答する方法を決定するルーティングポリシーを選択できる
<ul>
<li>シンプル
<ul>
<li>ランダムに応答する</li>
</ul></li>
<li>加重
<ul>
<li>ルーティング割合を設定できる</li>
</ul></li>
<li>フェイルオーバー
<ul>
<li>ヘルスチェックの結果に基づいて応答先を変える</li>
</ul></li>
<li>複数値回答
<ul>
<li>シンプル + フェイルオーバー</li>
</ul></li>
<li>レイテンシー
<ul>
<li>複数リージョンのうち最も低いリージョンのリソースを応答する</li>
</ul></li>
<li>位置情報
<ul>
<li>クライアントの位置情報に基づいて応答先を変える
<ul>
<li>適切な言語に合わせたコンテンツの提供が可能</li>
<li>ライセンス許可した市場にのみの提供制限が可能</li>
</ul></li>
</ul></li>
<li>物理的近接性
<ul>
<li>ユーザーとリソースの地理的場所に基づいて応答先を変える
<ul>
<li>トラフィックフローを利用してトラフィックルーティングを設定する必要がある</li>
</ul></li>
</ul></li>
</ul></li>
</ul></li>
</ul></li>
<li>特定のVPCからの問合せと、それ以外からの問合せを識別し、異なる応答を返すことができる
<ul>
<li>Amazon Route 53 Private Hosted Zone: VPCに閉じたプライベートネットワーク内のDNSドメインのレコードを管理するコンテナ
<ul>
<li>from Instance via Route 53 Resolver in VPC</li>
</ul></li>
<li>Amazon Route 53 Public Hosted Zone: インターネット上に公開されたDNSドメインのレコードを管理するコンテナ
<ul>
<li>from Internet</li>
</ul></li>
</ul></li>
</ul>
<h3>Amazon Route 53 Resolver</h3>
<ul>
<li>VPCに標準で備わるDNSサーバー(フォワーダー + フルサービスリゾルバー)
<ul>
<li>フォワーダーにはリゾルバールール(転送ルールのテーブル)がある</li>
<li>通信経路 via VPC
<ul>
<li><code>Inbound/Outbound Endpoint on EC2 in VPC <-> フォワーダー on Route 53 Resolver in VPC</code>
<ul>
<li>Private: <code>フォワーダー <-> EC2 in other VPC</code></li>
<li>Public: <code>フォワーダー <-> フルサービスリゾルバー on Route 53 Resolver in VPC <-> the Internet</code></li>
</ul></li>
<li>オンプレミス -> 他VPCのEC2インスタンス: xxx.ec2.internal
<ul>
<li><code>オンプレミス -> Inbound -> フォワーダー -> EC2 in other VPC</code></li>
</ul></li>
<li>オンプレミス -> インターネット: www.example.com
<ul>
<li><code>オンプレミス -> Inbound -> フォワーダー -> フルサービスリゾルバー -> the Internet</code></li>
</ul></li>
<li>VPC -> オンプレミス: x.on-prem.internal
<ul>
<li><code>EC2 -> フォワーダー -> Outbound -> オンプレミス</code></li>
</ul></li>
</ul></li>
</ul></li>
</ul>
<h3>Amazon Route 53 Resolver for Hybrid Clouds</h3>
<ul>
<li>ハイブリッド環境での名前解決を一元化するRoute 53 Resolverの拡張機能
<ul>
<li>オンプレミス VPC</li>
<li>オンプレミス -> インターネット</li>
<li>オンプレミス インターネット(同じドメイン)
<ul>
<li>リゾルバールールにサブドメインで通信先を分ける</li>
</ul></li>
</ul></li>
</ul>
Morichan
tag:crieit.net,2005:PublicArticle/Amazon-VPC
2022-03-16T01:17:43+09:00
2022-03-16T01:17:43+09:00
https://crieit.net/boards/aws-master/Amazon-VPC
Amazon VPC完全に理解したかった
<h1>Amazon VPCとは</h1>
<p>AWS上の仮想ネットワーク空間を構築できるサービスです。<br />
ただ、ネットワーク空間を作っても、コンピューティング機能が無ければ意味がない(例えるなら、ルーターとLANケーブルしかない状態)ため、EC2などを併用することが前提となるサービスです。</p>
<p><a target="_blank" rel="nofollow noopener" href="https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/what-is-amazon-vpc.html">Amazon VPC とは? - Amazon Virtual Private Cloud</a></p>
<h1>学習成果</h1>
<p>以下の資料を参考にまとめました。<br />
なお、以降は説明がない限りはIPv4をもとにした通信の設定です。</p>
<p><a target="_blank" rel="nofollow noopener" href="https://d1.awsstatic.com/webinars/jp/pdf/services/20201021_AWS-BlackBelt-VPC.pdf">20201021 AWS Black Belt Online Seminar Amazon VPC (PDF)</a></p>
<p>また、関連する内容として、以下も参考にまとめました。</p>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://d1.awsstatic.com/webinars/jp/pdf/services/202110_AWS_Black_Belt_Site-to-Site_VPN.pdf">202110 AWS Black Belt Online Seminar AWS Site-to-Site VPN (PDF)</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://d1.awsstatic.com/webinars/jp/pdf/services/20191113_AWS-BlackBelt_Transit_Gateway.pdf">20191113 AWS Black Belt Online Seminar AWS Transit Gateway (PDF)</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://d1.awsstatic.com/webinars/jp/pdf/services/20210209-AWS-Blackbelt-DirectConnect.pdf">20210209 AWS Black Belt Online Seminar AWS Direct Connect (PDF)</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://d1.awsstatic.com/webinars/jp/pdf/services/20200219_BlackBelt_Onpremises_Redundancy.pdf">20200219 AWS Black Belt Online Seminar オンプレミスとAWS間の冗長化接続 (PDF)</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://aws.amazon.com/jp/ec2/faqs/">よくある質問 - Amazon EC2 | AWS</a></li>
</ul>
<p>あまり使ったことのないサービスは理解が難しい......。<br />
省略形も多すぎて理解が追付かないです。<br />
とりあえずGWってついていたらゲートウェイって読むようにしたいですね。</p>
<h2>概要</h2>
<ul>
<li>データセンターのネットワークを、AWS上に仮想的なプライベートネットワーク空間として構築できる
<ul>
<li>任意のIPアドレスレンジの利用が可能</li>
<li>論理的なネットワーク分離が可能</li>
<li>ネットワーク同士の接続が可能</li>
<li>ネットワーク環境のコントロールが可能</li>
<li>複数のコネクティビティオプションの選択が可能</li>
</ul></li>
<li>様々なコンポーネントを組合せる</li>
</ul>
<h2>コンポーネント</h2>
<p>よく使われる省略形を前頭に記しています。</p>
<h3>IGW: インターネットゲートウェイ</h3>
<ul>
<li>インターネット (The Internet) と通信するための通り道
<ul>
<li>VPC内のEC2インスタンスがVPC外部と通信する際には必須</li>
</ul></li>
<li>VPC内のEC2インスタンスなどからはIPアドレスなどで直接参照できない
<ul>
<li>ルートテーブルによって通信先を教えてもらう必要がある</li>
</ul></li>
</ul>
<h3>サブネット</h3>
<ul>
<li>VPC内のネットワーク範囲の1つ
<ul>
<li>VPCより小さい</li>
</ul></li>
</ul>
<h3>仮想ルータ</h3>
<ul>
<li>ルートテーブルを保持している、サブネット内の仮想的なルーター</li>
</ul>
<h3>ルートテーブル</h3>
<ul>
<li>VPC内のパケットの通信先を表す
<ul>
<li>いわゆるiptablesのようなもの</li>
</ul></li>
<li>VPC作成時にデフォルトで1つのルートテーブルが作成される</li>
</ul>
<h3>VPC Peering</h3>
<ul>
<li>VPC間の接続に使う</li>
<li>1対1の関係
<ul>
<li>VPCを複数構築している場合は、最大で指数関数的に作成する必要がある</li>
</ul></li>
</ul>
<h3>NATゲートウェイ</h3>
<ul>
<li>プライベートサブネットのリソースがインターネットまたはAWSクラウドへ通信するために必要
<ul>
<li>パブリックサブネットのリソースには不要</li>
</ul></li>
<li>かつてはEC2インスタンスでNATを作る必要があった(NATインスタンス)</li>
</ul>
<h3>VPCエンドポイント</h3>
<ul>
<li>Client VPN接続構築時に、オンプレミスとVPC内EC2インスタンスの接続に使う</li>
<li>VPC内EC2インスタンスからVPC外AWSリソースへの接続に使う
<ul>
<li>AmazonProvidedDNSで通信先を教えてもらう必要あり</li>
<li>無料(PrivateLinkと異なる)</li>
<li>アクセス制御にはIAMポリシーのような構文(エンドポイントポリシー)を利用する</li>
</ul></li>
</ul>
<h3>EIP: ElasticIP</h3>
<ul>
<li>固定IPアドレスの設定が可能なサービス</li>
</ul>
<h3>VGW: バーチャルプライベートゲートウェイ</h3>
<ul>
<li>VPN接続に利用する接続口</li>
<li>関連リソースが少なく、設定が容易</li>
</ul>
<h3>VPNコネクション</h3>
<ul>
<li>VPN通信そのもの、または、VPN通信経路</li>
</ul>
<h3>VIF: 仮想インターフェイス</h3>
<ul>
<li>コネクション(物理接続)を通してAWSリソースにアクセスするための論理インター芸す
<ul>
<li>AWSと利用者のルーターの間でBGPピアを確立し経路交換をするために必要</li>
<li>VLAN IDを持つ</li>
</ul></li>
<li>種類
<ul>
<li>プライベートVIF: プライベートIPを介してVPCに接続</li>
<li>パブリックVIF: パブリックIPを介してAWSの全リージョンに接続</li>
<li>トランジットVIF: TGW用のDirect Coonnectゲートウェイに接続</li>
</ul></li>
</ul>
<h3>CGW: カスタマゲートウェイ</h3>
<ul>
<li>VPN接続の利用者側にある物理デバイスまたはソフトウェアデバイス</li>
</ul>
<h3>ENI: Elasticネットワークインタフェース</h3>
<ul>
<li>いわゆるNIC</li>
<li>EC2インスタンスに紐付く
<ul>
<li>インスタンスタイプにより上限が決まっている</li>
</ul></li>
<li>サブネットにも紐付く?
<ul>
<li>サブネットのENIというのは、サブネット内のEC2インスタンスに紐付けたENIのことを指しているのかもしれない</li>
</ul></li>
<li>接続方法によって規格が変化するっぽい
<ul>
<li>ENA ENI</li>
<li>EFA ENI</li>
<li>VPC ENI</li>
<li>TGW ENI</li>
</ul></li>
</ul>
<h3>ENA: Elasticネットワークアダプタ</h3>
<ul>
<li>ENIの種類の1つ</li>
<li>一般的なEC2インスタンスに紐付くENI</li>
</ul>
<h3>PrivateLink</h3>
<ul>
<li>VPC内EC2インスタンスからVPC外AWSリソースへの接続に使う
<ul>
<li>サブネットにエンドポイント用のプライベートIPアドレスが生成される</li>
<li>AmazonProvidedDNSで通信先を教えてもらう必要あり</li>
<li>有料(VPCエンドポイントと異なる)</li>
<li>アクセス制御にはSGを利用する</li>
<li>冗長な設計を意識する必要がある</li>
<li>オンプレミスにネイティブ対応</li>
</ul></li>
<li>VPC間の接続に使う</li>
<li>1対Nの関係
<ul>
<li>スケーラブル
<ul>
<li>アプリケーションの共有</li>
</ul></li>
<li>IPアドレスが重複していてもOK</li>
</ul></li>
</ul>
<h3>TGW: Transit Gateway</h3>
<ul>
<li>VPC間の接続に使う
<ul>
<li>VPC間の接続が無い場合や、1つのハブVPCがある場合などでは、使う必要は無い
<ul>
<li>VPCとハブVPC間の接続にはVPC Peeringを使えばよい</li>
<li>VPCとオンプレミス間の接続にはDXGWを使えばよい</li>
<li>TGWはハブとしては優秀だが、そこそこコストがかかる</li>
</ul></li>
</ul></li>
<li>1000以上のVPCとオンプレミス間の相互接続のハブとして使う
<ul>
<li>1つのVPN接続で複数にVPCへ接続が可能
<ul>
<li>複数のVPN接続を束ね、 Equal Cost Multi Path (ECMP) を利用し帯域を増やす
<ul>
<li>レイテンシーに一貫性を求めない場合に利用する
<ul>
<li>そうでない場合はDirect Connectを利用する</li>
</ul></li>
<li>行きと帰りのトラフィックが異なる可能性がある</li>
</ul></li>
</ul></li>
</ul></li>
<li>データストリームを仮想的に複数のアプリケーションに配信可能</li>
<li>1対1でも1対Nでも、ルートテーブルによって関係は変わる
<ul>
<li>スケーラブル
<ul>
<li>ネットワークの共有</li>
</ul></li>
<li>AZ単位
<ul>
<li>VPC間の通信は同一AZのENIを経由して通信する
<ul>
<li>E.g.
<ul>
<li>リクエスト
<ol>
<li>EC2 in SubnetA1 in VPCx in ap-northeast-1a</li>
<li>ENI in SubnetA2 in VPCx in ap-northeast-1a</li>
<li>TGW</li>
<li>ENI in SubnetA4 in VPCy in ap-northeast-1a</li>
<li>EC2 in SubnetC3 in VPCy in ap-northeast-1c</li>
</ol></li>
<li>レスポンス
<ol>
<li>EC2 in SubnetC3 in VPCy in ap-northeast-1c</li>
<li>ENI in SubnetC4 in VPCy in ap-northeast-1c</li>
<li>TGW</li>
<li>ENI in SubnetC2 in VPCx in ap-northeast-1c</li>
<li>EC2 in SubnetA1 in VPCx in ap-northeast-1a</li>
</ol></li>
</ul></li>
<li>ただし、同一AZのENIが存在する場合は、別AZ間の通信をする際に別AZ内のVPC内にENIが存在しないと通信がアウトバウンドでロストする</li>
</ul></li>
<li>送信先のVPC内に同一AZのENIが存在しなくても通信は可能</li>
</ul></li>
</ul></li>
<li>Acceleratedサイト間VPNオプション
<ul>
<li>もっとも近いAWS Edge LocationのVPNコネクションエンドポイントを利用できる</li>
<li>目的のTGWのエンドポイントまでは、AWSネットワーク内を利用できる</li>
</ul></li>
</ul>
<h3>SG: セキュリティグループ</h3>
<ul>
<li>NACLと比較して、ステートフルなファイアウォール
<ul>
<li>IN/OUTの戻りトラフィックは考えなくてよい</li>
</ul></li>
<li>サーバ単位で設定する</li>
<li>Allowのみのホワイトリスト型</li>
<li>全てのルールを適用(AND型)</li>
</ul>
<h3>NACL, ACL: ネットワークACLs</h3>
<ul>
<li>SGと比較して、ステートレスなファイアウォール
<ul>
<li>IN/OUTの戻りトラフィックについても明示的に許可/拒否する必要がある</li>
</ul></li>
<li>サブネット単位で設定する</li>
<li>Allow/Denyのブラックリスト型</li>
<li>設定順に適用(OR型)</li>
</ul>
<h2>ネットワーク空間の構築方法</h2>
<ol>
<li>まずは全体のネットワーク空間をVPCとして定義する
<ul>
<li>アドレスレンジを選択する
<ul>
<li>VPC空間としてのサブネット(CIDRブロック)を定義するようなもの</li>
</ul></li>
<li>リージョン単位で作成する</li>
<li>E.g.
<ul>
<li>ap-northeast-1: 172.31.0.0/16</li>
</ul></li>
</ul></li>
<li>利用するサブネットを定義する
<ul>
<li>VPC空間内で利用するサブネット(CIDRブロック)を定義する
<ul>
<li>IPアドレス</li>
<li>サブネットマスク</li>
</ul></li>
<li>EC2インスタンスを配備する空間</li>
<li>AZ単位で作成する
<ul>
<li>複数のAZをまたいでの作成はできない</li>
</ul></li>
<li>E.g.
<ul>
<li>ap-northeast-1a: 172.31.0.0/24</li>
<li>ap-northeast-1c: 172.31.1.0/24</li>
</ul></li>
</ul></li>
<li>(インターネットと接続する場合)IGWをVPCに生成する
<ul>
<li>外部インターネットやAWSサービスと、2で作成したサブネット(パブリックサブネット)内のEC2インスタンスが、互いに接続するための通信経路</li>
</ul></li>
<li>(インターネットと接続しない場合)VGWをVPCに生成する
<ul>
<li>仮想ルータを配置済みのオンプレミス環境サーバーと、2で作成したサブネット(プライベートサブネット)内のEC2インスタンスが、互いに接続するための通信経路
<ul>
<li>通信経路はVPNコネクションまたは専用線</li>
</ul></li>
</ul></li>
<li>ルートテーブルを編集する
<ul>
<li>サブネットごとに紐付け可能</li>
<li>EC2インスタンスのOSが確認できるのはプライベートIPのみであるため、VPC外部と通信するためには必ず IGW or VGW を通る必要がある
<ul>
<li>パブリックサブネットとプライベートサブネット間の通信は、プライベートIPで直接通信可能</li>
<li>VPC外部というのは、VPC外部に設置しているAWSの他リソース(別VPC内のEC2インスタンス、SQSなど)との通信も含む</li>
</ul></li>
<li>ターゲットの設定例
<ul>
<li>172.31.0.0/16(サブネット内の通信): local</li>
<li>0.0.0.0/0(そのほか): 先ほど作成した IGW or VGW</li>
</ul></li>
</ul></li>
<li>VPCへのIN/OUTトラフィックを許可する
<ul>
<li>SG</li>
<li>NACL</li>
</ul></li>
</ol>
<h2>その他のVPCの機能</h2>
<h3>Ingress Routing</h3>
<ul>
<li>IGW/VGWのIN/OUTトラフィックを特定EC2インスタンスのENIに設定できる
<ul>
<li>特定EC2インスタンスの経由を強制できる</li>
<li>ENIがIGW/VGWの代わりになるイメージ</li>
</ul></li>
</ul>
<h3>DHCP</h3>
<ul>
<li>サブネット内にDHCPサーバが存在する
<ul>
<li>サブネット内のENIにIPアドレスを自動割当て</li>
<li>プライベートIPを固定した場合は、EC2インスタンスの再起動によって変化しない</li>
</ul></li>
</ul>
<h3>Route53 resolver (AmazonProvidedDNS)</h3>
<ul>
<li>Amazonが提供するDNSサービス</li>
<li>VPC内のEC2インスタンスからのみ参照可能</li>
</ul>
<h3>Route 53 Resolver for Hybrid Clouds</h3>
<ul>
<li>オンプレミスからDirect Connect/VPN経由でVPC Provided DNSへの直接悪節可能なDNSエンドポイントを提供</li>
</ul>
<h3>DNS</h3>
<ul>
<li>DNS機能の有効化とホストへのDNS名割当て
<ul>
<li>Enable DNS resolution
<ul>
<li>AmazonProvidedDNSを利用できるようにする</li>
</ul></li>
<li>Enable DNS hostnames
<ul>
<li>FQDNが自動的に割当てられる</li>
</ul></li>
</ul></li>
</ul>
<h3>Amazon Time Sync Service</h3>
<ul>
<li>時刻同期可能なNTPサーバ
<ul>
<li>プライベートサブネット内でも利用可能</li>
<li>うるう秒への対策は実装済み</li>
</ul></li>
<li>VPC内で稼働する全てのEC2インスタンスが利用可能</li>
</ul>
<h3>IPv6</h3>
<ul>
<li>Site-to-Site VPNでIPv6が利用可能</li>
<li>IPv4と比べて、いくつか制限あり
<ul>
<li>CIDRブロックサイズは56bit固定、かつ自動でアサインされる</li>
<li>サブネットブロックサイズは64bit固定</li>
<li>プライベートIPは標準では無し
<ul>
<li>Egress-only Gateway (EGW) を利用すればIPv6においてもプライベートIPが利用可能</li>
</ul></li>
<li>AWSから提供されるDNSホスト名は無し</li>
</ul></li>
</ul>
<h3>VPCシェアリング</h3>
<ul>
<li>アカウントをまたいだVPCの共有によりVPC数の削減が可能</li>
<li>通信もVPC内で完結</li>
</ul>
<h3>VPC Flow Logs</h3>
<ul>
<li>ネットワークトラフィックをキャプチャしてCloudWatch LogsやS3にログデータを送信できる</li>
</ul>
<h3>VPC Traffic Mirroring</h3>
<ul>
<li>EC2インスタンスのENIからネットワークトラフィックをミラーリングできる</li>
<li>VPCフローログに含まれないパケット内容の取得が可能</li>
</ul>
<h3>Amazon GuardDuty</h3>
<ul>
<li>EC2またはIAMにおける脅威を検出する</li>
</ul>
<h2>VPCとのプライベートネットワーク接続</h2>
<h3>VPN接続</h3>
<h4>エンドポイントを利用したAWS Client VPN</h4>
<ul>
<li>OpenVPNベースでのクライアントVPN接続を提供するマネージドサービス</li>
<li>VPC内のプライベートサブネットと、クライアントVPNエンドポイントを、AWS Client VPNとしてグルーピングする</li>
<li>通信経路: <code>VPNクライアント <-> クライアントVPNエンドポイント <-> ENI (on EC2 in Private Subnet)</code></li>
</ul>
<h4>VGWを利用したサイト間VPN (Site-to-Site VPN)</h4>
<ul>
<li>1つのVPNコネクションを2つのIPsecトンネルが利用して冗長化</li>
<li>通信経路: <code>CGW <-(VPNコネクション)-> VGW <-> ENI (on EC2)</code></li>
</ul>
<h4>TGWを利用したサイト間VPN (Site-to-Site VPN)</h4>
<ul>
<li>Hyperplaneテクノロジーで処理ノードをマルチAZに分散して冗長化</li>
<li>通信経路: `CGW <-(VPNコネクション)-> TGW <-> TGW ENI (on EC2)</li>
</ul>
<h3>専用線接続</h3>
<h4>AWS Direct Connect</h4>
<ul>
<li>オンプレミスと接続する専用線(これはキャリアと契約する必要がある)の片側とAWSクラウドをDirect Connectロケーションで接続するサービス
<ul>
<li><del>オンプレミスと直接接続する専用線サービス</del></li>
</ul></li>
<li>本番サービス向け</li>
<li>LAG: Link Aggregation Group
<ul>
<li>複数の接続経路を集約して1つの論理インターフェイスとして提供する</li>
<li>Link Aggregation Control Protocol (LACP) を使用する</li>
</ul></li>
<li>通信経路: <code>CGW <-(Direct Connect Connection)-> 相互接続ポイント <-> ...</code>
<ul>
<li>相互接続ポイントの接続先
<ul>
<li>VPC</li>
<li>AWSクラウド</li>
<li>TGW</li>
</ul></li>
<li>接続経路
<ul>
<li>Direct Connectロケーションと利用者機器が同じロケーション
<ul>
<li><code>CGW <-(WAN回線)-> CGW in Direct Connect ロケーション <-(LAG)-> Direct Connect Device <-> AWS Cloud</code></li>
</ul></li>
<li>Direct Connectロケーションから別業者の専用線で接続
<ul>
<li><code>CGW <-(専用線)-> 別業者機器 in Direct Connect ロケーション <-(LAG)-> Direct Connect Device <-> AWS Cloud</code></li>
</ul></li>
<li>パートナー様閉域網(IP-VPN網、モバイル網など)経由で接続
<ul>
<li><code>CGW <-> 閉域網 <-> 別業者機器 in Direct Connect ロケーション <-(LAG)-> Direct Connect Device <-> AWS Cloud</code></li>
</ul></li>
</ul></li>
</ul></li>
</ul>
<h3>DXGW: Direct Connect Gateway</h3>
<ul>
<li>同一アカウントに所属する複数リージョンの複数AZから複数リージョンの複数VPCに接続できる機能</li>
<li>通信経路: <code>CGW <-(Direct Connect Connection)-> 相互接続ポイント <-(VIF)-> DXGW <-> ENI (on EC2 in VPC)</code></li>
</ul>
<h3>VPNとDirect Connectの冗長化</h3>
<ul>
<li>VPNとDirect Connectを同じVGWに接続可能</li>
<li>Direct Connectが優先
<ul>
<li>Direct Connectが何かしらの原因により通信障害が発生した場合、VPN経由での通信が可能</li>
</ul></li>
</ul>
Morichan
tag:crieit.net,2005:PublicArticle/Amazon-ECS
2022-03-13T03:27:43+09:00
2022-03-13T03:27:43+09:00
https://crieit.net/boards/aws-master/Amazon-ECS
Amazon ECS完全に理解した
<h1>Amazon ECSとは</h1>
<p>コンテナ管理サービスの1つです。</p>
<p><a target="_blank" rel="nofollow noopener" href="https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/Welcome.html">Amazon Elastic Container Service とは - Amazon Elastic Container Service</a></p>
<p>よくEKSと比較されがちです。</p>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://dev.classmethod.jp/articles/ecs-and-eks/">EKSは本当にECSより難しいのか? | DevelopersIO</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://zenn.dev/yoshinori_satoh/articles/2021-02-13-eks-ecs-compare">AWS EKSとECSの比較と選択基準</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/miyuki_samitani/items/b2b9d2f0654af2bd992c">EKSとECSの違い - Qiita</a></li>
</ul>
<h1>学習成果</h1>
<p>下記の要約のうち、気になった部分をまとめています。<br />
Dockerやdocker-composeのぼやっとした知識はあるものとします(無いと理解できないと思います)。</p>
<p><a target="_blank" rel="nofollow noopener" href="https://d1.awsstatic.com/webinars/jp/pdf/services/20200422_BlackBelt_Amazon_ECS_Share.pdf">20200422 AWS Black Belt Online Seminar Amazon Elastic Container Servise (Amazon ECS) (PDF)</a></p>
<p>補足として下記を参照しました。</p>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://d1.awsstatic.com/webinars/jp/pdf/services/20190925_AWS-BlackBelt_AWSFargate.pdf">20190925 AWS Black Belt Online Seminar AWS Fargate (PDF)</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://d1.awsstatic.com/webinars/jp/pdf/services/20190731_AWS-BlackBelt_AmazonECS_DeepDive_Rev.pdf">20190731 Black Belt Online Seminar Amazon ECS Deep Dive (PDF)</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://d1.awsstatic.com/webinars/jp/pdf/services/20191127_AWS-BlackBelt_Container_Insights.pdf">20191127 AWS Black Belt Online Seminar Amazon CloudWatch Container Insights で始めるコンテナモニタリング入門 (PDF)</a></li>
</ul>
<h2>ECSの主要要素</h2>
<h3>タスク定義</h3>
<ul>
<li>タスクを構成するコンテナ群の定義
<ul>
<li>コンテナ定義</li>
<li>要求CPU & メモリ</li>
<li>タスクの割当てIAMロール</li>
<li>ネットワークモード</li>
<li>など</li>
</ul></li>
<li>AWS Batchのジョブ定義とほとんど同じ
<ul>
<li>というか、多分AWS Batchの中身はECS + SQSなんじゃないかな
<ul>
<li>と思ったら、「AWS Batchは内部的にECS Taskを使っている」と断定している記事を見つけた(2次情報ですが)
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://techblog.timers-inc.com/entry/2019/08/06/aws-batch-lambda-ecs-comparison">AWS Batch, Lambda, ECS Task 比較:バッチやジョブにはどれを使う? - Tech Blog</a></li>
</ul></li>
</ul></li>
</ul></li>
</ul>
<h3>タスク</h3>
<ul>
<li>タスク定義に基づき起動されるコンテナ群
<ul>
<li>タスクというのは1つ以上のコンテナの集合</li>
</ul></li>
<li>タスク内コンテナは同一ホスト上で実行される
<ul>
<li>ホストというのは、実際のEC2インスタンスやFargate内の論理デバイスのこと</li>
<li>タスク内のコンテナ間の通信を可能とするため?</li>
</ul></li>
<li>こちらもAWS Batchのジョブとほどんど同じ</li>
<li>考え方としてはdocker-composeに近い?</li>
</ul>
<h3>サービス</h3>
<ul>
<li>タスク実行コピー数の定義
<ul>
<li>タスク実行コピー数とは、タスクを同時にいくつ起動するかということ</li>
</ul></li>
<li>起動後のタスク実行コピー数の維持</li>
<li>ELBとの連携</li>
<li>起動タイプ (EC2 or Fargate) の設定</li>
</ul>
<h3>クラスター</h3>
<ul>
<li>実行環境の境界
<ul>
<li>EC2インスタンスやFargateといった論理デバイスの1つひとつを表す
<ul>
<li>サービスはクラスターを跨る可能性がある</li>
</ul></li>
</ul></li>
<li>IAM権限の境界</li>
<li>スケジュールされたタスクの実行を設定可能
<ul>
<li>なんでサービスで設定できないんだろう?</li>
</ul></li>
</ul>
<h2>コンテナの実行環境</h2>
<h3>EC2</h3>
<ul>
<li>EC2インスタンスをコンテナインスタンスとして配置
<ul>
<li>Amazon ECS-optimized AMI
<ul>
<li>Dockerデーモン</li>
<li>ECSコンテナエージェント
<ul>
<li>ECSコントロールプレーンと通信</li>
<li>コンテナインスタンスの管理</li>
<li>タスクの実行/停止</li>
<li>このエージェント自体もコンテナ</li>
</ul></li>
<li>など</li>
</ul></li>
</ul></li>
<li>コンテナインスタンスのドレイン(おそらくECSクラスターからのインスタンス削減)
<ul>
<li>原因
<ul>
<li>システム更新</li>
<li>エージェント/Dockerデーモン更新</li>
<li>AutoScalingのスケールイン</li>
<li>など</li>
</ul></li>
<li>ポイント
<ul>
<li>新規タスクの配置は無し</li>
<li>PENDING状態のサービスタスクは即時停止</li>
<li>RUNNING状態のサービスタスクは設定に従い停止/代替</li>
</ul></li>
</ul></li>
<li>課題
<ul>
<li>OSやエージェント類へのパッチ当て/更新</li>
<li>EC2インスタンス数のスケーリング
<ul>
<li>あと、適切なEC2インスタンスタイプの選定もある</li>
</ul></li>
</ul></li>
</ul>
<h3>Fargate</h3>
<ul>
<li>EC2インスタンスのプロビジョニングや管理が不要
<ul>
<li>パッチ当てやOSアップグレード</li>
<li>エージェント類のアップグレード</li>
<li>など</li>
</ul></li>
</ul>
<h4>コンピュート</h4>
<ul>
<li>タスク割り当てCPUとメモリ設定が比較的柔軟
<ul>
<li>0.25vCPU: Memory 0.5, 1, 2GB</li>
<li>0.5vCPU: Memory 1, 2, 3, 4GB</li>
<li>1vCPU: Memory 2, 3, 4, ..., 8GB</li>
<li>2vCPU: Memory 4, 5, 6, ..., 16GB</li>
<li>4vCPU: Memory 8, 9, 10, ..., 30GB</li>
</ul></li>
<li>CPUとメモリの割当て
<ul>
<li>タスクレベル(必須): CPU、メモリ共にハード制約</li>
<li>コンテナレベル(オプション)
<ul>
<li>cpu: コンテナ用のcpuユニット数</li>
<li>memory: ハード制約</li>
<li>memoryReservation: ソフト制約</li>
</ul></li>
<li>考え方
<ul>
<li>コンテナレベルのcpuの合計値をタスクレベルのcpuの合計値にするとよいかも</li>
<li>コンテナレベルのmemoryの合計値をタスクレベルのメモリ量に設定するとよいかも</li>
<li>memoryReservationはmemoryの半分~3/4程度の値にすると揺らぎをある程度許容できそう</li>
</ul></li>
</ul></li>
<li>EC2タイプよりは若干割高
<ul>
<li>EC2オンデマンド料金と比較して約1.17倍
<ul>
<li>特に、Spotインスタンスの方が安い</li>
</ul></li>
<li>しかし、EC2の場合、全リソースをアプリケーションに割り当てることは現実的に難しい</li>
</ul></li>
</ul>
<h4>ストレージ</h4>
<ul>
<li>レイヤストレージ
<ul>
<li>Dockerイメージの最上位レイヤとして、タスクごとに10GBを利用可能</li>
<li>書込み内容はコンテナ間で独立</li>
<li>タスク停止後には利用不可</li>
</ul></li>
<li>ボリュームストレージ
<ul>
<li>タスクごとに4GB</li>
<li>タスク定義内でボリュームマウントとして利用可能
<ul>
<li>複数のコンテナ間での共有</li>
<li>ことなるcontainerPathでのマウント</li>
</ul></li>
<li>タスク停止後には利用不可(レイヤストレージと一緒)</li>
</ul></li>
</ul>
<h4>ネットワークモード</h4>
<ul>
<li>awsvpcのみ利用可能</li>
<li>詳細は 機能 > タスク定義 > ネットワークモード の節を参照のこと</li>
</ul>
<h2>機能</h2>
<h3>タスク定義</h3>
<ul>
<li>アプリケーションを構成する1つ以上のコンテナを定義するJSON形式のテキストファイル
<ul>
<li>アプリケーション実行時は、タスク定義をインスタンス化したタスクを実行</li>
<li>パラメータを指定</li>
</ul></li>
</ul>
<h4>ファミリー</h4>
<ul>
<li>タスク定義の名前のようなもの</li>
<li>ファミリーとリビジョン番号で1つのタスク定義が特定
<ul>
<li>リビジョン番号とは?</li>
</ul></li>
<li>タスク定義を更新する際は、ファミリーの新しいリビジョンを作成する必要がある
<ul>
<li>タスク定義そのものはイミュータブル</li>
<li>実行中のタスクは更新されない</li>
<li>サービスから利用している場合はサービスの更新が必要</li>
</ul></li>
</ul>
<h4>コンテナ定義</h4>
<ul>
<li>コンテナの設定項目
<ul>
<li>名前: コンテナの名前</li>
<li>イメージ: 使用するコンテナのイメージ</li>
<li>メモリ
<ul>
<li>memory: ハード制約(これを超えたらバーストする)</li>
<li>memoryReservation: ソフト制約(これを維持するようにある程度の揺らぎは許容する)</li>
</ul></li>
<li>logConfiguration: ログドライバーの設定(awslogsなど)</li>
<li>environment: 環境変数</li>
<li>secrets: AWS Secrets Manager シークレット、AWS SSM パラメータストアのパラメータを参照</li>
<li>dependsOn: 起動依存性の設定
<ul>
<li>起動順や停止順が設定可能
<ul>
<li>START: 依存元コンテナが起動開始したら起動する</li>
<li>COMPLETE: 依存元コンテナの実行が完了(終了)したら起動する</li>
<li>SUCCESS: 依存元コンテナの実行が正常終了したら起動する</li>
<li>HEALTHY: 依存元コンテナのhealthcheckが合格したら起動する</li>
</ul></li>
<li>依存先コンテナが起動しない/異常終了する場合
<ul>
<li>startTimeout: 依存先コンテナが起動しないことを依存元コンテナが待機する時間</li>
<li>stopTimeout: 依存先コンテナが正常終了しなかった場合に強制終了されるまでの待機時間</li>
</ul></li>
<li>docker-composeのdepends_onと同等?</li>
</ul></li>
</ul></li>
</ul>
<h4>タスクロール</h4>
<ul>
<li>コンテナのIAMロール
<ul>
<li>コンテナ内のアプリケーション向け</li>
</ul></li>
</ul>
<h4>タスク実行ロール</h4>
<ul>
<li>ECSコンテナエージェントのIAMロール
<ul>
<li>コンテナのイメージのpullやCloudWatch Logsへの書込みなど</li>
</ul></li>
</ul>
<h4>ネットワークモード</h4>
<ul>
<li>コンテナのDockerネットワークモード
<ul>
<li>none: 外部との接続無し</li>
<li>bridge (default for EC2): Dockerの組込み仮想ネットワークを使用して外部ネットワークとの通信(コンテナリンク利用可)</li>
<li>host: コンテナポートとホストEC2インスタンスのNICのマッピングによる外部ネットワークとの通信</li>
<li>awsvpc (default for Fargate): タスクをECS管理下のENIに自動割当て
<ul>
<li>ENIをEC2にアタッチすることで実現するため、EC2起動タイプの場合、EC2インスタンスタイプのENI上限によってタスク配置が制限される可能性がある
<ul>
<li>ENI Trunkingを有効にすると、1インスタンスのENI上限数を上げることが可能</li>
</ul></li>
<li>タスク内のコンテナはlocalhostインタフェースを共有</li>
<li>VPC無いの他のリソースはプライベートIPでの通信が可能</li>
<li>ロードバランサーの種類
<ul>
<li>ALB</li>
<li>NLB</li>
</ul></li>
<li>VPC外へのアクセス
<ul>
<li>イメージのプル、ログ送信は可能
<ul>
<li>タスク実行ロールへのIAMロールアタッチが必要</li>
</ul></li>
<li>他は IG-(EIP)-ENI 経由で通信可能</li>
</ul></li>
</ul></li>
</ul></li>
</ul>
<h4>ボリューム</h4>
<ul>
<li>データの共有先
<ul>
<li>Dockerボリューム(EC2のみ)
<ul>
<li>タスク間での共有や明示的なライフサイクル管理が可能</li>
</ul></li>
<li>バインドマウント
<ul>
<li>ホストマシン上のファイル/ディレクトリをコンテナにマウント</li>
</ul></li>
<li>EFSボリューム
<ul>
<li>コンテナインスタンスにかかわらず、同じ永続的ストレージにアクセス可能</li>
</ul></li>
</ul></li>
</ul>
<h4>タスクサイズ</h4>
<ul>
<li>タスクに適用するハード制約
<ul>
<li>vCPU</li>
<li>メモリ</li>
</ul></li>
</ul>
<h2>コンテナの実行</h2>
<h3>コンテナの実行方法</h3>
<ul>
<li>タスク起動
<ul>
<li>タスク定義にに従う</li>
<li>バッチジョブのような、処理が終わると停止するワークロードなどに適切
<ul>
<li>Amazon Batchを使うほどでもないような低規模タスクに良い</li>
</ul></li>
</ul></li>
<li>サービス起動
<ul>
<li>指定したタスク数を維持する
<ul>
<li>ECSにおけるコンテナオーケストレーションの機能の1つ</li>
</ul></li>
<li>Webアプリケーションなどの長時間実行するアプリケーションなどに適切</li>
</ul></li>
</ul>
<h3>タスクのライフサイクル</h3>
<ol>
<li>Provisioning</li>
<li>Pending</li>
<li>Activating</li>
<li>Running</li>
<li>Deactivating</li>
<li>Stopping</li>
<li>Deprovisioning</li>
<li>Stopped</li>
</ol>
<h3>タスクの配置</h3>
<ul>
<li>タスクの配置方法を、AZやインスタンスタイプに基づいて制約を設定可能</li>
</ul>
<h3>サービススケジューラ戦略</h3>
<ul>
<li>レプリカ
<ul>
<li>クラスタ全体で必要数のタスクを分散配置</li>
</ul></li>
<li>デーモン
<ul>
<li>コンテナインスタンス毎に配置</li>
</ul></li>
<li>Amazon ECSクラスターキャパシティープロバイダー
<ul>
<li>タスク配置先のコントロールがより柔軟に可能</li>
</ul></li>
</ul>
<h3>サービスのAuto Scaling</h3>
<ul>
<li>ターゲット追跡スケーリングポリシー
<ul>
<li>指定したメトリクスの値が指定値に近づくように調整</li>
</ul></li>
<li>ステップスケーリングポリシー
<ul>
<li>アラームをトリガーに調整値に基づいて増減</li>
</ul></li>
<li>スケジュールに基づくスケーリング
<ul>
<li>日付と時刻に基づいて増減</li>
</ul></li>
</ul>
<h2>Container Insights</h2>
<ul>
<li>既存のメトリクス情報はサービス単位
<ul>
<li>タスクレベルやコンテナレベルでの負荷を検知できなかった</li>
</ul></li>
<li>料金体系
<ul>
<li>CloudWatchカスタムメトリクス費用
<ul>
<li>計算式: <code>既存のECSクラスターメトリクス8個 + (既存のECSタスクメトリクス6個 * 一意のタスク名) + (既存のECSサービスメトリクス11個 * 一意のサービス名)</code></li>
</ul></li>
<li>CloudWatch Logs費用</li>
</ul></li>
</ul>
Morichan
tag:crieit.net,2005:PublicArticle/AWS-Batch
2022-03-11T01:19:38+09:00
2022-03-11T01:19:38+09:00
https://crieit.net/boards/aws-master/AWS-Batch
AWS Batch完全に理解した
<h1>AWS Batchとは</h1>
<p>バッチコンピューティングワークロードを提供してくれるコンピューティングリソースです。</p>
<p><a target="_blank" rel="nofollow noopener" href="https://docs.aws.amazon.com/ja_jp/batch/latest/userguide/what-is-batch.html">AWS Batch とは - AWS Batch</a></p>
<h1>学習成果</h1>
<p>ほぼ下記資料の要約です。</p>
<p><a target="_blank" rel="nofollow noopener" href="https://d1.awsstatic.com/webinars/jp/pdf/services/20190911_AWS-BlackBelt-AWS-Batch.pdf">20190911 AWS Black Belt Online Seminar AWS Batch (PDF)</a></p>
<h2>バッチコンピューティングにおけるクラウド活用</h2>
<ul>
<li>このAWS Batchにおけるバッチコンピューティングとは、シミュレーションなどの高負荷処理をスパコンやクラスタなどで順次実行するような処理のことを意味する</li>
<li>定型業務におけるバッチ処理については、AWS Batchでは想定していない(!)
<ul>
<li>SQSなどによるバッチ処理の待機みたいなものを前提としている?</li>
</ul></li>
<li>多数のジョブを同時実行して処理時間を短縮する</li>
</ul>
<h2>AWS Batch: 概要</h2>
<ul>
<li>スケジューラや計算ノードなどの管理が不要</li>
<li>Dockerコンテナイメージをもとにジョブの作成</li>
<li>AWS Batchの利用自体は無料
<ul>
<li>EC2インスタンスに課金</li>
</ul></li>
<li>バッチコンピューティング環境の提供
<ul>
<li>ジョブキュー</li>
<li>コンピューティング環境</li>
<li>タイムアウト、リトライ処理</li>
</ul></li>
</ul>
<h2>AWS Batch: 他サービスの方が適しているケース</h2>
<ul>
<li>コンテナ化が難しい</li>
<li>既存のジョブスケジューラからの移行が難しい
<ul>
<li>AWS ParallelCluster</li>
</ul></li>
<li>1つのジョブが数行など短時間で終わる
<ul>
<li>AWS Step Functions + AWS Lambda</li>
<li>S3 Batch</li>
</ul></li>
<li>機械学習用と
<ul>
<li>Amazon SageMaker</li>
</ul></li>
</ul>
<h2>AWS Batch: アーキテクチャ</h2>
<h3>ジョブ定義</h3>
<ul>
<li>ジョブ作成時のテンプレート
<ul>
<li>コンテナイメージ
<ul>
<li>コンテナ内の実行コマンド</li>
<li>パラメータ</li>
<li>再試行戦略・タイムアウト戦略</li>
</ul></li>
<li>IAM Role</li>
<li>要求性能</li>
<li>など</li>
</ul></li>
</ul>
<h3>ジョブ</h3>
<ul>
<li>AWS Batchによって実行される作業単位
<ul>
<li>元となるジョブ定義</li>
<li>投入先ジョブキュー</li>
<li>コンテナイメージ</li>
<li>要求性能</li>
<li>シングルジョブ or 配列ジョブ</li>
<li>ジョブの依存関係</li>
<li>など</li>
</ul></li>
</ul>
<h3>ジョブキュー</h3>
<ul>
<li>投入されたジョブの待ち行列となる場所
<ul>
<li>実行先コンピューティング環境</li>
<li>ジョブキューの優先度
<ul>
<li>ジョブの優先度じゃなくて、キューの優先度らしい</li>
</ul></li>
</ul></li>
</ul>
<h3>コンピューティング環境</h3>
<ul>
<li>実際に計算を行うECSクラスター
<ul>
<li>マネージド or アンマネージド</li>
<li>AMI</li>
<li>EC2起動テンプレート</li>
<li>オンデマンド or スポット</li>
<li>最小vCPU数、最大vCPU数
<ul>
<li>最小vCPU数を0に設定すると、ジョブのない時はインスタンスを起動しないことが可能</li>
</ul></li>
<li>許可されたインスタンスタイプ</li>
<li>VPC, Subnet, SecurityGroup</li>
<li>など</li>
</ul></li>
</ul>
<h3>コンテナレジストリ</h3>
<ul>
<li>Dockerコンテナイメージ置き場
<ul>
<li>ECR</li>
<li>Docker Hub</li>
<li>など</li>
</ul></li>
</ul>
<h3>ストレージ</h3>
<ul>
<li>永続化が必要なデータの保存先
<ul>
<li>S3
<ul>
<li>基本的には第1候補</li>
<li>マウントして扱うことができない</li>
</ul></li>
<li>EFS
<ul>
<li>NFSによりマウント可能</li>
<li>パフォーマンスが利用要領に依存する</li>
</ul></li>
<li>FSx for Lustre
<ul>
<li>マウント可能かつ高スループットでS3とも連携可能</li>
<li>専用クライアントが必要なために独自AMIの作成が必要</li>
</ul></li>
</ul></li>
</ul>
<h2>AWS Batch: 機能</h2>
<h3>機能説明</h3>
<ul>
<li>ジョブの状態遷移
<ol>
<li>Submitted<br />
1.1 Pending(遷移しない場合もある)</li>
<li>Runnable
<ul>
<li>EC2インスタンスの状態を待っている状態</li>
<li>ジョブの要求リソースが確保できない場合はここで停止する</li>
</ul></li>
<li>Starting(遷移しない場合もある)</li>
<li>Running</li>
<li>Succeeded or FAILED</li>
</ol></li>
<li>ジョブの順序
<ul>
<li>配列ジョブ
<ul>
<li>複数の子ジョブを作成可能</li>
<li>子ジョブは自分の配列IDを取得可能</li>
</ul></li>
<li>ジョブ依存関係
<ul>
<li>依存関係に指定したジョブが完了したら実行可能になる</li>
</ul></li>
</ul></li>
</ul>
<h3>機能</h3>
<ul>
<li>Amazon SNSにジョブ状態の変化を通知可能</li>
<li>ジョブパターンの種類を設定可能
<ul>
<li>集約パターン</li>
<li>前処理パターン</li>
<li>シーケンシャルパターン</li>
</ul></li>
<li>マルチノードによる並列ジョブも作成可能</li>
</ul>
<h2>活用方法</h2>
<ul>
<li>ジョブの投入方法
<ul>
<li>マネージメントコンソールから</li>
<li>CLIから</li>
<li>S3へのファイルアップロードをトリガーにしたAWS Lambdaから</li>
<li>Amazon EventBridgeから</li>
</ul></li>
<li>スポットインスタンスを活用するとよい
<ul>
<li>優先度の低いスポット用ジョブキューと優先度の高いオンデマンド用ジョブキューを分ける</li>
<li>スポット用バッチが失敗した場合にSNS経由でオンデマンド用バッチを実行する</li>
</ul></li>
<li>複雑なジョブワークフローにはAWS Step Functionsと併用するとよい</li>
<li>基本的に、バッチ実行中に落ちてしまった場合のことを考える必要がある
<ul>
<li>冪等である必要がある</li>
<li>一度失敗してもやり直すだけでよい仕組みである必要がある</li>
</ul></li>
</ul>
Morichan
tag:crieit.net,2005:PublicArticle/DynamoDB
2022-03-10T03:32:01+09:00
2022-03-12T01:05:09+09:00
https://crieit.net/boards/aws-master/DynamoDB
Amazon DynamoDBを完全に理解したかった
<h1>Amazon DynamoDBとは</h1>
<p>キーバリュー型のデータベースです。<br />
よくLambdaで使うデータベースとして使われるイメージがあります。</p>
<p><a target="_blank" rel="nofollow noopener" href="https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/Introduction.html">Amazon DynamoDB とは - Amazon DynamoDB</a></p>
<h1>学習成果</h1>
<p>導入効果は高いものの、ハードルは高いというイメージが強くなりました。</p>
<h2>テーブル設計基礎知識</h2>
<p>ほぼ以下の用語に関する要約です。</p>
<p><a target="_blank" rel="nofollow noopener" href="https://d1.awsstatic.com/webinars/jp/pdf/services/20170809_AWS-BlackBelt-DynamoDB.pdf">AWS Black Belt Online Seminar 2017 Amazon DynamoDB (PDF)</a></p>
<ul>
<li><strong>Table(テーブル)</strong>: RDBのテーブルと同等</li>
<li><strong>Item(項目)</strong>: テーブル内の1行、RDBのレコードと同等</li>
<li><strong>Attribute(属性)</strong>: 行内の1要素、RDBのフィールドと同等</li>
<li><strong>Partition Key (PK)</strong>: いわゆる主キー</li>
<li><strong>Sort Key (SK)</strong>: いわゆるセカンダリキーで、 PK+SK で主キーとすることが可能
<ul>
<li>ソートするためのキー、というわけではない</li>
</ul></li>
<li><strong>Local Secondary Index (LSI)</strong>: SK以外のセカンダリキー
<ul>
<li>PK(+SK)の親テーブルとは別に、内部ではPK+LSIのテーブルとして保持される</li>
<li>「ローカル」というのは、1つのパーティション内で完結する項目のみを対象とする(ように自動的に配置される)という意味で呼んでいる</li>
<li>LSIを増やせば増やすほど、テーブルがまるまる1つ増えることになる
<ul>
<li>親テーブルとの結果整合性には短い伝播遅延があるが、基本的には同じデータを持つ</li>
</ul></li>
</ul></li>
<li><strong>Global Secondary Index (GSI)</strong>: PK以外の主キー
<ul>
<li>PK(+SK)の親テーブルとは別に、内部ではGSI(PK+SK)のテーブルとして保持される</li>
<li>「グローバル」というのは、全てのパーティションを検索する可能性がある(対象の親テーブルは1つ)という意味で呼んでいる</li>
<li>GSIを増やせば増やすほど、テーブルがまるまる1つ増えることになる
<ul>
<li>親テーブルとの結果整合性には短い伝播遅延があるが、基本的には同じデータを持つ</li>
</ul></li>
</ul></li>
<li><strong>Query(クエリ)</strong>: データ抽出操作方法の1つ
<ul>
<li>ページサイズと呼んでいる1MBサイズ上限で検索結果を取得できる
<ul>
<li>ページ内に目的のデータが存在しない場合は、次ページの検索を引続き実行する</li>
</ul></li>
<li>理想的には、こちらのみを使ってデータを抽出することが望ましい</li>
</ul></li>
<li><strong>Scan(スキャン)</strong>: データ抽出操作方法の1つ
<ul>
<li>単一のスキャンにより、最大で (1ページサイズ / 4KB項目サイズ) / 2 = 128RCUを消費する(結果整合性のある読込みの場合)</li>
<li>テーブル全体を読込むため、余計なデータを抽出してしまう</li>
</ul></li>
</ul>
<h2>性能の算出方法</h2>
<p>ほぼ以下の用語に関する要約と、理解しづらかった箇所の補足です。</p>
<p><a target="_blank" rel="nofollow noopener" href="https://d1.awsstatic.com/webinars/jp/pdf/services/20170809_AWS-BlackBelt-DynamoDB.pdf">AWS Black Belt Online Seminar 2017 Amazon DynamoDB (PDF)</a></p>
<p>ただ、性能の算出方法については、用語が多すぎて理解しづらかったです。<br />
公式ドキュメントの方も読みましたが、英語で読んでも難しい......。</p>
<p><a target="_blank" rel="nofollow noopener" href="https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/HowItWorks.ReadWriteCapacityMode.html">読み込み/書き込みキャパシティーモード - Amazon DynamoDB</a></p>
<h3>Item size(項目サイズ)</h3>
<ul>
<li>単位</li>
<li>読込み・書込み時に、1回で取扱い可能なデータのサイズ</li>
<li>読込み: 最大4KB</li>
<li>書込み: 最大1KB</li>
<li>少数による分割は不可であり、少数になる場合は繰上げ
<ul>
<li>E.g.) 2.2KBのデータの場合
<ul>
<li>読込み: 2.2 / 4 = 0.55 -> 1 Item size</li>
<li>書込み: 2.2 / 1 = 2.2 -> 3 Item size</li>
</ul></li>
</ul></li>
</ul>
<h3>RCU (Read Capacity Unit)</h3>
<ul>
<li>単位</li>
<li>スループット(読込み数)を表す</li>
<li><strong>1秒間あたり</strong>の読込み項目数 * 項目サイズ
<ul>
<li>単位の中に「毎秒」というものが暗黙的に含まれている</li>
</ul></li>
<li>1RCUとは、1秒間あたり最大4KBのItemデータを1回読込み可能であることを表す</li>
</ul>
<h3>WCU (Write Capacity Unit)</h3>
<ul>
<li>単位</li>
<li>スループット(書込み数)を表す</li>
<li><strong>1秒間あたり</strong>の書込み項目数 * 項目サイズ
<ul>
<li>単位の中に「毎秒」というものが暗黙的に含まれている</li>
</ul></li>
<li>1WCUとは、1秒間あたり最大1KBのItemデータを1回書込み可能であることを表す</li>
</ul>
<h3>Capacity Unit(キャパシティーユニット)</h3>
<ul>
<li>RCUとWCUをまとめたもの
<ul>
<li>両者は合算可能</li>
</ul></li>
<li>文脈によっては、スループットと読替え可能</li>
</ul>
<h3>Throughput(スループット)</h3>
<ul>
<li>読込み・書込み時の処理可能なデータ量</li>
<li>RCUやWCUの数値(逆数)と考えても間違いではない</li>
<li>読込み・書込みスループットがn倍とは、RCUやWCUが1/n倍という意味</li>
</ul>
<h3>Provisioned Capacity</h3>
<ul>
<li>事前に設定するキャパシティーユニットの数値</li>
<li>DynamoDBの設定値の1つ</li>
<li>キャパシティーユニットとは若干意味が異なるくせに、文脈によってはキャパシティと書かれるし、Provisioned Throughputと同義で書かれることもある</li>
<li>今はオンデマンドモードによる自動的なスケーリング機能があるから、今後は考えなくても良くなりかも</li>
</ul>
<h3>Provisioned Throughput</h3>
<ul>
<li>事前に設定するスループット
<ul>
<li>スループットの数値を直接指定はできないが、Provisioned Capacityは指定できるため、それを指している?</li>
<li>文脈によってはスループットと書かれるし、キャパシティと同義で書かれることもある</li>
</ul></li>
</ul>
<h3>パーティション</h3>
<ul>
<li>テーブルを論理的に分割した際の、分割された物</li>
<li>文脈によっては、単位として読替え可能</li>
<li>1つのパーティションでは、3000RCUまたは1000WCU分のスループットを割当て可能
<ul>
<li>「または」というのは、RCUとWCUの片方どちらかしか割当てられないという意味ではない
<ul>
<li>RCUとWCUの数値の数に応じて、パーティションごとに割合を変えたうえで両方割当てられる</li>
</ul></li>
</ul></li>
<li>1つのパーティションでは、約10GBのデータを保存可能
<ul>
<li>「約」ってなんだよと思うが、そう書いてあるから仕方ない</li>
</ul></li>
<li>パーティションをいじることはできない(ブラックボックス)が、算出は可能
<ul>
<li>8GBのデータサイズ、5000RCU、500WCUの場合(恐らくRCUとWCUの値は事前設定の値)
<ul>
<li>スループットあたり必要なパーティション: 5000 / 3000 + 500 / 1000 = 1.67 + 0.5 = 2.17 -> 3</li>
<li>データサイズあたり必要なパーティション: 8 / 10 = 0.8 -> 1</li>
<li>最大値: MAX(1 | 3) = 3
<ul>
<li>すなわち、3つのパーティションに分割される</li>
</ul></li>
<li>RCUとWCUの値 (Provisioned Capacity) は均一に割当てられる
<ul>
<li>RCU: 5000 / 3 = 1666.67</li>
<li>WCU: 500 / 3 = 166.67</li>
<li>データ: 8 / 3 = 2.66</li>
<li>注意: 1つの項目に2000RCUとか実測値で出てしまうような場合、1パーティションで捌ききれず破綻(バースト)する</li>
</ul></li>
</ul></li>
</ul></li>
<li>Provisioned Capacity変更時の注意
<ul>
<li>増やす場合: 各パーティションの余裕を超えるまでは変化なし、余裕を超えた場合はパーティション追加</li>
<li>減らす場合: 各パーティションのCapacity削減(パーティションは減らない!)</li>
<li>テーブル作り直した方がいいのでは?</li>
</ul></li>
</ul>
<h2>NoSQLデータモデリング</h2>
<p>ほぼ以下の要約です。</p>
<p><a target="_blank" rel="nofollow noopener" href="https://d1.awsstatic.com/webinars/jp/pdf/services/20181225_AWS-BlackBelt_DynamoDB.pdf">AWS Black Belt Online Seminar 2018 Amazon DynamoDB Advanced Design Pattern (PDF)</a></p>
<h3>基本的な考え方</h3>
<ul>
<li>RDBでよくある正規化は、DynamoDBでは(ひいてはNoSQLでは)するべきではない</li>
<li>入力と出力の数に応じて切り分ける
<ul>
<li>1 : 1
<ul>
<li>PK or GSI(PK+SK)によるデータ抽出</li>
</ul></li>
<li>1 : n
<ul>
<li>PK+SK or GSI(PK+SK)によるデータ抽出</li>
</ul></li>
<li>n : m
<ul>
<li>PK+SKとGSI(PK+SK) or PK+SKの複数テーブル</li>
</ul></li>
<li>あれ、LSIは......?
<ul>
<li>1 : n で利用するSKを複数用意できるという意味では、テーブルを1つに抑えつつ複数のSKで 1 : n の検索ができるかも</li>
</ul></li>
</ul></li>
</ul>
<h3>Targeting queries: クエリの限定</h3>
<ul>
<li>Query filter
<ul>
<li>フィルター条件を使用する</li>
</ul></li>
<li>Composite key
<ul>
<li>キーになるデータを文字列結合した上で1属性化する</li>
<li>正直いけてないように思えるけど、文字列結合じゃなくてJSON辞書型にすればいいのかも?
<ul>
<li>でもそれを明記してないってことは、こっちのほうがイケてないって意味なんだろう</li>
<li>キー名の決め方が大変そうだ</li>
</ul></li>
</ul></li>
<li>Sparse indexes
<ul>
<li>属性を空にできるキーをGSIとすることで、GSIのテーブルの項目をそもそも削減する</li>
</ul></li>
<li>フィルターの代わりにインデックスを活用
<ul>
<li>名前の通り、フィルターで検索結果を削減するよりインデックスキーを使いましょうとのこと
<ul>
<li>フィルターでは通信量の削減はできない</li>
</ul></li>
</ul></li>
</ul>
<h3>GSI Overloading: GSIの多重定義</h3>
<p>GSIは親テーブルあたりデフォルト20までしか作成できないため、1つのGSIで複数の用で利用できるように定義する方法です。</p>
<ul>
<li>RDB
<ul>
<li>プライマリキーに社員ID、インデックスに名前、取得したいデータに勤務地、といった形の構造を作る</li>
<li>この時、勤務地で検索したくなった場合は、勤務地をインデックスとしたテーブルを作る</li>
</ul></li>
<li>DynamoDB
<ul>
<li>そもそも、PKは社員IDとして同じだが、SKはカラムAという形にして、値として名前や勤務地という構造を作る
<ul>
<li>PKに同じ値を設定できるという仕組みを活用する</li>
<li>その際の取得したいデータは、PK+SKで求まるデータ(RDBでいうインデックス名前の値)を入れる</li>
</ul></li>
<li>GSI作成時には、カラムAをPK、データをSKとする</li>
</ul></li>
</ul>
<h3>メッセージアプリの巨大項目</h3>
<p>メッセージ内容のようなデータサイズの変動が大きいキーについては、素直に別テーブルとするのが良いみたいです。</p>
<h2>GSIの使用パターン</h2>
<p>下記記事の要約です。</p>
<p><a target="_blank" rel="nofollow noopener" href="https://aws.amazon.com/jp/blogs/news/how-to-use-dynamodb-global-secondary-indexes-to-improve-query-performance-and-reduce-costs/">DynamoDB グローバルセカンダリインデックスを使用してクエリのパフォーマンスを向上させ、コストを削減する方法 | Amazon Web Services ブログ</a></p>
<h3>複数の属性によるデータのクエリとソート</h3>
<ul>
<li>フィルタリング属性をPKとしたデータの取得ができる
<ul>
<li>通常のフィルタリング機能では通信量を削減できない</li>
</ul></li>
<li>常にPKがソート済みのデータを取得できる
<ul>
<li>クエリ結果の順序は自動的にソートされる</li>
</ul></li>
<li>ソートキーで範囲を制限できる
<ul>
<li>フィルタリング機能とは別?</li>
</ul></li>
</ul>
<h3>RCUの通信量削減</h3>
<p>詳細情報を全てテーブルに記入しつつ、よく検索するキーを別にGSIで指定することで通信量を削減できるみたいです。</p>
<h3>読取りワークロードの分離</h3>
<p>互いに影響しないアクセスパターン(恐らくSKやフィルター機能などで検索対象が被らないようなクエリのこと?)がある場合に、親テーブルと同じPKを指定するGSIを作成しても効果があるらしいです。</p>
<h2>ベストプラクティス</h2>
<p>下記ドキュメントのうち、気になった部分をかいつまんで要約してます。</p>
<p><a target="_blank" rel="nofollow noopener" href="https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/best-practices.html">DynamoDB を使用した設計とアーキテクチャの設計に関するベストプラクティス - Amazon DynamoDB</a></p>
<h3>パーティションキーの設計: 書込みシャーディング</h3>
<ul>
<li>ランダムなサフィックスを使用して、PKへの書込みを分散させる
<ul>
<li>例えば、同じ日付のPKを持つ項目を追加する場合でも日付文字列の後ろにランダムな文字列を追加することで、書込み対象のパーティションを分散できる</li>
<li>上記ランダムな文字列に、別のSKなどから生成したハッシュを用いれば、読込み時にも項目の特定が可能になる</li>
</ul></li>
</ul>
<h3>パーティションキーの設計: データの効率的なアップロード</h3>
<ul>
<li>複数のデータを一度に登録する際、PK固定で項目を1つずつ登録するより、PKを分散させながら登録するとよい
<ul>
<li>PKごとの項目登録先パーティションを分散できる</li>
</ul></li>
</ul>
<h3>ソートキーの設計</h3>
<ul>
<li>begins_with, betweenなどのクエリを利用できるようなSKを設計するとよい
<ul>
<li>E.g.) <code>[country]#[region]#[state]#[county]#[city]#[neighborhood]</code></li>
</ul></li>
<li>バージョンコントロールでのSK
<ul>
<li>データを更新するたびに、バージョン番号を付与したSKを持つ項目 <code>v1_hoge</code> を作成し、最新版を表す項目 <code>v0_hoge</code> を最新版に上書きする
<ul>
<li>最新のデータを取得したい場合は <code>v0_</code> でクエリを限定して取得できる</li>
<li>任意のデータの全履歴を取得したい場合は <code>hoge</code> でクエリを限定して取得した上で <code>v0_</code> を除外することで取得できる</li>
</ul></li>
</ul></li>
</ul>
<h3>セカンダリインデックス: 一般的なガイドライン</h3>
<ul>
<li>インデックス数は最小限に抑える</li>
<li>インデックスサイズは最小限に抑える(1KB単位であるため、1KB未満であればサイズの変化は無い)</li>
<li>ほとんど必要にならない属性は設定しない
<ul>
<li>別テーブルに分離した方がよい</li>
</ul></li>
<li>ALLクエリは、異なるソートキーによってソートされるテーブル項目全体を取得する場合にのみ利用する</li>
<li>クエリで取得したい属性を計画しておく
<ul>
<li>計画されていない属性をクエリ検索する際、テーブル全体を読取る可能性があり、通信量が増える</li>
</ul></li>
</ul>
<h3>セカンダリインデックス: スパースなインデックス</h3>
<ul>
<li>スパースなインデックス: 項目に存在しない可能性があるソートキーのこと</li>
<li>スパースなインデックスをGSIのPKに設定することで、通信量を削減できる</li>
</ul>
<h3>セカンダリインデックス: 集計データ</h3>
<ul>
<li>集計データのキーをGSIに設定し、親テーブルのPKに対する項目が追加されるごとにDynamoDB StreamsからLambdaを起動してGSIの項目を追加するフローを確立することで、スパースなインデックスをGSIのPKに設定でき、WCUを削減できる</li>
</ul>
<h3>セカンダリインデックス: レプリカの作成</h3>
<ul>
<li>親テーブルのPKと同じキーをGSIのPKに設定することで、GSIを利用したレプリカテーブルを作成できる</li>
<li>親テーブルに比べてGSIの整合性には伝播遅延がある</li>
<li>GSIのPKは親テーブルのPKと同じキーを設定したうえで、GSIのSKを別キーにすることで、親テーブルから読取る項目を削減できるレプリカテーブルを作成できる</li>
</ul>
<h3>大きな項目</h3>
<ul>
<li>Binary属性タイプを使えば、GZIPやLZO圧縮によるバイナリデータをDynamoDBに登録できる</li>
<li>S3にオブジェクト識別子を登録するのも良い</li>
</ul>
<h3>時系列データ</h3>
<ul>
<li>基本的に、アプリケーション1つに対してテーブルは1つであることが望ましい</li>
<li>時系列データの場合は、期間ごとにテーブルを作ると最適に処理できる</li>
<li>期間終了前に、次の期間でテーブルを事前に作成する</li>
<li>期間終了後に新しいテーブルにリダイレクトする</li>
<li>テーブルの書込みが減ったら、プロビジョンドキャパシティを削減する</li>
<li>ほとんど必要ないと判断したデータのテーブルは、アーカイブするか削除する</li>
<li>E.g.
<ul>
<li>当月
<ul>
<li>WCU700, RCU300</li>
</ul></li>
<li>先月
<ul>
<li>WCU1, RCU100</li>
</ul></li>
<li>昔
<ul>
<li>WCU1, RCU1</li>
</ul></li>
</ul></li>
</ul>
<h3>多対多の関係</h3>
<ul>
<li>隣接関係のリスト設計パターン
<ul>
<li>E.g.) 多対多の関係があるエンティティA, B(AとBは親子関係)
<ul>
<li>親テーブルのPKとSKの両方にキーA, Bを登録し、キーAがPKの場合はAとBの値をSKに、キーBがPKの場合はBの値のみをSKに登録する</li>
<li>親テーブルのSKをGSIのPKに設定することで、GSIからBをキーとして検索すると、Bに関連するAが全て抽出できる</li>
</ul></li>
</ul></li>
<li>マテリアライズドグラフパターン
<ul>
<li>簡易的なグラフ指向DBを実装できる</li>
<li>複雑なグラフ指向DBが必要な場合はAmazon Neptuneの使用を推奨する</li>
<li>正直、理解できなかった......</li>
</ul></li>
</ul>
<h3>リレーショナルモデル化</h3>
<p>正直、この記事を読んだ方が理解は早いと思います。</p>
<p><a target="_blank" rel="nofollow noopener" href="https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/bp-relational-modeling.html">DynamoDB でリレーショナルデータをモデル化するためのベストプラクティス - Amazon DynamoDB</a></p>
<ol>
<li>データのアクセスパターンを整理する</li>
<li>欲しいデータのPKとなるキーを複数決める</li>
<li>決まった複数キーを被らないように登録フォーマットを定め、PKとする</li>
<li>PKに紐づけるSKとなるキーを、PKの各キーごとに複数決める</li>
<li>決まった服すーを被らないように登録フォーマットを定め、SKとする</li>
<li>親テーブルのSKをPKに、データをSKとするGSI1を設定する</li>
<li>集計データが必要な場合、ランダムな値をPKに、期間をSKとするGSI2を設定する</li>
</ol>
<h3>クエリとスキャン</h3>
<ul>
<li>スキャンはテーブル全体を読込むため、テーブルサイズに比例して時間も費用もかかる
<ul>
<li>フィルターは読込み後に結果を削減するため、通信量の削減にはならない</li>
<li>なるべくスキャンは避けて、クエリを利用するべき</li>
</ul></li>
<li>大量データへのスキャンによるスパイク回避方法
<ul>
<li>ページサイズを削減する
<ul>
<li>目的のデータが見つからなければ、何度も通信する必要がある事には変わらない</li>
</ul></li>
<li>スキャン対象のテーブルを分離する</li>
<li>並列スキャンを活用する
<ul>
<li>大量のリクエストが発生する可能性がある</li>
</ul></li>
</ul></li>
</ul>
Morichan