LoginSignup
3
0

More than 1 year has passed since last update.

AWS Clean Rooms(プレビュー)を触ってみた

Posted at

はじめに

昨年末のre:InventでAWS Clean Roomsというサービスが発表されました。

昨今、データクリーンルームという言葉が聞かれ始めたので、AWSはどういうサービスを提供するのか興味ありました。

そして先日プレビューが開始されました。

なので触ってみた内容や、所感などを書いていきます。
まだプレビュー版であり、私自身素人ですので、判断される際は他の情報と照らし合わせたり、自身で試用して確認してください。

サービスの概要

  • 「コラボレーション」という場が作れます
  • コラボレーションには、AWSアカウントが参加できます
    • メンバーと呼ぶようです
    • 最大5メンバー
  • メンバーには2種類あります
    • クエリを実行して結果を受け取ることができるメンバー
      • 1メンバーのみ
    • データを提供するメンバー
      • 上記メンバー以外
  • 料金は、クエリ実行に対してのみ
  • データ提供用に別途リソースを作る必要がなさそう
    • 専用のIAMロールは必要
  • 見せるカラムを選択する
  • 許可する集計の列と集計方法も選択する

使っていて、以下のようなイメージが浮かびました。

image.png

やってみた

AWSアカウントを2つ用意して、「受領企業」と「提供企業」として扱います。

コラボレーション作成

「受領企業」アカウントにて、コラボレーション作成をクリックします。

image.png

詳細にて、名前と説明を入力します。
image.png

メンバーにアカウントを指定します。自アカウントのIDはデフォルトで入っています。
image.png

「メンバー能力」の箇所で、データを見せてもらうアカウントを指定します。今回は「受領企業」アカウントを指定します。
image.png

それ以降はチェックなしで作成します。
image.png

確認画面が出ますので、作成及び参加します。
image.png

作成直後で、「提供企業」アカウントが招待を受領する前の状況は以下のようになっています。
image.png

招待を受ける

招待を受けたアカウント側では、先のコラボレーションが参加可能タブに表示されます。
image.png

招待を受けるには、メンバーシップを作成、から行います。
image.png
image.png
メンバーシップを作成されると、ステータスがアクティブになりました。
image.png

役割(メンバー能力)で、表示されるタブに違いがありました。

受領企業アカウントでは、「クエリ」があります。
image.png

一方、提供企業アカウントにはありません。
image.png

データ提供(Glueテーブル公開)

提供企業アカウント側でデータを用意し、受領企業アカウント側に公開していきます。

Glueテーブルを公開するので、関連するリソースをCloudFormationで作ります。

クリックで表示

データ格納バケット、Athena結果出力バケット、Athenaのワークグループ、Glueデータベースを作ります。昔のものを流用しているので、一部アウトプットが余計ですがご容赦ください。

AWSTemplateFormatVersion: '2010-09-09'

Parameters:
  Env:
    Type: String

Resources:
  RawDataBucket:
    Type: AWS::S3::Bucket
    Properties: 
      BucketName: !Sub raw-data-${AWS::AccountId}-${AWS::Region}-${Env}
      BucketEncryption: 
          ServerSideEncryptionConfiguration: 
            - 
              ServerSideEncryptionByDefault: 
                  SSEAlgorithm: 'AES256'
              BucketKeyEnabled: false
      PublicAccessBlockConfiguration:
        BlockPublicAcls: true
        BlockPublicPolicy: true
        IgnorePublicAcls: true
        RestrictPublicBuckets: true

  AthenaQueryResultBucket:
    Type: AWS::S3::Bucket
    Properties: 
      BucketName: !Sub query-result-${AWS::AccountId}-${AWS::Region}-${Env}
      BucketEncryption: 
          ServerSideEncryptionConfiguration: 
            - 
              ServerSideEncryptionByDefault: 
                  SSEAlgorithm: 'AES256'
              BucketKeyEnabled: false
      PublicAccessBlockConfiguration:
        BlockPublicAcls: true
        BlockPublicPolicy: true
        IgnorePublicAcls: true
        RestrictPublicBuckets: true
      LifecycleConfiguration: 
        Rules: 
          - 
            Id: 'auto-delete'
            Status: 'Enabled'
            ExpirationInDays: 7

  AthenaWorkGroup:
    Type: AWS::Athena::WorkGroup
    Properties:
      Name: !Sub athena-work-group-${Env}
      RecursiveDeleteOption: true
      WorkGroupConfiguration:
        ResultConfiguration:
          OutputLocation: !Sub s3://${AthenaQueryResultBucket}/data
          EncryptionConfiguration: 
            EncryptionOption: 'SSE_S3'
        EnforceWorkGroupConfiguration: true
        PublishCloudWatchMetricsEnabled: true

  GlueDatabase:
    Type: AWS::Glue::Database
    Properties: 
      CatalogId: !Ref AWS::AccountId  
      DatabaseInput:
        Name: !Sub glue-database-${Env}

