DataZone本番3ヶ月|メタデータ管理の地獄をどう乗り越えたか

AWSのDataZoneを3ヶ月運用して気づいた現実。導入は簡単だけど、メタデータ管理の運用設計で失敗したこと、工夫した対策をそのまま書きました。

DataZone導入の背景——データ迷子と決別したい

先日、うちのチームでDataZoneを本番環境に投入してから3ヶ月が経った。正直、最初の1ヶ月は地獄だった。なぜなら、誰も「メタデータ管理」が何なのか、現場レベルで理解していなかったから。

うちのデータエンジニアチームは去年の夏くらいから、ある悩みに直面していた。S3に山積みされたデータセットが増えるたびに「あのデータって何?どこから来たの?」という質問が絶えない。ExcelやConfluenceにドキュメントを書いても、気づくと3世代前の情報になってる。データソースが10を超えたあたりから、もう管理しきれなくなってた。

「これはカタログツール導入が必須だな」って判断したのは去年の11月。選択肢はCollibra、Alation、Atlasと、あとはAWSネイティブなDataZone。CloudFormationでインフラ即座に作れるし、既存のGlueジョブやAthenaと連携できるDataZoneを選んだ。当時は「これなら数週間で導入できるだろう」なんて甘く見てた。

最初の試行錯誤——「メタデータを入れてください」の地獄

DataZoneの基本設定は実は簡単だ。AWSコンソールで数クリック、IAM設定を済ませたら動く。ただし、ここからが本番なんだ。

# DataZone最初の構成(シンプル過ぎた)
Project: Analytics
AssetTypes:
  - S3
  - Athena
Users: 5名
MetadataFields:
  - name
  - description

これだけじゃ何も始まらない。データセット1つを登録しようとしたら、「このデータの所有者は?更新頻度は?データ品質スコアは?」って項目がポップアップする。最初は「まあ、入力すればいいか」って感じで進めた。

そしたら3週目に、データエンジニアから悲鳴が上がった。「毎回これ入力するんですか?」と。実は、S3のメタデータ自動検出機能があっても、ビジネス層のメタデータ(「これ何に使うデータなの?」という文脈)は手動入力が必須なんだ。

うちの場合、Glueカタログと連携させようとしたら、スキーマはGlueから自動取得できるけど、そこからはお手上げ。「え、Glueのテーブル説明文をDataZoneに同期させることできるの?」って思ったけど、できない。手作業だ。

AWS構成図でDataZoneを見える化する

graph TB
    subgraph VPC["VPC"]
        AppLayer["Application Layer"]
        DataZone["AWS DataZone"]
    end

    subgraph DataLake["Data Lake Architecture"]
        S3Raw["S3 Raw Zone"]
        S3Processed["S3 Processed Zone"]
        GlueDB[("AWS Glue Catalog")]
    end

    subgraph Analytics["Analytics & Governance"]
        Athena["Amazon Athena"]
        DataZoneCatalog["DataZone Catalog"]
        MetadataStore[("Metadata Store")]
    end

    subgraph Users["Users & Access"]
        DataOwner["Data Owner"]
        DataConsumer["Data Consumer"]
        Analyst["Analyst"]
    end

    DataZone <-->|「メタデータ連携失敗」| GlueDB
    GlueDB -->|テーブル定義| S3Raw
    GlueDB -->|テーブル定義| S3Processed
    S3Raw -->|ETL| S3Processed
    S3Processed -->|Query| Athena
    Athena <-->|メタデータ参照| DataZoneCatalog
    DataZoneCatalog -->|同期| MetadataStore
    MetadataStore -->|情報提供| Users
    DataOwner -->|メタデータ管理| DataZoneCatalog
    DataConsumer -->|検索・利用申請| DataZoneCatalog
    Analyst -->|データ発見| DataZoneCatalog

    style DataZone fill:#FF9900
    style GlueDB fill:#FF9900
    style DataZoneCatalog fill:#FF9900
    style MetadataStore fill:#FF6666

この図を見てもらえば、DataZoneがGlueカタログの上に乗っかってる感じが伝わると思う。ただし「上に乗っかる」ってのは「統合される」じゃなく「並走する」の意味だ。互いに独立してるから、連携がスムーズじゃないんだよね。

