MEGAZONEブログ
Advanced data modeling with Amazon DynamoDB
Amazon DynamoDBを使った高度なデータモデリング
Pulisher : Mass Migration & DR Center ムン・ボンギ
Description : データモデリングのためのDynamoDBの基礎と原則について紹介したSean氏
はじめに
DynamoDBの使用を最適化するためには、既存のRDMSとは異なるデータモデリングアプローチが必要であり、そのセッションでデータモデリングのためのDynamoDBの基礎と原則を学ぶことができそうなので申し込みました。
セッションの概要紹介
Amazon DynamoDBで使用するデータモデリングについて学びます。
今日のアジェンダは以下の通りです。
・Amazon DynamoDBの基本
・DynamoDBのユニークな側面
・データモデリングの演習
上の8つの図は、航空会社で使用する一部のデータを持って、Table, Item, Primary Key, Attributes, Simple primary key, Composite primary keyを区分して、それぞれtableでどのように構成されているかを示しています。
診断テーブルには二つのタイプのprimary keyがあります。単一要素、つまり、パーティションキーだけのSimple primary keyを持つこともできますし、Partition keyとsort keyの二つの要素を持つComposite primary keyを持つこともできます。
Simple primary key があるテーブルがある場合、知っている個々の項目を作業しながら行間を読み書きするようなキー値タイプの演算子をほとんど実行することになります。
・GetItem, PutItem, UpdateItem, DeleteItem
Composite Primary keyを持つテーブルでは、主にPartition keyを使用してレコードを割り当て、同じPartition keyを持つレコードはそのSort keyによってソートされます。これにより、クエリを実行する時、特定の項目を探したり、範囲を取得するのに便利に活用することができます。
Secondary indexで考慮すべき核心は、読み取りテーブルのデータがこのSecondary indexにコピーされるということです。 同じデータですが、再構造化され、新しいPartition keyとSort keyを使うことができます。これにより、追加的なパターンが可能になりますが、再び基準を再設定する必要があります。セカンダリインデックスには書き込みができません。
すべての書き込み作業は、読み取りテーブルを介して行われ、この補助インデックスでソートされます。補助インデックスで属性を選択できるのは、補助インデックスの興味深い点の一つです。”ALL”を指定することもできますし、”KEYS_ONLY”を提供してもらうこともできますし、”INCLUDE”という方法もあります。
・Partitioning
・Dynamo DBは、データを複数のセグメントに分割し、ハッシュを通じてどのセグメントに行くかを決定するパーティショニングを通じてユニークな機能を提供し、データを様々なノードに分散保存し、管理することで拡張性を強化します。
・Multi-Tenant
・Dynamo DBテーブルは、個々の地域内ですべてのユーザーとテーブルが同じインフラを共有するマルチテナントアーキテクチャーを持ち、特定のテーブルに対するインスタンスを別途に割り当てることなく、すべてのユーザーが同じ共有インフラを使用します。
・Every Request is an Index Hit
・すべてのリクエストはインデックスを使用して処理されます。パーティションキーを使用してデータを効率的に読み書きすることに重点を置きます。データ要求時、そのパーティションキーを使用してデータの位置を把握して応答します。
・Eventually Consistent Reads by Default
・DynamoDBは基本的に読み取り作業に一貫性を維持します。これは、すべてのノードにデータを複製し、読み取り要求がランダムに1つのノードで処理され、最終的な一貫性を提供します。読み取りパフォーマンスを向上させるために一貫性を放棄することができ、その場合、コストが削減されます。
・Operation-Based Pricing
・DynamoDBは、実行された操作の量に応じて料金を設定するオペレーションベースの価格設定ポリシーを採用しています。ユーザーは必要な読み取りと書き込み操作の量を指定し、リソースの割り当てではなく、操作の実行に応じて費用が発生します。
データモデリングを練習してみましょう。
・Know Your Access Patterns
・Dynamo DBを使用する場合、データにどのようにアクセスするかを明確に知る必要があります。 主に、どのような種類の書き込みと読み取り操作が必要かを定義し、これに基づいてテーブルを設計します。
・Know Your Domain
・アプリケーションドメインに対する理解が必要です。データモデリングの前に、ドメインでどのような制約条件やデータ分布が予想されるかを考慮する必要があります。
・What Are Your Constraints?
・データを書き込んで保存する際、アプリケーションで維持したい制約を考慮する必要があります。
・What’s Your Data Distribution?
・データのパーティションキーによってどのように分散されるか、特に同じパーティションキーを持つレコードがどのように処理されるかを考慮する必要があります。
・How Big Are Your Items?
・アイテムの大きさを考慮する必要があります。大きなアイテムは、書き込みと読み取りコストに影響を与える可能性があります。
・Know the DynamoDB Basics
・Dynamo DB APIの基本的な使用方法を理解する必要があります。 特に、シングルアイテムアクションとクエリを中心に使用する方法を習得することが重要です。
・Single-Item Actions for Core Operations
・コア操作には個別レコードの操作が含まれます。アイテムの作成、照会、更新などのための単一アイテムアクションを理解して使用する必要があります。
・Query for ‘Find Many’ Needs
・多数のアイテムを探す必要がある場合は、適切なクエリ操作を使用する必要があります。フィルタリング、ソートなどを通じて様々な検索ニーズに対応することができます。
・Batch + Transaction Operations
・複数の作業をバッチで処理したり、トランザクションで処理する必要がある場合、バッチとトランザクション操作を理解して使用する必要があります。効率的なデータ処理のための方法を熟知する必要があります。
座席予約可能かどうかを確認したい場合、特に一般席の中から特定の座席を選択する場合は、条件式を使用すると効果的に機能します。 また、フライトには複数の区間が含まれる場合があり、フライト確定後にマイルを獲得することができます。
全体の流れを見ると、まず、各旅程の座席を予約する必要があります。選択した座席が有効かどうかを確認し、予約に失敗した場合、ユーザーに拒否応答を送信します。 座席予約が成功した場合、そのフライトの決済を処理します。 決済が失敗した場合、座席予約をロールバックし、予約を拒否します。
DynamoDBトランザクションとは、複数のDynamoDBジョブを単一のアトミックリクエストで処理することを意味します。 各ジョブは条件式を持つことができ、1つのジョブが失敗すると、トランザクション全体が失敗してロールバックされます。これは、複数のDynamoDBタスクをまとめて一度に成功または失敗させることができるという利点がありますが、長時間のトランザクションを実行することはできません。
DynamoDBトランザクションは、変更を1つのリクエストにまとめて送信する単一作業トランザクションに制限されています。これは、RDBMSのトランザクションとは異なり、複数の段階を経てトランザクションを実行することができないことを意味します。
外部システムとのトランザクションを処理するためには、クライアント側トランザクションまたは統合された関数を使用することが重要です。ステップ関数を活用して複雑なトランザクションを管理することができ、ステートマシンを定義して複数のタスクを単一のリクエストで実行することができ、条件式を使用して制約を維持し、項目を構造化して直接的なタスクを実行できるようにする必要があります。トランザクション操作は、複数の項目を一緒に成功または失敗させるのに便利ですが、追加コストとレガシーが発生する可能性があります。イベントブリッジとステップ関数を活用して作業完了後に追加作業を行うのが効果的であり、長期実行トランザクションは避けることをお勧めします。
セッションを終えて
DynamoDBの主任エンジニアと一緒にAmazon DynamoDBの基礎とユニークな特徴、そしてRDBMSとの違いを理解し、データモデリングを練習してみるセッションが本当に良かったです。 一般的な理論にとどまらず、一緒に考え、DynamoDBの特徴を考慮してダイアグラムを構成し、データモデリングを導き出すのが印象的でした。