Outputs:
  RawDataBucket:
    Value: !Ref RawDataBucket
    Export:
      Name: !Sub "${Env}-RawDataBucket-Name"
  AthenaQueryResultBucket:
    Value: !Ref AthenaQueryResultBucket
    Export:
      Name: !Sub "${Env}-AthenaQueryResultBucket-Name"
  AthenaWorkGroup:
    Value: !Ref AthenaWorkGroup
    Export:
      Name: !Sub "${Env}-AthenaWorkGroup-Name"
  GlueDatabase:
    Value: !Ref GlueDatabase
    Export:
      Name: !Sub "${Env}-GlueDatabase-Name"

Athenaを作成します。先のCloudFormationで設定したパラメータと同じパラメータを指定してください。

AWSTemplateFormatVersion: '2010-09-09'

Parameters:
  Env:
    Type: String

Resources:

  ItemTable:
    Type: AWS::Glue::Table
    Properties:
      CatalogId: !Ref AWS::AccountId
      DatabaseName:
        Fn::ImportValue:
          !Sub "${Env}-GlueDatabase-Name"
      TableInput:
        Name: item
        TableType: EXTERNAL_TABLE
        Parameters:
          skip.header.line.count: 1
          has_encrypted_data: false
          serialization.encoding: utf-8
          EXTERNAL: true
        StorageDescriptor:
          OutputFormat: org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat
          Columns:
            - Name: item_cd
              Type: string
            - Name: item_name
              Type: string
            - Name: store
              Type: string
            - Name: salse
              Type: int
          InputFormat: org.apache.hadoop.mapred.TextInputFormat
          Location:
            Fn::Join:
              - ''
              - - 's3://'
                - Fn::ImportValue: !Sub "${Env}-RawDataBucket-Name"
                - '/item' 
          SerdeInfo:
            Parameters:
              field.delim: ","
              serialization.format: ","
            SerializationLibrary: org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe

作成されたバケットに、以下のファイルを置きます。Athena作成時のロケーションに指定したitemフォルダ以下に置くようにします。

item/item.csv
item_cd,item_name,store,salse
AAAA,商品A,店舗1,1
AAAA,商品A,店舗2,10
AAAA,商品A,店舗2,100
BBBB,商品B,店舗1,1
BBBB,商品B,店舗2,10
CCCC,商品C,店舗1,1

作ったAthenaを関連付けます。
image.png

データベースとテーブルを設定します。
image.png

すべての列を許可して設定。
image.png

設定すると分析ルールを設定するよう促されますので、設定します。
image.png

タイプは集約を選択。
image.png

作成時にはガイドフローを使います。
image.png

集約関数を設定します。数値項目(っぽい)「salse列に対しSUMを許可」で指定します。
image.png

結合コントロールで「はい」を指定することで、他テーブルと結合しなくても使えるようです。
image.png

SELECTに使いたい項目を設定します。
image.png

スカラー関数はすべて使うこととして次へ
image.png

集約制約なるものを設定します。(よくわからなかったので適当に設定しています。)

image.png