メタデータ自動化への転換——LambdaとEventBridgeの組み合わせ

2ヶ月目に、自動化を本気で考えた。毎日新しいS3パスが追加されるたびに、誰かがDataZoneに手入力するなんて持たない。

実装したのがこれだ:

# Lambda関数:S3新規データセット発見時にDataZoneに自動登録
import boto3
import json
from datetime import datetime

datazone_client = boto3.client('datazone', region_name='ap-northeast-1')
s3_client = boto3.client('s3')

def lambda_handler(event, context):
    """
    S3 PutObject → EventBridge → Lambda → DataZone Asset自動作成
    """
    bucket = event['detail']['bucket']['name']
    key = event['detail']['object']['key']
    
    # S3メタデータから基本情報を取得
    try:
        obj = s3_client.head_object(Bucket=bucket, Key=key)
    except Exception as e:
        print(f"Error getting S3 object metadata: {e}")
        return {"statusCode": 500, "body": str(e)}
    
    # DataZoneアセット登録のペイロード
    asset_payload = {
        "domainIdentifier": "YOUR_DOMAIN_ID",
        "name": key.split('/')[-1].replace('.parquet', '').replace('.csv', ''),
        "typeIdentifier": "S3Location",
        "owningProjectIdentifier": "YOUR_PROJECT_ID",
        "description": f"Auto-discovered from s3://{bucket}/{key}",
        "externalIdentifier": f"s3://{bucket}/{key}",
        "metadata": {
            "s3_bucket": bucket,
            "s3_path": key,
            "size_bytes": str(obj['ContentLength']),
            "last_modified": obj['LastModified'].isoformat(),
            "content_type": obj.get('ContentType', 'unknown')
        }
    }
    
    try:
        response = datazone_client.create_asset(
            domainIdentifier=asset_payload['domainIdentifier'],
            name=asset_payload['name'],
            typeIdentifier=asset_payload['typeIdentifier'],
            owningProjectIdentifier=asset_payload['owningProjectIdentifier'],
            description=asset_payload['description'],
            externalIdentifier=asset_payload['externalIdentifier'],
        )
        
        print(f"Successfully created asset: {response['id']}")
        return {
            "statusCode": 200,
            "body": json.dumps({"assetId": response['id']})
        }
    
    except Exception as e:
        print(f"Error creating DataZone asset: {e}")
        return {"statusCode": 500, "body": str(e)}

このLambda、最初は自分で書いてテストしたんだけど、本番環境で走らせたら予想外の問題が出た。DataZoneのAPI呼び出しレート制限にすぐ引っかかるんだ。

1時間に100ファイル追加されるようなパイプラインだと、Lambda関数が100個同時起動して、DataZoneのAPI呼び出しが集中して、503エラーが返ってくる。これはEventBridgeでスロットリング設定を入れるしかない。

{
  "Name": "DataZoneAutoDiscovery",
  "EventBusName": "default",
  "EventPattern": {
    "source": ["aws.s3"],
    "detail-type": ["Object Created"],
    "detail": {
      "bucket": {
        "name": ["data-lake-bucket"]
      },
      "object": {
        "key": [{
          "prefix": "processed/"
        }]
      }
    }
  },
  "State": "ENABLED",
  "Targets": [
    {
      "Arn": "arn:aws:lambda:ap-northeast-1:ACCOUNT_ID:function:datazone-auto-register",
      "RoleArn": "arn:aws:iam::ACCOUNT_ID:role/EventBridgeDataZoneRole",
      "RetryPolicy": {
        "MaximumEventAge": 3600,
        "MaximumRetryAttempts": 2
      },
      "DeadLetterConfig": {
        "Arn": "arn:aws:sqs:ap-northeast-1:ACCOUNT_ID:datazone-dlq"
      }
    }
  ]
}

重要なのはDeadLetterConfigだ。API呼び出しに失敗したイベントを死なせず、SQSキューに入れて、後から非同期で処理する。これでAPIレート制限の問題をうまく避けられた。地味だけど、本番環境では必須の設定だ。

メタデータの品質問題——「入ったら終わり」の罠

2ヶ月目から3ヶ月目にかけて気づいたのは、メタデータを登録することより、更新し続けることの方がずっと難しいってこと。

