😬

BedrockログをAthenaのパーティション射影を使用して効率的に分析する

に公開

こんにちは、ツクリンクでSREエンジニアをやってるida.です。

社内でAmazon Bedrock(以下「Bedrock」)を活用するにあたり、ログを収集して分析できる形にしておく必要が出てきました。そこでS3に出力してAmazon Athena(以下「Athena」)で分析する構成で検討しました。
調べていく中でパーティション射影なしでのテーブル作成の記事はいくつか見つかったんですが、パーティション射影を使用してのテーブル作成の記事が見当たらなかったため、自力で作成しました。この記事では、その方法について共有しようと思います。

Athenaのパーティション射影について

Athenaのパーティション射影とは、テーブルのパーティション構造をメタデータとして事前に定義しておくことで、クエリ実行時のパーティション検出を効率化する機能です。詳細については公式ドキュメントをご確認ください。

簡単に言うと、データを日付やリージョンなどの条件で論理的に区分け(パーティショニング)し、クエリ時にWHERE句などで絞り込めるようにする仕組みです。
これにより以下のようなメリットが得られます:

  • 検索速度の向上: スキャンするデータ量が絞り込まれるため、クエリの実行速度が大幅に向上します
  • コスト削減: Athenaはスキャンしたデータ量に応じて課金されるため、必要な範囲のみをスキャンすることでコストを抑えられます
  • 管理の簡素化: 新しいパーティションが追加された場合でも、ALTER TABLE ADD PARTITIONなどのコマンドを実行する必要がなく、自動的に認識されます
  • 大規模データセットへの対応: 何千、何万というパーティションがある場合でも、AWS Glueのデータカタログの制限に悩まされることなく効率的に処理できます
  • メンテナンスコストの削減: ETLプロセスでパーティションを登録・管理する作業が不要になり、運用負荷が軽減されます

特にBedrockのようなログデータは日々増加していくため、パーティション射影を設定しておくことで将来的なデータ増加にも柔軟に対応できるようになります。例えば、日付パーティションを設定しておけば、2025年のデータだけを参照したいときに、それ以外の年のデータをスキャンする必要がなくなります。

また、特定のリージョンのデータのみを分析したい場合も、リージョンでパーティションを分けておくことで、必要なリージョンのデータのみをスキャンでき、より効率的な分析が可能になります。

Bedrockのログ記録からAthenaでの分析まで

実際にログ記録からAthenaで分析するまでの手順を説明します。
前提として、今回は出力先のS3バケットは作成済み、Athenaの初期設定も完了済みとして進めていきます。

1. Bedrockのログ記録設定

BedrockにてS3へのログ記録を有効にします。
マネジメントコンソールから「Bedrock」→「設定」→「モデル呼び出しのログ記録」をオンにします。
ログ記録先をS3のみに設定し、作成済みのS3バケットを指定して設定を保存します。
(Cloudwatch Logsにも追加で連携する場合は「S3とCloudWatchLogsの両方」を選択してください。)

設定後にS3バケットにログが出力されていることを確認しておいてください。

2. Athenaでテーブル作成

S3バケットへのログ出力が完了したら、実際にAthenaにテーブルを作成します。
ここが今回の記事のポイントになります。

以下をAthenaのクエリエディタに貼り付けて実行してください。

  • データベース名やテーブル名は必要に応じて修正してください。
  • S3パスのS3_Bukcket_NAMEはログを出力しているS3バケットに変換してください。
  • S3パスのaccountIDは適宜ご自身のAWSアカウントIDに変換してください。
CREATE EXTERNAL TABLE IF NOT EXISTS `bedrock`.`bedrock_logs` (
    `identity` string,
    `operation` string,
    `modelId` string,
    `requestId` string,
    `timestamp` string,
    `input` struct < inputTokenCount: INT >,
    `output` struct < outputTokenCount: INT >
)
PARTITIONED BY ( 
`region` string, 
`date` string) 
ROW FORMAT SERDE 'com.amazon.ionhiveserde.IonHiveSerDe'
WITH SERDEPROPERTIES (
    'ion.encoding' = 'BINARY',
    'ion.fail_on_overflow' = 'true',
    'ion.path_extractor.case_sensitive' = 'false',
    'ion.timestamp.serialization_offset' = '+09:00',
    'ion.ignore_malformed' = 'true'
)
STORED AS INPUTFORMAT 'com.amazon.ionhiveserde.formats.IonInputFormat' 
OUTPUTFORMAT 'com.amazon.ionhiveserde.formats.IonOutputFormat'
LOCATION 's3://S3_Bukcket_NAME/AWSLogs/accountID/BedrockModelInvocationLogs/'
TBLPROPERTIES(
 'projection.enabled' = 'true',
 'projection.region.type' = 'enum',
 'projection.region.values' = 'us-east-1,us-west-2,eu-central-1,eu-west-1,ap-northeast-1',
 'projection.date.type' = 'date',
 'projection.date.range' = '2025/01/01,NOW',
 'projection.date.format' = 'yyyy/MM/dd',
 'projection.date.interval' = '1',
 'projection.date.interval.unit' = 'DAYS',
 'storage.location.template' = 's3://S3_Bukcket_NAME/AWSLogs/accountID/BedrockModelInvocationLogs/${region}/${date}/')

少しだけ解説すると、パーティション射影を実現するために重要なのは、PARTITIONED BY句とTBLPROPERTIES句です。PARTITIONED BY句でパーティション設定するカラムを指定し、TBLPROPERTIES句でパーティション設定するカラムを定義しています。
これらを適切に設定することで、パーティション管理を自動化できます。もしパーティション射影が不要であれば、これらの2つの句を除外することでシンプルなテーブルを作成できます。

3. Athenaで検索して分析

実際にクエリを実行してログを分析してみましょう。以下に活用できそうなクエリ例を2つ紹介します。

  • 全てのカラムを確認したい場合

    SELECT * 
    FROM bedrock.bedrock_logs
    WHERE date between '2025/01/01' and '2025/01/31'
    AND region = 'us-east-1'
    
  • identity単位で集計したい場合

    SELECT
        identity,
        SUM(input.inputtokencount) as total_input_tokens,
        SUM(output.outputtokencount) as total_output_tokens
    FROM bedrock.bedrock_logs
    WHERE date between '2025/01/01' and '2025/01/31'
    AND identity is not null
    GROUP BY identity
    ORDER BY total_input_tokens DESC
    

これで無事Athenaでパーティション射影を活用したテーブルを作成し、Bedrockのログを効率的に分析できるようになりました。日付やリージョンで絞り込むことで、分析コストを大幅に節約することができます。

まとめ

Athenaは少量のデータを扱う場合は問題ありませんが、データ量が増加するとスキャン容量も増えコストが膨らんでいく傾向があります。そのため一部の期間のデータだけを確認したいのに、全データをスキャンして課金されるのは非効率ですね。(とは言っても安いんですがついつい甘えがちではありますが。。)

そのため、テーブルを作成する際は基本的にはパーティション射影を使用してテーブルを作成し、必要な範囲のデータのみを効率的に分析できるようにするようにしています。これまでは調査してコピペで作成していたパーティション射影ですが、今回自分で作成することで改めてクエリの意味を理解することができ良い勉強になりました。

パーティション射影を活用することで、Bedrockのログ分析をより効率的に行うことができます。みなさんもAWSのログ分析に取り組む際は、ぜひパーティション射影の活用を検討してみてください。

Discussion