集約制約については、後で「こうじゃないかな・・・?」というのを説明します。

作成がうまくいったようです。
image.png

分析ルールを作成後は、コラボレーションに関連付けます
image.png
image.png

必要なロールは自動作成で作ってくれます。(ロール名は自分で指定可能なので、テーブル名や相手先など、わかりやすい名前を付けておくとよいと思います。)
image.png

受領企業アカウントに移り確認すると、関連付けを行ったテーブルに対してクエリ可能になりました。
image.png

クエリしてみる

受領企業アカウントに移り、クエリを実行しますが、最初にバケットを指定します。
image.png
image.png

試しに以下のクエリを実行します。

SELECT
    "item"."store",
    SUM("item"."salse")
FROM  "item"
GROUP BY  
    "item"."store"

結果は出てきました。結構時間はかかります。
image.png

集約制約の影響

今度はitem_nameでグルーピングして検索してみます。

SELECT
    "item"."item_name",
    SUM("item"."salse")
FROM  "item"
GROUP BY  
    "item"."item_name"

が、何も出てきません・・・
image.png

先ほどの制約を修正して、item_cdからstoreに変更しました。編集するときはガイドフローは使えませんので、JSONを編集します。
image.png

そして同じSQLを実行してみます。

SELECT
    "item"."item_name",
    SUM("item"."salse")
FROM  "item"
GROUP BY  
    "item"."item_name"

今度は結果がかえってきましたが、商品Cが出てきません。
image.png

試しに以下のファイルをフォルダにいれて再実行すると、以下のような結果がかえってきます。

item/item2.csv
item_cd,item_name,store,salse
CCCC,商品C,店舗9,1000

image.png

集約制約の考察

これらのことから考えるに「グループ化した際に各グループで、集約制約で指定した列の一意の個数が最小値を超えている場合に、対象とする」となっているように見られました。

ケース1

最初に実行したクエリでは、sotreでグループ化して、「item_cdが2以上」という制約でした。

SELECT
    "item"."store",
    SUM("item"."salse")
FROM  "item"
GROUP BY  
    "item"."store"

対象のデータを、storeitem_cdで一意にすると以下のようになり、各店舗ごとでitem_cdの数が2以上になり、集計されたようです。

store,item_cd
店舗1,AAAA
店舗1,BBBB
店舗1,CCCC
店舗2,AAAA
店舗2,BBBB

ケース2

2番目に実行したクエリでは、item_nameでグループ化して、「item_cdが2以上」という制約でした。

SELECT
    "item"."item_name",
    SUM("item"."salse")
FROM  "item"
GROUP BY  
    "item"."item_name"

先ほどと同様に、item_nameitem_cdで一意にすると以下のようになり、「商品A」「商品B」「商品C」いずれも1つになってしまったので、対象から外れた、と考えられます。

item_name,item_cd
商品A,AAAA
商品B,BBBB
商品C,CCCC

ケース3

同じSQLに対して制約条件を変えて、item_nameでグループ化して、「storeが2以上」と設定するとどうでしょう。
item_namestoreで一意にすると以下のようになり、「商品C」が1つになってしまったので、対象から外れた、と考えられます。

item_name,store
商品A,店舗1
商品A,店舗2
商品B,店舗1
商品B,店舗2
商品C,店舗1

ケース4

その後、同じSQLで同じ制約条件、データに「商品Cに対して、店舗1以外のデータ」を追加した結果、「店舗C」も2以上になり集計対象になった、という動きをしていました。

item_name,store
商品A,店舗1
商品A,店舗2
商品B,店舗1
商品B,店舗2
商品C,店舗1
商品C,店舗9

おわりに

プレビュー版ですが、新サービスのAWS Clean Roomsを触ってみました。
提供側が(Glueテーブルを作ってあれば)わざわざ新規でデータを用意しなくても提供できる、というのはかなり良いかと思います。

別のデータと結合したり、別のタイプ「リスト」というのもありますが、今回はそこまでできませんでした。時間があったら見てみようと思います。

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0