DataZoneに「データ品質スコア」みたいなフィールドを設定したんだけど、誰がそれを保守するのか。データエンジニアか?ビジネスオーナーか?ステークホルダーが増えると、その答えはもっと複雑になる。

うちの場合、Athenaでクエリを走らせたときのメタデータ(実行時間、データサイズ、クエリ複雑度)をDataZoneに自動同期させることにした。

# Athena実行完了後にDataZoneメタデータを更新する仕組み
import boto3
from datetime import datetime

athena_client = boto3.client('athena')
datazone_client = boto3.client('datazone')

def update_asset_metadata_from_athena(query_execution_id, asset_id):
    """
    Athena実行結果からメタデータを抽出し、DataZoneのアセットを更新
    """
    # Athena実行情報を取得
    response = athena_client.get_query_execution(
        QueryExecutionId=query_execution_id
    )
    
    stats = response['QueryExecution']['Statistics']
    
    metadata_updates = {
        "last_queried": datetime.now().isoformat(),
        "execution_time_ms": stats['TotalExecutionTimeInMillis'],
        "data_scanned_bytes": stats['DataScannedInBytes'],
        "status": response['QueryExecution']['Status']['State']
    }
    
    # DataZone APIで動的にメタデータを更新
    # ただし、DataZone APIにはメタデータ更新エンドポイントが限定的
    # 公式ドキュメント:UpdateAsset APIは特定フィールドのみ対応
    try:
        datazone_client.update_asset(
            domainIdentifier="YOUR_DOMAIN_ID",
            identifier=asset_id,
            description=f"Last queried: {metadata_updates['last_queried']} | "
                       f"Execution time: {metadata_updates['execution_time_ms']}ms | "
                       f"Data scanned: {metadata_updates['data_scanned_bytes']} bytes"
        )
        print(f"Updated asset {asset_id} with Athena metrics")
    except Exception as e:
        print(f"Failed to update metadata: {e}")
        # 重要:失敗してもクエリ結果は保存しておく
        # メタデータ更新失敗がデータ利用を妨げてはいけない

正直まだ検証中なんだけど、このやり方で**「メタデータが古い」という訴えは大幅に減った**。なぜなら、メタデータが常に「最後に使われたのはいつ」という情報を持つようになったから。これってビジネスユーザーにとって、スキーマ情報より大事な情報かもしれない。

DataZone vs 他のカタログツール——本音で比較

うちのチームは、DataZone導入前にCollibra と Alationのトライアルも触ってた。率直に言うと、こんな感じだ:

項目DataZoneCollibraAlation
AWS統合ネイティブAPI連携API連携
学習コスト低い中程度高い
カスタマイズ性限定的高い高い
初期費用数十万円数百万円数百万円
メタデータ自動化部分的自動自動
運用負荷低い中程度高い
ガバナンス機能標準的高度高度

DataZoneを選んだ理由は、AWS環境ならサクッと動く、という「気軽さ」。ただし、本当にエンタープライズレベルのガバナンスが必要なら、Collibra や Alation の方が圧倒的に強い。機能としては向こうが数段上なんだよね。でも、コストと運用負荷を考えると、うちみたいな小〜中規模チームはDataZoneが無難かもしれない。

意外な落とし穴——ビジネスユーザーのメタデータ理解

3ヶ月目で気づいた一番大きな問題は、データオーナーとデータコンシューマーの「メタデータ」の定義がズレてたってこと。

エンジニアは「スキーマ、更新頻度、データ品質スコア」って考えるけど、マーケティング部門は「このデータで何ができるのか」を知りたい。営業は「信頼度は?」を気にする。ビジネスアナリストは「どの部門が持ってるデータなの?」を聞きたい。それぞれ違うメタデータを欲しがってるんだ。

これを解決するために、DataZoneの「カスタムメタデータフィールド」機能を使ってみた。各ユーザーグループに必要な情報を個別に設定できるようにしたんだ:

