web-dev-qa-db-ja.com

DynamoDBで基本的な集計を行う方法は?

Dynamodbではどのようにして集計が行われますか? Mongodbとcouchbaseにはマップ削減のサポートがあります。

ユーザーが記事を投稿できる技術ブログを構築しているとしましょう。そして、記事にタグを付けることができると言います。

user
{
    id : 1235,
    name : "John",
    ...
}

article
{
    id : 789,
    title: "dynamodb use cases",
    author : 12345 //userid
    tags : ["dynamodb","aws","nosql","document database"]
}

ユーザーインターフェイスで、現在のユーザータグとそれぞれの数を表示します。

次の集計をどのように達成しますか?

{
    userid : 12,
    tag_stats:{
        "dynamodb" : 3,
        "nosql" : 8
    }
}

このデータはREST APIを介して提供し、頻繁に呼び出されます。この情報はアプリのメインページに表示されます。

  • すべてのドキュメントを抽出し、アプリケーションレベルで集計することを考えることができます。しかし、私は自分の読み取りキャパシティーユニットが使い果たされるだろうと感じています
  • EMR、redshift、bigquery、aws lambdaなどのツールを使用できます。しかし、これらはデータウェアハウジングの目的のためだと思います。

同じことを実現する他のより良い方法を知りたいのですが。コストと応答時間を考慮して、プライマリデータストアとしてdynamodbを選択したこれらの動的な単純なクエリをどのように実現していますか。

20
prem kumar

要するに、Dynamoはこれをサポートしていません。このユースケース用にビルドされているわけではありません。低レイテンシで迅速なデータアクセスを目的としています。単に集約機能をサポートしていません。

主に3つのオプションがあります。

  • DynamoDBデータを Redshift または EMR Hive にエクスポートします。その後、古いデータに対してSQLクエリを実行できます。このアプローチの利点は、RCUを一度しか消費しないことですが、古いデータに固執することになります。

  • Hiveには DynamoDBコネクタ を使用し、DynamoDBに直接クエリを実行します。ここでも任意のSQLクエリを記述できますが、この場合はDynamoDBのデータに直接アクセスします。欠点は、実行するすべてのクエリで読み取り容量を消費することです。

  • DynamoDBストリーム を使用して、集計データを別のテーブルに保持します。たとえば、テーブルUserIdをパーティションキーとして、ネストされたマップにタグとカウントを属性として含めることができます。元のデータが更新されるたびに、DynamoDBストリームはホスト上でLambda関数またはいくつかのコードを実行して、集計テーブルを更新します。これは最もコスト効率の良い方法ですが、新しいクエリごとに追加のコードを実装する必要があります。

もちろん、アプリケーションレベルでデータを抽出してそこで集計することはできますが、お勧めしません。小さなテーブルがない限り、プロビジョニングされた容量の一部のみを使用して(100%ではなく、RCUの20%を集約するために消費するなど)、複数のワーカー間で作業を分散する方法について検討する必要があります。

RedshiftとHiveのどちらも、これを行う方法をすでに知っています。 Redshiftはクエリを実行するときに複数のワーカーノードに依存しますが、HiveはMap-Reduceの上に基づいています。また、RedshiftとHiveはどちらも、RCUスループットの事前定義された割合を使用できます。

19
Ivan Mushketyk