AWS 認定トレーニング「Planning and Designing Databases on AWS」を受講しました
お疲れさまです。とーちです。
AWS 認定トレーニング「Planning and Designing Databases on AWS」を受講したので、内容のレポートや感想などをお伝えしようと思います。
概要
AWS における様々な DB サービスの特徴や設計上の考慮点、各 DB でのデータ設計の考え方まで学べる、盛りだくさん、かつ、素晴らしい内容になっています。
このトレーニングを受ければ AWS において DB の最適な選択ができるようになること間違いなしです。
とても学びが多いトレーニングだったのでぜひ多くの方にお薦めしたい内容になっています。
トレーニングは座学の部分とラボというハンズオン部分がいいバランスで配置されており、3日間という比較的長期間の内容ですが、終始集中して臨むことができました。 以下、ラボの内容になります。
- Amazon RDS データベースを使用する
- Amazon Aurora データベースを使用する
- Amazon DocumentDB データベースを使用する
- Amazon DynamoDB テーブルを使用する
- Amazon Redshift クラスターを使用する
ハンズオンにはない座学のみの DB サービスに関しても、講師の方がデモを見せてくださったので理解しやすかったです。(このあたりは同じトレーニングでも講師の方により異なるかもしれません)
なお、こちらのトレーニング、現在クラスメソッドのメンバーズプレミアムサービスに入っているとなんと 半額 で受けられるようになっています。
この機会にぜひとも受講してみてはいかがでしょうか?
開催スケジュールの確認やお申込みなどは以下 URL をご参照ください。
以降、座学部分についてのレポートになります。
モジュール1 Database Concepts and General Guidelines
クラウド内のデータベース
- 6 つの利点
- 変動支出
- スケールメリット(規模の経済)
- キャパシティ予測不要
- ビジネススピード向上
- ビジネスに集中
- 数分でデプロイ
- オンプレ DB とクラウドの比較
- オンプレ
- コスト:資本支出
- 人件費:HW 保守、設定、NW 管理、DB 管理
- セキュリティ:HW も含め企業で管理
- EC2
- コスト:従量課金
- 人件費:開発者、DB 管理、システム管理
- セキュリティ:企業と AWS で共同管理
- RDS
- コスト:従量課金
- 人件費:開発、DB 管理
- セキュリティ:企業と AWS で共同管理
- オンプレ
- DB タイプ
- リレーショナル
- 非リレーショナル(key-value)
- 非リレーショナル(ドキュメント)
- 非リレーショナル(インメモリ)
- 非リレーショナル(グラフ)
- 非リレーショナル(台帳)
DB 設計に関する考慮事項
- 従来のアプリは一つのシステムに一つの DB が紐付いていた(モノリシックな形。給与、ERP 等業務システムごとに DB が存在)
-
インターネット規模のアプリケーションの特徴
- スマホや IoT からもアクセス
- 取り扱うデータ種類やデータ量も増える
- 一つの DB だけでまかなうのは難しい
- インターネット時代の DB アーキテクチャ
- データをどう分散させるか
- 接続は複数インスタンスに分散
- 可用性を維持するためのスケーラビリティ
- DB のスケーリング
- スケールアップ:インスタンスサイズを大きく
- スケールアウト:数を増やす
- データ分散方法アプローチ
- パーティション化:例:注文日付をキーにして月ごとにデータファイルを分ける
- シャーディング:一つの注文テーブルを別々のサーバに配置
- データベース分散(DB フェデレーション)
- データの用途毎に DB を分ける(例:注文 DB、顧客 DB)
- クラスタリング
- 複数の DB をクラスタ化する
- 単一の DB で全ての要件を満たすのは難しい
- CAP 定理
- システムの中で使用するデータの持ち方
- 分散 DB に対して3つの特性のうち2つまでしか満たせないという定理
- 一貫性(C):全てのシステムで同じ応答(最新データ)を生成
- 可用性(A):すべてのリクエストで応答を確実に受け取る(一部ノードが落ちても他ノードが応答できるか)
- 分断体制(P):ネットワークの分断に耐えられるようにする
- 例えば分断体制を必須とする場合、一貫性か可用性どちらかしか選べない
- CA の例
- よくある同期プライマリスタンバイ構成
- 一貫性:スタンバイとの同期完了してから更新完了応答を返せば、スタンバイでも一貫した応答
- 可用性:プライマリが落ちてもスタンバイにアクセスできる
- 分断耐性:NW が切れたら終わり
- よくある同期プライマリスタンバイ構成
- AP の例
- 非同期型のプライマリスタンバイ
- 非同期なので一貫性は保てない
- 分断耐性は非同期型なので同期することを保証していないがゆえに NW 分断してもプライマリを使い続けられる
- 非同期型のプライマリスタンバイ
- CP の例
- いわゆるシャーディング
- 一貫性はデータが別々なので常に最新になる
- 分断耐性:ネットワークが DB 間には必要ない
- 可用性:一つの DB が落ちたらその DB にあるデータが参照できなくなる
- いわゆるシャーディング
- CA の例
- 分散 DB に対して3つの特性のうち2つまでしか満たせないという定理
- 一貫性にこだわると・・
- NW 遅延・障害の影響を受けやすい=障害に弱い
- 一貫性の要件に応じて、サブシステム毎に DB とアプリを分割してサブシステムの中で一貫性をもたせる
- 数秒の遅延を許容:非同期レプリ+オンメモリキャッシュ
- 数時間の遅延:KVS と RDBMS、DWH で構成
- アプリケーションで必要な一貫性レベルは業務要件と関連が深い
- システムの中で使用するデータの持ち方
- PIE 定理(DB 機能に重点をおいた設計のトレードオフ)
- P:パターン(クエリ)の柔軟性:表の中のデータを order や sum などで柔軟に組み替える機能があるか等
- I:無限のスケール(アウト):システムが制限なく適切にスケールできる
- E:効率:レスポンスタイムのこと、クエリ投げてからどれくらいで結果が返るか
- 上記の3つを同時に満たすのが難しい
- PE の例
- RDBMS
- SQL によりパターンクエリ機能をもつ
- 効率:おおむね良好
- スケール:台数増やしてスケールが難しい
- RDBMS
- IE の例
- 非リレーショナル、e コマース、ストリーミングシステム(DynamoDB)
- パターンクエリを諦めて、スケールアウトとレスポンスを重視したもの
- 非リレーショナル、e コマース、ストリーミングシステム(DynamoDB)
- PI の例
- redshift
- レスポンスタイムを犠牲にする
- 非常に大量のデータからクエリをかける
- そもそも大量データをターゲットにしている DB
- redshift
- PE の例
- 用途に応じて適材適所の DB を採用するのが重要
- CAP 定理
トランザクションコンプライアンス
- DB 用語
- トランザクション:
- リレーショナル DB:DB に対して実行される処理の開始から終了までの一連のクエリをまとめたもの、コミットの単位
- 非リレーショナル DB:putItem,UpdateItem などの個々のコマンドがトランザクション単位
- トランザクション特性の適用
- ACID:データにロックをしてデータの整合性を強力に維持する仕組み
- 原子性
- 整合性
- 分離性
- 耐久性
- BASE:非リレーショナルで使う
- 基本可用性:1つのシステムで変更がすぐに利用可能になる
- 柔軟な状態:部分的整合性を許容
- 結果整合性:一時的に一貫性のない状態を受け入れる
- ACID:データにロックをしてデータの整合性を強力に維持する仕組み
- あくまでもよく使われるというだけで、必ずしもリレーショナル= ACID、非リレーショナル= BASE ではない
- トランザクション:
モジュール 2 Database Planning and Design
ワークロード要件
- DB ワークロード:どういうリクエストが飛んでくるかを把握する
- データストレージ(DB 使う必要があるか)
- 非構造化データ、1データの容量が大きい
- ファイルシステム
- オブジェクトストア
- データ構造が決まってる、データを一意に識別するキーがある、ブロックサイズデータ
- リレーショナルデータ
- 非リレーショナルデータ
- 非構造化データ、1データの容量が大きい
- データの使用方法(データ処理特性にあった DB を選択)
- リレーショナルデータ構造
- OLTP、OLAP
- 非リレーショナルデータ
- IoT からのセンサーデータ
- セッション状態
- リレーショナルデータ構造
- データ量、速度、種類
- データアクセス(ランダムアクセス?シーケンシャル?)
- パフォーマンス:スループット重視?レスポンスタイム重視?
- データの保持期間
- 永続的に保存
- 1時間経ったら削除など
- 耐久性、可用性
- データが必ず保管場所にあること=耐久性
- 必要なときにデータにアクセスできる=可用性
- サーバ:AZ:リージョン単位で検討
- 復旧時間、許容できるダウンタイムも重要
- データストレージ(DB 使う必要があるか)
設計上の考慮事項
- 設計の基準
- パフォーマンス
- 必要なレイテンシ、IOPS、スループットなど
- キャパシティとスケーリング
- 過去を振り返る、新しい要件を調査、将来の成長
- スケーリング方法:垂直 or 水平、手動 or 自動
- 高可用性
- リードレプリカ
- クラスタリング
- マルチ AZ
- マルチリージョン
- ネットワーク
- 接続の拡張が必要あるか(VPC 外からとか)
- オンプレでワークロードを維持するか
- VPN
- DirectConnect
- VPC(パブリック、プライベート)
- バックアップと復旧
- RPO:復旧ポイント
- RTO:復旧タイム
- セキュリティ、コンプライアンス
- 法令、業界のガイドライン、社内規程
- 認証認可
- データを保管する国
- パフォーマンス
- これらに基づいて設計基準を書き出す。重要なのは優先順位をつけること
モジュール 3 Databases on Amazon EC2
DB を EC2 にホストする
- EC2 に移行する理由
- 大規模移行の最初のステップ
- ライセンスの問題
- カスタムロジック、サードパーティツールの維持
- DB の不具合解消、DB の不具合があるたびに細かくパッチを当てたい
- DB 管理責任範囲
- マネージド(RDS)だとバージョンが制限されるというデメリットはあるが、まずはマネージドを検討
- EC2 だと OS パッチ、DB インストールなどユーザの責務は増える
- EC2 だと以下のコストが発生する点にも注意
- DB エンジンのライセンス費用
モジュール4 Purpose-Built Databases
AWS への移行
- データベース選択の理由
- 新しいから、ライセンスがある、使い方を知ってる ← このような理由で選んでいいのかという話
- 慣れてるメンバーが多いからという理由で RDB を選んでないか?
- どのような理由で選択すべきか
- このデータベースは使用するアプリの目的をサポートするために作られた専用の DB だから
- どういうタイミングで DB を選択し直せるか
- オンプレからクラウドの移行
- 新しいから、ライセンスがある、使い方を知ってる ← このような理由で選んでいいのかという話
- re-host,re-locate(vmware)
- オンプレの環境をそのまま AWS に移行する方法
- re-platform
- OS,DB エンジン変更
- アプリのアップグレード
- x86 から x86_64 に
- refactor
- データベースの移行
- MW 変更
- アプリコンポーネント再コード化
- アーキテクチャ再構築
- システムのユースケースを確認することから始める
- ユースケースを理解することでデータモデルが明らかになる → 適切な DB を選択できる
- 目的別 DB 選択の具体例
- airbnb
- ユーザ検索履歴:DynamoDB
- 大量データ
- セッション状態:Elasticache
- 認証・セッション管理、ユーザーフィードとメッセージングが主なユースケース
- リレーショナル:Aurora
- 部屋の予約など
- ユーザ検索履歴:DynamoDB
- samsung
- ミッションクリティカルデータ(3億ユーザのデバイスデータの保存)
- DynamoDB
- リレーショナル(所有者、保証の情報
- Aurora
- ソーシャルグラフ(アプリ内のソーシャルネットワーク作成
- デバイス状態
- Elasticache for redis
- ミッションクリティカルデータ(3億ユーザのデバイスデータの保存)
- airbnb
- AWS データベース移行
- DMS
- SCT
- Database Freedom:DB 移行プログラム
- リレーショナル DB の利点
- 使いやすさ
- データ整合性
- SQL
- ストレージ削減(データの整合性のため正規化をすることでデータ重複を排除できるため)
- 非リレーショナル DB の利点
- 柔軟性
- スケーラビリティ
- 高パフォーマンス(特定のデータモデルをターゲットにしているので目的に合う時)
- 高機能 API(目的に特化した API)
- 非リレーショナル DB を選択するのはどんなとき?
- 整合性よりもスピード
- 厳格なスキーマより柔軟なスキーマ
- データの正規化よりネイティブドキュメントストレージ
- 永続性よりスピード
- 移行を計画する
- 以下のステップで変更が必要か判断できる
- 1:現在のビジネスシステムの性質を特定する
- データに強力な整合性が必要か
- バッチかこまめなアクセスか
- レイテンシかスループットか
- 2:変更する理由があるか?
- 優先順位に従い既存アーキテクチャを吟味して、このままで問題ないか?移行したほうがいいかを検討
- ワークロードを複数のセグメント(DB)に分割できるか
- どの DB がどのワークロードを充足できるかを検討
- モノリシックな DB を小さい単位の専用 DB に分割
- ワークロードの一部をマイクロサービスに置き換えられるか
- 例:ストアドプロシージャを lambda に
- 1:現在のビジネスシステムの性質を特定する
- 以下のステップで変更が必要か判断できる
データモデリングの基本
- データモデルとは:データ構造、定義、メタデータを定義する抽象モデル
- リレーショナルデータモデル:エンティティを提供する
- 例えば、人というエンティティは名前、性別
- 非リレーショナル:アクセスパターンを提供する
- アクセスパターン、例えば key:value なら一つのキーに対してデータを書き込むなど
- データモデルタイプ
- リレーショナルモデル
- 非リレーショナル(key:value)
- 非リレーショナル(グラフ)
- 関係性を表す
モジュール5 Databases on Amazon RDS
Amazon RDS
- リレーショナル
- RDS
- 裏側は EC2
- 利点
- 管理簡単
- スケーラビリティ
- 可用性、耐久性
- 使用する理由
- バックアップ、パッチ適用、HW 管理などを AWS にオフロードできる
- onEC2 だとスケーリング、高可用性などを実現するために専用のエンジニアが必要。なので RDS
- トレードオフ
- OS にアクセスできない
- サービスの制限(例えばストレージサイズとか
- RDS で利用できるエンジン
- SQLServer
- Oracle
- Postgre
- mysql
- mariaDB
- RDS とセルフマネージド DB の違い
- 高可用性
- マルチ AZ
- プライマリとスタンバイで「同期」レプリケーションを行う
- フェイルオーバー条件
- AZ 障害
- ネットワーク接続喪失
- プライマリ上でのコンピューティングユニット障害
- プライマリ上でのストレージ障害
- データベースエンドポイント(DNS 名)を使ってアクセス
- 常にプライマリ DB にアクセス
- フェイルオーバ順序
- 障害検知
- スタンバイがプライマリに昇格
- データベースエンドポイント(DNS)更新
- 注意点
- DNS 更新されても古い方を向き続ける
- 原因:Java などで DB エンドポイントを参照してるとき JVM が IP アドレスをキャッシュしてしまう
- 対応:アプリケーションの JVM キャッシュの有効期限(TTL)を調整
- 更新パフォーマンス、同期レプリなのでループ処理で更新などすると性能低下
- 原因:同期レプリ構成なので都度スタンバイにデータ反映している
- 対応:ループ処理は1ループ毎にコミットするのでなく、ある程度のまとまりでデータ更新するよう実装
- ダウンタイム(フェイルオーバ完了までに、1,2分)
- 原因:フェイルオーバである以上必須
- 対応:許容
- DNS 更新されても古い方を向き続ける
- リードレプリカ
- 「非同期」レプリケーションする
- RR 側の反映にタイムラグ
- 書き込みが多いとラグが長くなることも
- プライマリごとに5つのリードレプリカ
- サポート
- mysql
- mariaDB
- postgresql
- oracle
- 自動で昇格しないので手動でやる必要あり
- リードレプリカの再構成も手動でやる必要あり
- 「非同期」レプリケーションする
- リードレプリカとマルチ AZ の比較
- リードレプリカの場合、別リージョンにも展開できる
- インスタンスタイプの変更は、インスタンス停止の必要あり(EC2 と一緒
- ストレージ
- 汎用 SSD
- プロビジョニンド
- マルチ AZ
- 高可用性
- モニタリング
- OS レベルメトリクス
- cloudwatch メトリクス
- CPU,ストレージ、メモリ
- I/O
- レイテンシ
- スループット
- performance Insights
- データベースのパフォーマンス・チューニングとモニタリングを行う
- 6つのエンジン全てサポートしてるが、インスタンスタイプなどで制限あり
- 最大2年間保持
- cloudwatch メトリクスに専用メトリクスが追加される
- DB ロード:AAS
- DB ロード CPU:待機イベントタイプが CPU である AAS
- DB ロード nonCPU:CPU 以外の AAS
- 主なメトリクス
- バッファプールヒット率
- ロック待ち
- 接続数
- describe-pending-maintenance-actions
- この API でメンテナンスタスク(矯正アプデ)があるか確認できる
- クォータ
- デフォルトで40インスタンス
RDS 設計上の考慮事項
- セキュリティ
- 推奨事項
- 認証認可に IAM を使用
- セキュリティグループ
- secretManager
- 推奨事項
- 暗号化
- 物理的ストレージに書き込まれるときに暗号化される
- エンベロープ暗号化
- KMS でデータキーを暗号化してデータと一緒に配置
- ログとかスナップショットも暗号化範囲に含まれる
- 転送時の暗号化
- パラメータグループを使用して SSL 接続を強制
- RDS 接続時の認証
- 通常;パスワード認証
- IAM 認証:mysql,mariaDB,postgre,Aurora で利用可能
- https://docs.aws.amazon.com/ja _jp/AmazonRDS/latest/UserGuide/Concepts.RDS _Fea _Regions _DB-eng.Feature.IamDatabaseAuthentication.html
- 事前に create user+grant する
- クレデンシャル(トークン)を API で受け取って、トークンを DB 接続時のパスワードのところに指定
- SecretManager
- バックアップと復旧戦略
- https://docs.aws.amazon.com/ja _jp/AmazonRDS/latest/UserGuide/USER _WorkingWithAutomatedBackups.html#USER _WorkingWithAutomatedBackups.BackupRetention
- 自動(システムスナップショット、
- トランザクションログも5分に一回などの頻度で自動 B/U
- バックアップウィンドウに従い取得
- バックアップウィンドウ内のどこかで実行
- 手動スナップショット
- 復元
- スナップショットから
- 指定された時刻に復元(PITR)
- どちらも新インスタンスを作成される
モジュール 6 Databases in Amazon Aurora
Amazon Aurora
- 利点
- パフォーマンス、スケーラビリティに優れる
- 高い可用性耐久性
- mysql,postgre サポート
- リレーショナル DB を再考
- 1970 年代に基本設計が完成している
- 今考えるともっとできるはず
- スケールアウト可能
- 自己修復
- AWS 既存サービス活用
- aurora 特徴
- 以下のレイヤで分離、それぞれのレイヤで独立してスケール
- コンピューティングレイヤ
- ストレージレイヤ(SSD)
- 1つのデータが3 AZ、6箇所に分散されて記憶
- protection group ごとに6つのノード
- 1 protection group は10 GB
- 2つのコピーに障害が起こっても読み書き可能
- 3つのコピーに障害が発生しても読み込みは可能
- メンバーシップチェンジ
- 自動的に障害ストレージノードを交換
- キャッシュレイヤ
- DB エンジンとキャッシュレイヤが分離
- パッチを適用するためにノードを再起動するようなときでもキャッシュが残る
- RDS との違い
- RDS は一つのディスクに全て(ログレコード、binlog,data,buffer,metadata)書く
- Aurora はログレコードだけをディスクに書く
- マスターと RR で同じストレージが共有されているのでレプリ遅延が非常に少ない
- 共有ストレージだが、バッファキャッシュにのってるようなキャッシュについては転送する必要があるので、ここで遅延が発生する
- logStructuredStorage
- システムログのような追記型ストレージ、書き込み処理は変更差分のみ
- データが書き込まれてるブロックを上書きしたりしない
- シーケンシャルに読み込める
- システムログのような追記型ストレージ、書き込み処理は変更差分のみ
- AWS サービスの活用
- lambda:ストアドプロシージャから lambda を呼び出せる
- iam ロール:DB アクセス・制御を管理
- aurora が高性能な理由
- 作業量が少ない
- 少ない I/O
- ネットワークパケット最小化
- 以前の結果をキャッシュ
- DB エンジンオフロード
- 作業量が少ない
- 設計上の考慮事項
- 最大15の RR
- DB エンジン固有のレプリケーションもサポート
- mysql
- 論理レプリ(クロスリージョンレプリケーション)
- 物理レプリ(グローバル DB)
- postgresql
- 論理レプリ
- aurora の外の postgre から、もしくは aurora から、別の postgre にレプリ
- クロスリージョンレプリとグローバル DB はないので注意
- 論理レプリ
- mysql
- シングルマスタクラスタ
- tier が低いものからプライマリに昇格
- エンドポイント
- クラスタエンドポイント:常にプライマリインスタンスを指す
- 読み取りエンドポイント:RR 群を指す
- カスタムエンドポイント:カスタムのエンドポイント
- インスタンスエンドポイント:各インスタンスのエンドポイント
- フェイルオーバ
- 単一リージョン内で自動で行われる
- rds プロキシだと瞬時に(ほぼダウンタイムなく切り替わる)
- aurora mysql クロスリージョンレプリカ
- 最大5つのセカンダリリージョン
- 各リージョンでさらに 15 この RR
- レプリケーションレイテンシは1秒以上
- 最大5つのセカンダリリージョン
- aurora mysql グローバル DB
- 遅延が少ない
- 最大5つのセカンダリリージョン
- 各リージョンでさらに15の RR
- 自動でフェイルオーバされない
- 1分未満でフェイルオーバ
- aurora のセキュリティ
- https 暗号
- 保管時暗号
- 物理ストレージに書き込まれるデータを暗号化する
- 透過的な暗号化、SQL 実行できる人に対しては暗号化は意識されない
- IAM 認証
- KMS
- データベースのクローン作成
- copy on write
- バックアップ
- 継続的増分バックアップ
- 最大35日保存
- ポイントインタイムの復元
- バックトラック
- 既存 DB を巻き戻す(72時間以内)
- aurora の特徴的機能
- 並列クエリクラスタ
- 完了までに数分〜数時間かかるクエリで最も効果がある
- ストレージから行を取得
- 列の値を抽出
- 並列クエリクラスタ
- 以下のレイヤで分離、それぞれのレイヤで独立してスケール
モジュール 7 Amazon DocumentDB (MongoDB 互換)
- ドキュメント DB とは:Key:val で表すスキーマレスで柔軟にデータを扱える DB
- 例:不動産物件情報
- 建物によりアピールポイントが異なる(バス・トイレ別とかエアコンありとか)
- こういった定型ではないデータを RDBMS に保存するのは大変。アピールポイントが増えるごとに列を増やすことになる
- スキーマがマッチしないということ
- ドキュメント DB ならキーに紐づく情報をそれぞれの ID 毎に異なる属性(列)にできるのでやりやすい
- 例:不動産物件情報
- Amazon DocumentDB(MongoDB 互換)
- 非リレーショナルはあるユースケース専用の設計になっている
- DocumentDB はドキュメント指向
- 類似は DynamoDB
- MongoDB をマネージド・サービスとして提供しているもの
- MongoDBV3.6,4,0 と互換
- MongoDB を使えるドライバで使えたりする
- MongoDB との具体的な機能差
- https://docs.aws.amazon.com/ja _jp/documentdb/latest/developerguide/functional-differences.html#functional-differences.updated-functional-differences
- https://docs.aws.amazon.com/ja _jp/documentdb/latest/developerguide/mongo-apis.html
- アーキテクチャは Aurora とよく似ている
- パフォーマンス
- PITR
- コンピューティングとストレージを疎結合化
- 小さな単位にデータを6つに分割して 3AZ に保存
- プライマリとレプリカが同じストレージを共有(データレプリ遅延が少ない)
- ネイティブ MongoDB で負荷分散、冗長化しようとするとかなり大変(データ再配置など)
- マシン毎にデータを分散配置(RAID っぽい)するような構造になっている
- エンドポイント
- クラスターエンドポイント:読み書き
- 読み取りエンドポイント:RR 群を指す
- インスタンスエンドポイント:インスタンスを指す
- レプリカセットモード:リクエストが読みか書きかを判断して自動でマスターか RR に自動接続する
- 読み込み設定のオプション
- https://docs.aws.amazon.com/ja _jp/documentdb/latest/developerguide/how-it-works.html#durability-consistency-isolation
- mongosh をつかって接続する
- insertOne でキーとバリューを指定してデータを入れる
- properties が表に相当するもの
- データを入れたタイミングで勝手に properties が出来上がる
- find でデータ参照
- find の中に条件(key:value)を入れるとそのレコードだけを参照
- update でレコード更新
- count でレコード数をカウント
- deleteOne で1レコードだけ削除、主キーを指定
- deleteMany で条件を指定して複数削除
- read プリファレンスで接続先をクエリレベルで選べる
- find().readPred("primary")みたいな使い方:この場合必ずプライマリに接続
- JSON に類似したドキュメントに保存
- プライマリキー以外の索引も作れる
- 詳しくは mongoDB ドキュメント参照
- https://www.mongodb.com/docs/v4.2/reference/operator/query/
- DocumentDB 設計上の考慮点
- 高可用性
- 自動で高可用性となるよう設定される(デフォで AZ 2つなど)
- 推奨
- AZ は3つにする
- シャーディングの兼ね合い
- コンピューティングノードは最低3つ
- AZ は3つにする
- コスト面
- テスト・開発はシングルノードクラスタも OK
- 不要なときはクラスタ停止
- リードレプリカ
- 10分くらい追加に時間がかかる
- データの反映遅延は少ない
- 他のノードとノードサイズをあわせる必要はない
- 追加した RR をプライマリに昇格することも可能
- 変更ストリーム
- ドキュメント DB に対するデータ更新をイベントとしてキャッチできる
- デフォルト無効
- modifyChangeStreams という API で有効化
- レプリカからは読み込めない(プライマリからだけ)
- イベントはデフォルト3時間保存、最大24時間
- イベント記録用のストレージの追加コストが必要
- ユースケース
- クロスリージョンレプリケーション
- 変更通知
- OpenSearch との連携
- 詳細
- https://www.twitch.tv/aws/video/510542149
- セキュリティ
- VPC(プライベートサブネット
- IAM でドキュメント DB 内要素レベルで制限
- secretManager も使える
- 暗号化
- バックアップ
- https://docs.aws.amazon.com/documentdb/latest/developerguide/backup _restore.html
- 自動スナップショット、手動スナップショット
- 手動スナップショットはクラスタパフォーマンスに影響しない
- aurora と同じ
- 最大35日間バックアップ
- PITR 使える
- 復元の考え方も aurora と同じで新しいクラスタ作成
- フェイルオーバ
- プライマリ障害時に RR の Tier が低いものに FO
- クラスター全体の数も自動調整
- まとめ
- アクセスパターン:ドキュメントデータ
- データサイズ:中 TB サイズ
- パフォーマンス:高スループット、低レイテンシ
- ユースケース
- 分析
- 製品カタログ
- CMS(コンテンツ管理システム)
- 高可用性
モジュール8 Amazon DynamoDB Tables
DynamoDB
- kye:val
- mongo のようなドキュメントは格納できないことはないがサイズに制限あり
- 利点
- サーバーレス
- パッチ適用なし
- 無限のスケール
- サーバーレス
- 対応できる課題
- トラフィックが上がってくるとスケーリングが困難に(業務継続しながらは特に
- 構成要素
- テーブル
- プライマリキー:データを一意に識別するもの、データを分散配置するための保存先決定にも使う
- データの保存先をパーティションと呼ぶのでパーティションキーとも呼ぶ
- パーティションは実質サーバらしい
- 項目:プライマリキーにひもづくもの
- 属性:一つ一つの key:value
- プライマリキー以外の属性はデータ挿入時に決める(スキーマレス
- プライマリキー:データを一意に識別するもの、データを分散配置するための保存先決定にも使う
- テーブル
- データ分散
- 複数の AZ にデータは分散配置される。
- またデータは3 AZ に冗長化
- データはパーティションキーのハッシュに基づいて分散される
- シャーディングにより実現、シャーディングのデータ再配置や管理は AWS が全部やる
- 特定のシャードのデータが増えると新しいシャードが自動で追加され、データが新しいシャードに再配置
- ルーターが dynamoDB 内部に存在。ルータが LB のように働き、アプリからのクエリをルータが受付、ハッシュ値を計算してどのパーティションかを確定し、そのパーティションにアクセスさせる
- 複合プライマリキー
- パーティション+ソート:2つのキーを使ってデータを一意に識別する
- パーティションキーでデータを格納するパーティションを決定するのは変わらない(のでパーティションのかたよりに注意)
- ソートキーはパーティションの中でソートに使われるキー。ソートキーの順でデータは格納
- 検索
- スキャンとクエリ
- スキャン:全てのパーティションにある全てのデータを検索する(その後フィルター条件に従いフィルタ)
- パフォーマンス低
- クエリ:RDB のインデックススキャンに近い。プライマリキーを指定して検索
- パーティションキーは常にイコール条件にする必要あり(特定のパーティションを指定することでパフォーマンス高
- ソートキーは等しいとか次で始まるとか条件が指定できる
- GetItem
- パーティションキーもソートキーもイコール条件で指定するやり方
- スキャン:全てのパーティションにある全てのデータを検索する(その後フィルター条件に従いフィルタ)
- スキャンとクエリ
- セカンダリインデックス
- パーティションキーとソートキーを別の項目にすることができる
- ローカル
- ベーステーブルのパーティションキーを使う必要あり
- ソートキーはベースと違うものを指定できる
- それ以外の属性値は元のソートキーは必ず含まれる、他属性は任意
- テーブル辺り最大5こまで
- テーブルの更新は同期
- ベーステーブルの WCU/RCU が使われる
- グローバル
- 任意のパーティションキー
- ソートキーはなくても OK
- 元のパーティションキーを含む
- 最大20こ
- 別表を作ってるイメージなので非同期レプリ(更新直後は最新データでない可能性
- 通常1秒以内
- 別表なので別の WCU/RCU
- 射影する属性をどこまで含めるかが重要
- デフォはベーステーブルのプライマリキーのみ
- 全ての属性を含めなくても複数回検索すればほしい情報は取れたりする
- 全て属性含めるとデータ容量もその分増えるのでコスト増
- あまり利用しない属性はセカンダリインデックスには含めないこと
データモデル
- どのようにテーブル設計するか
- リレーショナルの正規化とは異なるアプローチで設計する
- dynamo はパターンクエリが得意ではない
- アクセスパターンを特定しておくのが重要
- 可能な限り一回の問い合わせで必要な情報が取得できるようにする
- 後からテーブルの変更をかけるのではなく最初にアクセスパターンを特定して逆算でテーブル設計
- パーティションキーは常にイコールで検索する必要あり
- 検索の条件としてどのようにデータを絞り込むか(イコールなのか<か>か)
- 参考設計
- https://docs.aws.amazon.com/ja _jp/amazondynamodb/latest/developerguide/bp-modeling-nosql.html
- プライマリインデックス設計
- 範囲検索をする場合にはソートキーにするなど
- パーティションキーはデータの分散に使われるのでカーディナリティが高いデータを指定する
- セカンダリインデックス設計
- より多くのアクセスパターンを実現
- 頻繁によむデータはその属性も射影
- パーティションキーの選択
- アプリケーションのアクセスパターンに適合させるのが最重要
- 例えば顧客全ての注文取得をしたいときに注文 ID をプライマリキーにすると SCAN するしかなくなってしまう
- この場合は顧客 ID をパーティションキー、注文 ID をソートキーにするのがよい
- 例えば顧客全ての注文取得をしたいときに注文 ID をプライマリキーにすると SCAN するしかなくなってしまう
- カーディナリティが高い
- 均等に値が分散できる
- 例えば社員 ID とか
- 性別とかはカーディナリティ低のためパーティションキーには適さない
- 例えば処理日付、特定の日付に集中する可能性があり偏りが出るのでパーティションキーには適さない
- スプシなどでアクセスパターンを整理してそれをどのように実現するか(インデックス)を具体的に考える
- アプリケーションのアクセスパターンに適合させるのが最重要
- ベストプラクティス
- 関連するデータをまとめる(表の結合ができないので表を分けすぎない)
- 一つのテーブルに関連データを全て格納(非正規化)
- ソート順を使用する
- 関連項目をグループ化する
- クエリを分散する
- ホットスポットを回避するような設計
- GSI を使う
- プライマリキー以外での検索が必要になったら
- 埋め込み(データが小さい場合)
- 注文と注文明細が別れてるリレーショナルデータの場合
- dynamoDB では注文+明細テーブルにする
- 注文表に注文明細という属性をもたせる
- 注文明細属性に複数の値をもたせる
- ドキュメント型(配列とかオブジェクト型のイメージ)
- 一つの項目のサイズは400 KB までなので注意
- 注文と注文明細が別れてるリレーショナルデータの場合
- パーティションオーバーローディング
- amazon dynamoDB deep dive advanced design patterns
- https://pages.awscloud.com/rs/112-TZM-766/images/Session%203%20-%20purpose _built _database _DynamoDB _advancedDP _narita _rev.pdf
- ソートキーに複数のコンテキストを入れる
- 例えば、日付#注文番号#商品番号
- 例えば、日付#注文番号
- 各レコードの項目はソートキーごとに異なってくる
- ソートキーは前方一致ができるので日付と注文番号で検索できたりする
- amazon dynamoDB deep dive advanced design patterns
- 関連するデータをまとめる(表の結合ができないので表を分けすぎない)
- トランザクションとバッチ処理
- バッチオペレーション内の複数の操作はロールバックされずにその場で中断される
- そのため DynamoDB にもトランザクション機能ができた
- ひとつのトランザクションごとに2倍 WCU/RCU が使われる
- 1トランザクション最大25オペレーション
- 1トランザクション最大4 MB データ
- DynamoDB に ACID をもたせられるという特徴
- ユースケース
- 財務トランザクション
- 注文発想管理
- バッチ処理の利点
- 実行したとこまでは確定
- 失敗した処理だけロールバック
- 項目の有効期限
- データの有効期限が設定できる
- テーブルで TTL 属性を作る
- 削除には最大48時間かかる
- コストがかからない
- イベントとして TTL を検知して lambda でアーカイブ的なこともできる
設計上の考慮点
- その他の考慮事項
- データの保存のされ方
- 3 AZ に保管されている
- 例えば更新するとき
- 同時に3箇所書き換えようとする。
- 早いものもあれば遅いものもある
- そのため2 AZ から応答があれば完了と応答をアプリに返す
- データの一致しない状況が生まれる可能性があるということ
- 通常は1秒以内に全 AZ の整合性が取られる(結果整合性)
- 読み込みは3 AZ のうちのどれかを取り出す
- たまたま古いパーティションからデータをとると古いデータが返るかも(結果整合性の読み込み)
- 絶対に最新のデータがほしいときは強力な整合性の読み込みを使う
- 明示的にそのオプションを指定
- 処理が重い(データを複数の場所から取り出す)
- プロビジョニングモード
- ユーザ側で WCU/RCU を指定する
- RCU
- GetItem,Query,Scan
- 4 kb/項目/秒
- WCU
- PutItem,UpdateItem,GetItem
- 1kb/項目/秒
- ベストプラクティスは AutoScaling
- 自動でスケールアップ、ダウン
- https://docs.aws.amazon.com/ja _jp/amazondynamodb/latest/developerguide/AutoScaling.html
- 即応性は期待できない。ゆるやかに処理能力が変化する
- スパイクには苦手
- RCU/WCU 見積もり
- https://d1.awsstatic.com/webinars/jp/pdf/services/20170809 _AWS-BlackBelt-DynamoDB.pdf#page=32
- オンデマンドモード
- スパイクパターンにも対応
- 予めキャパシティを AWS 側が予約している
- プロビジョニングモードのほうが安くはなる
- キャパシティプランニング不要、未知、予測できないワークロードに
- リクエスト数で料金が決まる
- 必要に応じて最大でそれまでの2倍にスケールアップ
- スパイクパターンにも対応
- スケーリング参考資料
- Amazon DynamoDB スケーリングのベストプラクティス
- https://aws.amazon.com/jp/blogs/news/dynamodb-scaling-best-practice/
- アダプティブキャパシティ
- データにかたよりが発生してしまったときに使える
- デフォルト有効
- 特定のパーティションに CU の偏りが発生したときにそのパーティション以外の CU を融通して、偏りのあるところに CU を投入する
- プロビジョニング CU 範囲で上記実現
- セキュリティ
- オンデマンドフルバックアップ
- PITR
特徴的機能
- DynamoDB ストリーム
- 項目レベルの変更を時系列で保存
- リレーショナルでいうとこの redo,トランザクションログに近いもの
- lambda で受け取って Dynamo の変更トリガーで別サービスに連携
- TTL 機能とあわせて、期限切れレコードのバックアップ
- グローバルテーブル
- 内部的にストリームを使ってる
- 別のリージョンにデータをレプリケーションする
- マルチマスターテーブルとして機能するので、書き込みを複数リージョンで R/W できる
- データをあとから書き込んだものが有効(後勝ち)
- あとからアップデートした内容が有効になるので、これを許容できるかを検討すること
- DAX
- 読み込みリクエストが多いときに有効
- DynamoDB 前段に配置するキャッシュサービス
- DynamoDB 自体の RCU を消費しない
- Dyanamo はミリ秒単位だが DAX はマイクロ秒単位の応答
- 書き込み速度には影響しない
- キャッシュされてない場合の動き
- Dynamo にアクセス
- 結果をキャッシング
- 2回め移行はキャッシュから応答
- まとめ
- アクセスパターン:key:value、ドキュメント、分析
- データサイズ:上位 TB
- パフォーマンス:非常に高い
- ユースケース:セッション管理、サーバレスウェブアプリ、マイクロサービス
- ドキュメント DB との違い
- ドキュメント DB
- クエリが柔軟にかけるのでどちらかというとリレーショナル型に近い
- インデックス種類が豊富
- 全文検索
- 配列インデックス
- Orderby みたいなこともできる
- json Schema を利用してバリデーションできる
- 必須項目、長さチェック、正規表現マッチ
- ユースケース
- キーバリューより複雑でキー以外からの検索が必要になる場合
- 例えば EC サイト製品情報
- DynamoDB
- 細かい機能はない
- キャパシティユニット変更で無限にスケール
- ユースケース
- キーを指定して一意にデータを識別できる
- ドキュメント DB
モジュール9 Databases in Amazon Neptune
Amazon Neptune
- 非リレーショナル型 DB
- 特定の要件に対する専用 DB
- グラフクエリに最適化
- 現在のグラフ DB の選択肢
- 商用
- 高価
- OSS
- 可用性などの面で課題
- これらの課題を解決するために Amazon Neptune がある
- 商用
- リレーショナルモデルとグラフモデルの比較
- グラフモデル
- 数学におけるグラフ議論を指すようなもの
- なんらかの関係があるものの集合
- 点(ノード)と線(エッジ)でデータの関係を表す
- ノード間をエッジでつなぐ
- どのデータとどのデータに関連があるのかが簡単にわかる
- グラフとは
- https://ja.wikipedia.org/wiki/%E3%82%B0%E3%83%A9%E3%83%95 _(%E3%83%87%E3%83%BC%E3%82%BF%E6%A7%8B%E9%80%A0)
- グラフモデルのイメージ例
- 例えば路線図
- 例えばシステム構成図
- 例えば組織図
- リレーショナルモデルで表現しようとすると
- 複数の外部キーをもつテーブルが多くなってくる
- N:M 関係を扱うには中間テーブルが必要になる
- パフォーマンスが落ちてくる
- なので、グラフ DB が必要になってくる
- グラフモデル
- ユースケース
- 協調フィルタリング
- お薦めの商品
- SNS におけるレコメンデーション
- 中心性分析
- 誰がインフルエンサーかを判断して広告
- もっとも多数の Edge が集まっている Vertex がインフルエンサーの可能性
- 誰がインフルエンサーかを判断して広告
- 協調フィルタリング
- アーキテクチャは Aurora や DocumentDB と近い
- コンピューティングとストレージが疎結合
- グラフタイプ:プロパティ
- Vertex:エンティティまたはドメイン
- VertexID:リレーショナル DB でいうところプライマリキー
- Vertex ラベル:リレーショナル DB でいうところのテーブル
- Edge:方向関係、Edge にはラベルがつく
- Edge プロパティ:リレーショナル DB でいうところの中間表がもつようなデータ
- プロパティ:Vertex と Edge 両方につけられる。プロパティの値は自由に設定可能
- プロパティキー:リレーショナル DB でいうところの列名
- Vertex:エンティティまたはドメイン
- グラフタイプ:リソース
- 主語:
- 述語:
- 目的語:
- Neptune で使えるグラフモデル
- プロパティグラフ
- ローカルデータを扱う、外部に公開する必要がない場合
- リソース記述フレームワーク(RDF)
- 外部に公開して、ユーザに検索させたい場合
- W3C 標準
- SPARQL
- SemanticWeb:情報自体にフレームワーク
- プロパティグラフ
- Neptune WorkBench
- Jupyter ノートブックを使って Neptune にクエリを発行できる
- Gremlin クエリ、SPARQL クエリを使用できる
- グラフを可視化できる
- Jupyter ノートブックを使って Neptune にクエリを発行できる
- クエリでどんなことができるか
- 協調性フィルタリング:友達の友達を表示
- 最短経路:
設計の考慮事項
- ストレージ
- 3 AZ で6箇所へのレプリケート
- 可用性
- 書き込みクォーラム 4/6
- 読み取りクォーラム 3/6
- リードレプリカ
- 最大15こ
- すべてのレプリカがストレージを共有するのでデータ遅延がほとんどない
- インスタンスサイズはそれぞれ異なっていても OK
- データロード
- S3 から Neptune にデータコピーできる
- VPC デプロイ
- VPC に作成する必要がある
- プライベートサブネットに作成してセキュリティグループでアクセス制御
- バックアップ
- 自動バックアップ(最大35日
- 手動スナップショット
- PITR 対応
- モニタリング
- CloudWatch と統合
- データベースイベント通知
- Neptune まとめ
- アクセスパターン:グラフ
モジュール10 Databases in Amazon Quantum Ledger Database (Amazon QLDB)
Amazon QLDB
- 概要
- 非リレーショナル型
- Neptune 等と同様に特定のユースケースを満たすための専用 DB
- 台帳 DB
- データを履歴データとしてどんどん保存していくイメージ
- 履歴データ例
- 住民票
- 戸籍
- いずれも過去の履歴が残すことが必須であることが特徴
- 途中でデータが改ざんされないことも重要(システム管理者でも)
- リレーショナル DB では管理者であればデータの変更ができてしまうので、このような専用 DB が必要
- 特徴
- SQL に似たデータ操作言語が使える
- 内部のデータの持ち方がログ(追記型)の構造になっている
- データ更新、削除など操作されたときにどんどん追記で残っていく
- これが消せないような仕組みになっている=イミュータブル
- 暗号的に改ざんされてないことを検証可能
- 従来 DB での上記のような要件を実現するための課題
- リレーショナル DB では上記のような仕組みの実装は難しい
- 管理者であれば基本的になんでもできるので
- トレーサビリティ(データを追跡できること)要件もリレーショナル DB では実現困難
- QLDB の場合はビジネス要件が使用するしないの分岐点になる
- QLDB はブロックチェーンと似た仕組みが使われている
- ブロックチェーンの中でもっているデータはログのような形になっていて追記の形で記録される
- ブロックチェーン(分散型)
- 正常に動作しないサーバがいても問題ない
- 多数の参加者にデータを分散保持させる
- その NW に参加している複数のメンバー間でデータをコピーしてそれぞれのノードで同一データを保持している
- ノードを追加してブロックチェーンの NW を広げていくことができる
- 欠点
- どこかのサーバでデータの更新が発生
- データの更新の承認を受ける=これが一般的にマイニングと呼ばれる
- データの更新が確定するまでに時間がかかる
- トランザクション性能が高くない
- ブロックチェーン分かりやすいブログ
- https://www.softbank.jp/biz/blog/business/articles/201804/blockchain-basic/#:~:text=%E3%83%96%E3%83%AD%E3%83%83%E3%82%AF%E3%83%81%E3%82%A7%E3%83%BC%E3%83%B3%E3%81%A8%E3%81%AF%E3%80%8C%E5%8F%82%E5%8A%A0,%E4%BF%9D%E6%8C%81%E3%81%95%E3%81%9B%E3%82%8B%E4%BB%95%E7%B5%84%E3%81%BF%E3%80%8D%E3%81%A7%E3%81%82%E3%82%8B%E3%80%82
- 集中型
- 高頻度でデータを書き換える場合、上記の分散型よりもトランザクション性能が高いのでこちらのほうが良い
- 追記型という観点で似たようなアーキテクチャ= Aurora
- ユースケース
- 処方薬
- 保健医療系システムは投薬履歴、カルテ情報など秘匿する必要など配慮の必要がある
- 改ざんも許されない
- 厳しい規制やガイドラインが設けられている
- 上記がデータ保管場所の要件になってくる
- 処方薬
- 事例
- 会津若松で実証実験
- 行政手続き等の改善を目的
- どんなふうに QLDB を使ったか
- ヘルスケアのデータ管理で使った
- 生活習慣病のアラート等に活用
- 保険情報は機微なので QLDB を採用
- コロナワクチンの配送中の温度管理
- ワクチンが無駄にならないように各場所での温度管理が必要
- 温度データが書き換えられるのは許されない
- 上記要件のために QLDB を使用
- 会津若松で実証実験
- QLDB の概念
- 台帳
- リレーショナル DB でいうところのスキーマ、DB にあたる
- リレーショナル DB のように列定義などない
- テーブルの中にドキュメントを格納していくイメージ
- ドキュメント形式= ION
- PartiQL = SQL のようなデータ操作言語
- ビューに PartiQL でクエリを投げる
- ジャーナル
- すべての操作が履歴として残る
- 追記の形で記録
- 一度保存したデータは全て残る
- ハッシュ関数でデータ(が書き換えられてないか)を検証できる
- ビュー
- ビューを使ってジャーナルのデータにアクセスする
- 台帳
- ジャーナルの挿入
- ジャーナルに挿入される
- ビューを介してデータを参照できる
- ユーザービュー:データ参照だけできる(通常はこちら)
- コミット済みビュー:バージョン、更新日時、整合性検証のためのハッシュ値など
- 過去の履歴情報は history 関数で確認できる
- データを削除する
- ユーザービューからは見えなくなる
- history 関数では確認できる
- QLDB デモ
- マネコン上の PartiQL エディタからクエリを実行できる
- create table 〜:台帳にテーブルを作る
- select * from テーブル名:テーブルのデータを参照
- insert into テーブル名 << {json のような形}:データ挿入
- update テーブル名 set 〜:データの更新
- history :データの履歴を追うことができる
- delete from テーブル名:データの削除
- 削除しても
- ドキュメント
- blockAddress
- metadata
- 検証
- 台帳単位でダイジェストをファイルとして保存できる
- metadata の id の部分を使えば、その操作までの部分について検証も可能
- ハッシュチェーン
- ジャーナル内の隣り合ったブロックのハッシュ値も計算されているので、改ざんが難しい仕組みになっている
- ジャーナル内の途中のブロックが削除されると前後のハッシュ値が異常になる
- ジャーナル全体のサマリ情報=ダイジェスト
- データ構造とクエリ言語
- データ構造:Amazon Ion
- json ドキュメントに似ている
- データの型をドキュメント内に記述できる
- クエリ:PartiQL
- SQL を拡張したような雰囲気
- SQL に非常に似ている
- 違うところ
- リレーショナル DB の場合はフラットなデータを扱うが Ion ではネストしたデータがあるので、クエリでもネストデータを扱えるようになっている
- データ構造:Amazon Ion
- マネコン上の PartiQL エディタからクエリを実行できる
QLDB に関する設計の考慮事項
- DynamoDB と似たような構造
- DynamoDB のようなサーバーレスサービス
- API コールして台帳にアクセス
- VPC 内からアクセスする場合は VPC エンドポイントを使用
- IAM でアクセス制御ができる
- cloudwatch でモニタリング可能
- KMS での保管時暗号化可能
- ジャーナルエクスポート
- ジャーナルをエクスポートできる
- ダイジェストをエクスポート時にも生成
- 別の DB で分析をかけたい時などに使う
モジュール11 Databases in Amazon ElastiCache
Amazon ElastiCache
- 非リレーショナル型
- 特定の要件に対応するための専用 DB
- Key:Value 型
- インメモリ型 DB エンジン
- OSS の Redis と Memcached をマネージドで使える
- 比較的単純なデータをメモリ容量の範囲内で取り扱う
- なぜ必要か
- DB はシステムのボトルネックになりやすい
- DB は水平スケールも難しい場面が多い
- データ整合性や可用性を切り捨てることで高い性能を得たものが Elasticache
- パターンクエリの柔軟性は切り捨ててる
- データ耐久性も切り捨ててる
- リレーショナル DB ではコミットしたデータであればシステムダウンしても復旧可能
- 耐久性が高い仕組みではどうしてもパフォーマンス(ディスクに保存、NW でのレプリケーションなど)落ちがち
- ElastiCache 検討の指標
- 低レイテンシ要件
- 高スループット要件
- データ耐久性が低くても問題ない
- どちらかというと他の DB と組み合わせてつかう
- いわゆるホットスポットなデータを切り離して、そのデータだけを ElastiCache で扱う
- 典型的な例はセッション情報
- これによりリレーショナル DB などの DB 本体の負荷を下げる
- キャッシュで使うパターン
- DB 本体の読み込みをしなくていいようにキャッシュ層として使う
- 同じデータに頻繁に読み込みがあるようなシステム
- いわゆるホットスポットなデータを切り離して、そのデータだけを ElastiCache で扱う
- 一般的なキャッシュ戦略
- 遅延読み込み
- アプリケーション側に以下のようなプログラムを実装
- 問い合わせをする
- まずキャッシュにデータをリクエストする
- キャッシュがあればアプリケーションにデータを返す
- キャッシュにデータがなければ DB にアクセスする
- DB からの戻り値をキャッシュに保存する
- アプリケーション側に以下のようなプログラムを実装
- 書き込みスルー
- アプリケーション側に以下のようなプログラムを実装
- アプリケーションから DB にデータを書き込むときにキャッシュにも DB にも両方にデータを書き込む
- アプリケーション側に以下のようなプログラムを実装
- キャッシュ戦略詳細
- https://speakerdeck.com/moznion/pattern-and-strategy-of-web-application-caching?slide=106
- 遅延読み込み
- キャッシュするかしないかの基準
- キャッシュしたほうがよい性質か
- キャッシュできるかどうか
- ビジネス上の判断
- キャッシュからの項目削除
- 例えば遅延読み込み戦略のとき、キャッシュデータが最新かどうかを判断する必要がある場合がある
- TTL に基づく削除
- TTL を短くすればするほどキャッシュ効果が薄れる
- TTL を長くすれば古いデータが長くのこるのでデータ整合性のリスク
- キャッシュがいっぱいになったときの削除
- キャッシュとして利用頻度が低いデータが残ると容量の無駄遣い
- maxmemory ポリシーに基づく削除
- LRU(最も長く使用されていない)データ
- 例えば遅延読み込み戦略のとき、キャッシュデータが最新かどうかを判断する必要がある場合がある
memcached
- ノード:ひとつひとつのインスタンスのこと
- クラスタ:ノードがまとめられたもの
- Key:Value 型のインメモリ DB
- 使い方
- クライアントがなく telnet で接続
- コマンドを使ってデータを取得、格納
- add キー名 フラグ キャッシュ有効期限 バイト数
- データの格納
- その後 value を入れる
- get キー名
- value が取得できる
- add キー名 フラグ キャッシュ有効期限 バイト数
- 永続化のためにストレージに保存する仕組みがないので、ノードが再起動するとデータが消える
- データのレプリケーションの仕組みもない
- Redis と比較すると単純な分、非常に高速
- クラスタ
- RDS のクラスタは2つのインスタンスで同じデータを持ち、AZ 障害に備えたりする。それが目的
- memcached はレプリケーションできないので、クラスタを組む目的は可用性やデータ耐久性のためではない
- データのシャーディングのためにクラスタを組む
- 複数のノードのメモリを一つのデータ空間のように扱ってより大容量のデータを格納する
- ノード台数が増えるとデータがそれだけ分散されるので、ノード障害のときのデータ損失範囲はノード台数が増えると小さくはなる
- シャーディング
- アプリケーションにルータに相当する機能が必要
- 例えばデータが偶数のときはノード1、奇数のときはノード2など
- 特定のノードにアクセスが集中しないようにデータ偏りが発生した場合はデータの再配置をユーザが行う必要がある
- クラスタにノードを追加・削除のたびにデータの再配置が必要
- ベストプラクティス
- Consistent hashing(アルゴリズム)
- ノードとデータ双方にハッシュ関数をかけ、値をリング状に配置するイメージ
- 「データのハッシュ値 ≦ ノードのハッシュ値」を満たすノードの中で一番小さいハッシュ値のノードにデータを格納
- 「データのハッシュ値 ≦ ノードのハッシュ値」を満たすノードがなければ、最も小さいハッシュ値のノードに格納
- これによってリング状につながることになる
- ノード追加削除時に移動するデータを少なくできる
- 全体のノード数が少ないときに偏りが発生しやすい
- TWEM プロキシ、memcached や Redis で使えるプロキシに実装されていたりする
- https://github.com/twitter/twemproxy
- Consistent hashing(アルゴリズム)
- アプリケーションにルータに相当する機能が必要
- 考慮事項
- ノードを追加、削除でスケーリング。(ただしアプリケーション側で上記のシャーディング等の考慮は必要あり)
- 新しく追加したノードにどうやって接続するか
- 設定エンドポイントに API でリクエストを送るとクラスタの中の各ノードのエンドポイントを取得できる
- 取得したあとに適切なノードに接続するためのロジックはアプリケーションに必要
- 新しく追加したノードにどうやって接続するか
- 垂直スケーリングには対応していない。最初に立てたインスタンスタイプで固定
- 新しくクラスタを作成する必要がある
- ノードを追加、削除でスケーリング。(ただしアプリケーション側で上記のシャーディング等の考慮は必要あり)
Redis
- memcached よりも豊富な機能を備える
- 色々なデータ型を扱える
- 可用性高めるための非同期レプリケーションを実装できる
- ノード障害時にフェイルオーバ可能
- トランザクションに近い処理が可能
- pub/sub メッセージング機能
- オンラインリシャーディング機能
- バックアップ機能
- 事例紹介
- https://eh-career.com/engineerhub/entry/2019/02/22/103000
- elasticache ではないが OSS の Redis を使っている
- オーソドックスな web3 層構成
- メッセージの処理だけ Redis に任せた
- Redis のデータ型
- memcached では一つのキーに一つの値という単純なデータ
- Redis では一つのキーに複数の値を割り当てることも可能
- HASH
- SET
- LIST(キューとして使うようなイメージ)
- LIST 型のデモ
- RedisCLI で接続
- lpush キー名 値
- キューの左に入れる,l は多分 Left
- rpop キー名
- キューの右から出す、r は多分 right
- LIST 型のデモ
- Redis 利用パターンの参考資料
- Advanced Design Pattern for Amazon ElastiCache
- ソート済みセットデータ型(Sortedset)
- ゲームのランキングなどのリーダーボードで使用
- rdbms だといったんソートしたデータを頭からよみこんで offset の値のデータまでを捨てるということをしているので offset 件数に応じてクエリが遅くなる
- Redis の場合 Sortedset で高速にできる
- 内部データ構造にスキップリストを採用しているため
- スキップリスト:全データを適度にはしょってるリストなイメージ
- 内部データ構造にスキップリストを採用しているため
- Redis 構成
- 単一ノード
- クラスターの設定方法が2つ
- マルチノード(クラスターモード無効)
- 1つのプライマリ、複数のリードレプリカ(最大5)
- プライマリとリードレプリカ間は非同期レプリケーション
- タイムラグがある点に注意
- プライマリとリードレプリカで1つのシャードを構成
- つまりクラスターモード無効では1シャードのみ
- マルチノード(クラスターモード有効)
- マルチシャード
- クラスターモード無効の1シャードを複数束ねたイメージ
- 最大 90 ノード
- マルチノード(クラスターモード無効)
- クラスターサイズ設定
- そのクラスターでまかなえるデータ量か?
- 10%の拡大を見込んでおく
- cloudwatch メトリクスでアラート検知したらノードを追加するといったことが可能
- クラスターの分離
- 目的別の分離
- 分離すればコストは高くなる
- そのクラスターでまかなえるデータ量か?
- スケーリング
- スケールアウト、イン、スケールアップ、ダウンをサポート
- Redis のシャーディング
- Redis クラスタ側にはルータ相当の機能がない
- RedisClient がルータの役割 これをアプリケーション側に組み込む
- それぞれの言語向けに用意されている
- クラスター対応のものと非対応の RedisClient がある
- 各シャードにハッシュスロットという番号の範囲が割当てられている
- 0-16383
- アクセス時に redisclient が key を元に格納するハッシュスロットを決定
- RedisAUTH
- パスワード認証
- 自動フェイルオーバ
- リードレプリカが1つ以上あると自動でマルチ AZ 構成になる
- プライマリが障害になると自動でリードレプリカが昇格
- 非同期レプリケーションなので最新データの消失の可能性はある
- バックアップ
- 1日1回の自動バックアップ →S3 に保存
- ElastiCache と DynamoDB の比較
- マイクロ秒レベルのアクセスが必要なら ElastiCache
- ネットワーク要件上、パブリックネットワークからのアクセスが必要な場合は DynamoDB(スマホから直接書き込みたいなど)
- MemoryDB for Redis との違い
- アプリケーションから見るとほぼ同じ
- 耐久性に違いがあり
- Elasticache の場合、プライマリノードに障害があると(非同期レプリケーションゆえに)データ損失するのでそこをカバーした形
- トレードオフとして書き込み性能がやや低い
モジュール12 Data Warehousing in Amazon Redshift
Redshift
- リレーショナル DB に分類される
- OLAP タイプのクエリを取り扱う
- RDS、Aurora は OLTP
- 少ないデータを高頻度に書き換えるのが得意
- RDS、Aurora は OLTP
- 大量のデータに対する集計処理、分析的な問い合わせ
- データウェアハウス
- データウェアハウスとは
- さまざまなデータソースからデータを集めて保存する
- 他の業務システムが存在している前提でそれらの DB からデータを集める
- LOB:ラインオブビジネス、データの発生源のこと
- データウェアハウスなしでやろうとすると複数 DB をまたいだクエリや業務 DB のリソースに影響があったりするのでデータウェアハウスが必要
- Redshift の特徴
- 列指向型
- フルマネージド型
- ペタバイト規模のデータも扱える
- ユースケース
- 得意
- 大量データを一気に処理する
- 同時実行数は少なめ
- insert や update ではなくバルクロード(COPY)が得意
- 不得意
- 実行時間の短い SQL が大量同時に実行される
- 得意
- コンポーネント(第2世代)
- postgresql がベースとなっている
- 分散 DB、複数ノードでクラスタを構成
- リーダーノード
- 処理をまず受け付ける、コンピューティングノードの処理を取りまとめて応答する
- コンピューティングノード
- 実際の処理をする
- ノードタイプに応じた CPU,メモリが割当てられる
- タイプによってはハードディスク、SSD がついている
- スライス
- コンピューティングノードの中に複数存在
- スライス単位で処理するプロセスが立ち上がる
- リーダーノードからのリクエストはプロセスが受け取る
- スライス=1シャード
- RA 3(第3世代)では
- S3 が永続的データを保存
- コンピューティングノードについている SSD がキャッシュとして機能
- 耐久性、耐障害性
- クラスターにはリーダーノードとコンピューティングノードが含まれるがこれは全て1 AZ に配置される
- 1AZ に配置することでシャーディングの性能を重視
- コンピューティングノード間ではデータは自動でレプリケーションされる
- RA3 ではデータは s3 配置されるのでデータの耐久性は高い
- ストアドプロシージャのサポート
- postgresql で使えるものが概ね使える
データモデリング
- リレーショナル DB と異なりどのようにテーブルを作るのがいいのか
- データの保存のされ方の違い
- リレーショナル DB では、物理的ストレージに格納する際に行指向で格納
- 1つのデータブロックに行のデータを数珠つなぎにして保管
- Redshift では物理的ストレージに格納する際に列指向で格納
- 同じデータブロックに入るデータは列単位でまとめて格納
- データの集計
- 行指向だと不要データを読み飛ばしていく必要がある
- 列指向だと必要な列のデータが固まっているので少ないデータブロックの読み込みで済む
- 新しいデータの挿入
- 行指向だとデータブロックにまとめてデータを挿入でき、少ないデータブロックへのアクセスで済む
- 列指向だと列ごとにデータブロックが異なるので、多くのデータブロックにアクセスする必要がある
- パフォーマンスが悪くなる
- リレーショナル DB では、物理的ストレージに格納する際に行指向で格納
- 列圧縮
- 列ごとに同じ種類(データ型)のデータが集まるので、圧縮効率が良い
- ストレージ容量が削減できる=一度のアクセスで取得出来るデータが増える
- 圧縮タイプの指定=何も書かないと最適な圧縮タイプを選択して圧縮
- 何も書かないのが一応、推奨ではある
- データの保存
- シャーディングしている
- データ分散のさせかたを指定できる
- 分散スタイル
- AUTO,EVEN,KEY,ALL
- EVEN:中身のデータをみないで均等にデータを配置
- KEY:DynamoDB 等と同じであるキーのハッシュ値をとってそれを元に分散
- ALL:全部のノードにデータにコピーする(ストレージ容量が増える)
- create table 時に指定
- diststyle で分散スタイルを指定
- distkey で分散のためのキーを指定(KEY のときのみ)
- プライマリキーがお薦め
- 複数テーブルを頻繁に JOIN する場合は各テーブル間で diststyle,distkey をあわせるとパフォーマンスが上がる
- EVEN だと JOIN の際にネットワークを経由して一つのノードにデータを集約する必要があるのでパフォーマンスが下がる
- ALL でも全ノードにデータを置くのでパフォーマンスは上がる。クエリが様々で distkey が決めづらいときに有効
- KEY を使うと distkey 次第ではノード間でデータに偏りがでるので、注意する
- skew と呼ぶらしい(redshift 用語)
- distkey にはカーディナリティが高いものを指定する
- AUTO が一応、推奨
- Redshift 側で自動で分散スタイルを決めてくれる
- データが多くなるとより良い分散?
- AUTO,EVEN,KEY,ALL
- redshift テーブル設計詳細ガイド
- Amazon Redshift テーブル設計詳細ガイド 分散スタイルとソートキーの決定方法
- https://d1.awsstatic.com/events/jp/2017/summit/slide/D3T1-5.pdf
- データの非正規化
- データウェアハウスでは非正規化することで JOIN を省くことができる
- データウェアハウスでは LOB がデータソースなので、データウェアハウス側でデータの更新は基本的に発生しないはず(データソースの改ざんになるので)
- データの更新がないので、非正規化が問題にならない
- 非正規化でデータが冗長になるのでデータ容量は増えるが列圧縮をうまくつかえばそれもカバーできる
- リレーショナル DB だからといって正規化にこだわらないのが重要
- ソートキー
- ディスク上のデータを物理的に順序づけする
- インデックスが近い
- where 句で特定の範囲を抽出するときなどに使う
- create table 時に指定
- 複合ソートキー
- 複数の列をソートキーとして指定
- 指定した列の順番でソートされる
- 参照時も作った順番で指定しないと効果が得られない
- インターリーブソートキー
- 指定した列をそれぞれ単独で参照しても効果があるのが複合ソートキーとの違い
- メンテナンスコストが複合ソートキーと比較して高い
- 通常は複合ソートキーを使う
- URL のようなデータがある場合
- 複合ソートキーだと先頭 8byte くらいまででソートする
- インターリーブソートキーでは長い文字列も OK なので、この場合は使うべき
- ゾーンマップ
- クエリ処理中の検証済みブロック数と I/O を削減する
- 制約
- 一意制約、キー制約等の制約違反のデータを挿入してもエラーにならない
- NOTNULL 制約だけはエラーになる
- 一意制約、キー制約等の制約違反のデータを挿入してもエラーにならない
- データモデル最適化ツール
- EXPLAIN
- RedshiftAdvisor
- ワークロードに基づいて分析してコスト削減のための推奨事項を提示
設計上の考慮事項
- クラスタ作成時にコンピューティングノードタイプを指定
- ノードタイプ
- RA3(第3世代)
- コンピューティングとストレージ(S3)が分離
- データ耐久性が高い
- コンピューティング側 SSD がキャッシュとして機能
- AQUA(クエリ高速化機能)が使用可能
- Datasharing
- クロス AZ クラスタリカバリ
- DC2(高密度コンピューティングノード)
- それぞれのコンピューティングノードのストレージ(ローカル SSD)にデータを保管
- データの容量がそれほど多くないときに使う(SSD の容量がそれほど多くないため)
- DS2(レガシー)
- ローカル SSD にデータを保存
- ディスク容量は DC2 より大きい
- レガシーなので非推奨
- RA3(第3世代)
- ノードタイプ
- クラスタとノードのサイジング
- 本番では2つ以上のコンピューティングノードを推奨
- 20%くらいのストレージ空き容量を確保するように
- VACCUM が発生するまではストレージ容量を占有し続けるので
- 最大テーブル容量の3倍くらいのメモリ容量をもつ余裕のあるインスタンスを選ぶ
- VACCUM により自動で裏側でソートが走ったりするのでそれを見越して余裕のあるインスタンスを選ぶ
- クラスターのスケール
- クラシックリサイズ(DC2)
- スナップショットを撮ってからサイズを変更
- 1〜24時間かかる
- エラスティックリサイズ(RA3)
- 数分でサイズ変更可能
- RA 3であればすぐ終わる
- 参考情報
- https://aws.amazon.com/jp/premiumsupport/knowledge-center/redshift-elastic-resize/
- クラシックリサイズ(DC2)
- セキュリティ
- セキュリティグループ
- DB ユーザに対する IAM 認証
- SecretManager でのシークレット自動更新
- 拡張 VPC ルーティング
- redshift から他の AWS サービスと連携するとき
- デフォルト設定では他のサービスと通信するときグローバル経由で通信する
- VPC エンドポイントを作ったとしてもグローバル経由になるそう
- デフォルト設定では他のサービスと通信するときグローバル経由で通信する
- 拡張 VPC ルーティングを有効にすると VPC エンドポイント等を使うようになる
- redshift から他の AWS サービスと連携するとき
- 暗号化
- クラスタ作成時に暗号化を指定
- それぞれの層で暗号化キーが異なる
- CMK
- クラスターキー
- データベース暗号化キー
- データブロック用の暗号化キー
- それぞれの層で暗号化キーが異なる
- 後から暗号化もできる
- クラスタ作成時に暗号化を指定
- バックアップと復元
- 自動スナップショット
- 8時間ごとまたは5 GB ごと
- 保持期間は35日
- PITR 的なものはない
- スケジュールされたスナップショット
- 最頻1時間ごと
- 自動スナップショット
- 高可用性
- 第2世代はシングル AZ
- 第3世代はデータは S3 なのでそこの部分はマルチ AZ
機能
- Redshift Spectrum
- S3 に入っているデータを直接 redshift にロードして使える
- 他のシステムに貯められたデータを S3 に保存して、S3 のデータで Redshift が分析する
- S3 を基点に連携できる
- ワークロードマネージメント
- たくさんのクエリが Redshift に飛んできたときにクエリごとに優先順位をつけて実行してくれる
- 例えば開発用クエリを優先度落として、本番用クエリを優先させるなど
- 同時実行(コンカレンシー)スケーリング
- 一時的な処理高に対してクラスタ1セットのコピーを作成(Autoscaling に近い)して、そこにも処理をさせるという機能
- ワークロードマネージャでコンカレンシースケーリングモードを有効にすると使える
- 料金:1日ごとに1時間分は無料、超過分は秒単位課金
- たくさんのクエリが Redshift に飛んできたときにクエリごとに優先順位をつけて実行してくれる
- まとめ
- postgresql がベースとなっているので勘違いされがちだが、あくまでもデータウェアハウスなのでその用途で使うこと
まとめ
冒頭にも記載しましたが、内容盛りだくさんでこのトレーニングを受けるだけでかなり AWS の DB に詳しくなれると思います。
DB に少しでも関わりがあるという方はインフラエンジニア、開発者共にお薦めできる内容となっておりますので、ぜひ受講してみてください。
以上、とーちでした。