{
  "CustomFields": [
    {
      "name": "business_use_case",
      "type": "string",
      "description": "このデータの主なビジネス用途",
      "required": true,
      "options": [
        "顧客分析",
        "売上予測",
        "マーケティング自動化",
        "リスク管理",
        "その他"
      ]
    },
    {
      "name": "data_quality_score",
      "type": "numeric",
      "description": "0-100スケールのデータ品質スコア",
      "required": true,
      "minValue": 0,
      "maxValue": 100
    },
    {
      "name": "refresh_lag_hours",
      "type": "numeric",
      "description": "ソースシステムからの更新遅延(時間単位)",
      "required": false
    },
    {
      "name": "pii_flag",
      "type": "boolean",
      "description": "個人識別情報を含むか",
      "required": true
    }
  ]
}

これを導入したら、ようやく「あ、このデータ信頼できるんだ」「このデータは顧客情報が入ってるから慎重に扱わないと」という判断がビジネスユーザー側でできるようになった。メタデータって、結局のところ「判断材料」なんだなって改めて感じたね。

3ヶ月運用して分かった実装のコツ

1. メタデータ入力は段階的に

最初から完璧なスキーマを作らない。まず「最小限」のメタデータ(名前、説明、所有者)を満たしたら、あとは使いながら追加していく。完璧さを求めると、チームのモチベーションが下がっちゃう。

2. 自動化は「失敗容認」で設計する

Lambdaが失敗してもメインのデータパイプラインが止まっちゃダメ。メタデータ更新はあくまで「補足情報」。DLQにためて、非同期で処理する。データの可用性を絶対に優先する。

3. ビジネス層とエンジニア層のメタデータを分ける

「テーブル定義」と「ビジネス文脈」は別物。前者はGlueから自動同期、後者は手動入力か、ビジネスユーザーが自分で入力する仕組みを作る。混ぜると誰のための情報かわからなくなる。

4. データカタログはGUIじゃなくAPIで検索

うちの場合、DataZoneのWebUIより、Pythonで検索クエリを書く方が圧倒的に速い。開発者はAPIの方が使いやすいんだ。

# DataZone検索API
import boto3

datazone_client = boto3.client('datazone')

# キーワードで資産を検索
response = datazone_client.search(
    domainIdentifier='YOUR_DOMAIN_ID',
    searchScope='ASSET',
    searchText='customer',  # 「customer」に関するアセット検索
    filters=[
        {
            'name': 'typeName',
            'values': ['S3Location']  # S3オブジェクトのみ
        }
    ]
)

for result in response['results']:
    print(f"Asset: {result['name']}, Owner: {result['owner']}")

まとめ

DataZoneは確かに便利なカタログツールなんだけど、「導入したら自動的にデータガバナンスが回る」わけじゃない。むしろ、メタデータをどう定義して、誰が保守するのか、という組織的な問題の方がずっと大きい

3ヶ月運用してわかった重要なポイント:

  • メタデータ自動化には上限がある — スキーマは自動取得できるが、ビジネス文脈は手動入力が必須
  • API呼び出しレート制限は早めに対策する — EventBridgeのリトライとDLQ設定が大事
  • カスタムメタデータフィールドでビジネスユーザーの要件を満たす — エンジニア視点だけじゃデータ探索は進まない
  • 完璧さを目指さない — 「80%のメタデータで十分」くらいの気持ちで進めた方が、運用が続く
  • ビジネス層のオーナーシップが必須 — データエンジニアだけで回そうとすると、確実に破綻する

うちはまだ5人のチームだからちょうどいいスケールだけど、これが50人、100人規模のデータ組織になったら、もっと高度なカタログツール(CollibラやAlation)の出番なんだろう。ただし、AWSだけで完結させたいなら、DataZoneは悪くない選択肢だ。正直、Alationの初期導入費用を聞いたときは目玉が飛び出たし。

まだ改善の余地があるし、メタデータの「信頼度」をどう担保するかはこれからのテーマだ。ただ、3ヶ月前の「データ迷子状態」に比べたら、格段に良くなったのは確か。最近では「あのデータ、DataZoneで見つけてくれ」って言う人も増えてきた。

U

Untanbaby

ソフトウェアエンジニア|AWS / クラウドアーキテクチャ / DevOps

10年以上のIT実務経験をもとに、現場で使える技術情報を発信しています。 記事の誤りや改善点があればお問い合わせからお気軽にご連絡ください。

関連記事