この記事は、ニフティグループ Advent Calendar 2024 23日目の記事です。
はじめに
こんにちは、新卒1年目の後藤です。
今回は、S3内にあるALBのアクセスログをAthenaで確認する方法について、記載していこうと思います。
Amazon Athenaとは
クラウドインフラの運用において、ログ分析は不可欠です。
AWSでは、多くのサービスがログをAmazon CloudWatchとAmazon S3で保存しています。
しかし、蓄積された大量のログデータを効率的に分析することは、いずれも困難です。
ここで登場するのがAmazon Athenaです。
Amazon Athenaは、標準SQLを使用してS3のデータを直接クエリできるサーバーレスの対話型クエリサービスです。
Athenaを使用することで、複雑なインフラ設定なしに、S3の大規模なログデータを効率的に分析できます。
環境設定
Athenaを使用するには、以下のAWSサービスへのアクセス権限が必要です:
- Amazon S3
- S3バケットへの読み取り権限
- Amazon Athena
- Athenaクエリの実行権限
S3バケットの設定
1. ログを保存するS3バケットを作成または確認します。
2. バケットポリシーを適切に設定します。
- Athenaからの読み取り権限を許可する
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "athena.amazonaws.com" }, "Action": [ "s3:GetBucketLocation", "s3:GetObject", "s3:ListBucket" ], "Resource": [ "arn:aws:s3:::your-bucket-name", "arn:aws:s3:::your-bucket-name/*" ] } ] } |
- 必要に応じて、特定のIAMロールやユーザーからのアクセスのみを許可する
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::123456789012:role/YourRoleName" }, "Action": [ "s3:GetObject", "s3:PutObject" ], "Resource": [ "arn:aws:s3:::your-bucket-name/*" ] } ] } |
注意: 上記のポリシーは一例なので、実際の環境に合わせて適切に調整してください。
3. 必要な権限を付与します。
- s3:GetBucketLocation – バケットの場所を取得する権限
- s3:GetObject – オブジェクトを読み取る権限
- s3:ListBucket – バケット内のオブジェクトを一覧表示する権限
- s3:PutObject – クエリ結果を保存する権限(結果を S3 に保存する場合)
設定
ログを保存するS3バケットを指定
Location of query resultでログを保存するS3バケットを指定します。
Browse S3で選択することも可能です。
データベースの作成
以下コマンドをクエリで実行します。
1 |
CREATE DATABASE your_database; |
- [Run] (実行) をクリックするか、
Ctrl+ENTER
キーを押します。 - 左側の [Database] (データベース) リストから、現在のデータベースとして
your_database
を選択します。
テーブルの作成
- 今回はALBのアクセスログ用のテーブルを作成します。
- 使用したいログやデータに合わせて変更してください。
- 作成したデータベース(
your_database
)を選択 - クエリで以下コマンドを実行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
CREATE EXTERNAL TABLE IF NOT EXISTS alb_access_logs ( type string, time string, elb string, client_ip string, client_port int, target_ip string, target_port int, request_processing_time double, target_processing_time double, response_processing_time double, elb_status_code int, target_status_code string, received_bytes bigint, sent_bytes bigint, request_verb string, request_url string, request_proto string, user_agent string, ssl_cipher string, ssl_protocol string, target_group_arn string, trace_id string, domain_name string, chosen_cert_arn string, matched_rule_priority string, request_creation_time string, actions_executed string, redirect_url string, lambda_error_reason string, target_port_list string, target_status_code_list string, classification string, classification_reason string, conn_trace_id string ) PARTITIONED BY ( year string, month string, day string ) ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe' WITH SERDEPROPERTIES ( 'serialization.format' = '1', 'input.regex' = '([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*):([0-9]*) ([^ ]*)[:-]([0-9]*) ([-.0-9]*) ([-.0-9]*) ([-.0-9]*) (|[-0-9]*) (-|[-0-9]*) ([-0-9]*) ([-0-9]*) \\"([^ ]*) (.*) (- |[^ ]*)\\" \\"([^\\"]*)\\" ([A-Z0-9-_]+) ([A-Za-z0-9.-]*) ([^ ]*) \\"([^\\"]*)\\" \\"([^\\"]*)\\" \\"([^\\"]*)\\" ([-.0-9]*) ([^ ]*) \\"([^\\"]*)\\" \\"([^\\"]*)\\" \\"([^ ]*)\\" \\"([^\\\\s]+?)\\" \\"([^\\\\s]+)\\" \\"([^ ]*)\\" \\"([^ ]*)\\" ?([^ ]*)?' ) LOCATION 's3://your-bucket-name/access-log-folder-path/' TBLPROPERTIES ( 'projection.enabled'='true', 'projection.year.type' = 'integer', 'projection.year.range' = '2024,2050', 'projection.year.interval' = '1', 'projection.month.type' = 'integer', 'projection.month.digits'='2', 'projection.month.range' = '1,12', 'projection.day.type' = 'integer', 'projection.day.digits'='2', 'projection.day.range' = '1,31', 'storage.location.template' = 's3://your-bucket-name/access-log-folder-path/year=${year}/month=${month}/day=${day}' ); |
- [Run] (実行) を選択。
- テーブル
alb_access_logs
が作成され、your_database
データベースの [Tables] (テーブル) リストに表示されます。
- テーブル
公式から追加した箇所の説明
PARTITIONED BYの説明
PARTITIONED BY
テーブルをパーテーション化することを宣言しています。- パーテーション化は、大規模なデータセットを小さな、管理しやすい部分に分割することです。
year string
,month string
,day string
パーテーションキーとして使用され、それぞれがstring型で定義されています。年、月、日の順で階層的にパーティションが作成されます。
TBLPROPERTIESの説明
'projection.enabled'='true'
Partition Projectionを有効にします。クエリ時にPartitionを動的に生成できます。'projection.year.type' = 'integer'
,'projection.month.type' = 'integer'
,'projection.day.type' = 'integer'
年、月、日のPartitionがそれぞれ整数型であることを指定します。'projection.year.range' = '2024,2050'
年の範囲を2024年から2050年までと指定します。'projection.year.interval' = '1'
年のPartitionが1年ごとに増加することを指定します。'projection.month.digits'='2'
,'projection.day.digits'='2'
月と日のPartitionが2桁の数字で表されることを指定します。'projection.month.range' = '1,12'
月のPartitionが1から12までの範囲であることを指定します。'projection.day.range' = '1,31'
日のパーティションが1から31までの範囲であることを指定します。'storage.location.template'
S3内のデータの実際の格納場所のテンプレートを指定します。${year}
,${month}
,${day}
はそれぞれ年、月、日の値に置き換えられます。
データの取得
テーブルを作成したら、実際にデータを取得してみます。
基本的なクエリ
- 最新のログエントリを10件取得する:
SELECT * FROM alb_access_logs WHERE year = 2024 AND month = 12 AND day = 12 LIMIT 10;
- コンソールの下に結果が表示されるので確認します。
パフォーマンスとコスト最適化
Athenaにデータを設定する際の最適化
1. パーテーションの活用
- 適切なパーティションにより、スキャンするデータ量を減らし、クエリ速度を向上させ、コストを削減することが可能です。
- 今回はs3://~/YYYY/MM/DDのようにデータが保存されているので、以下のように
PARTITIONED BY
でパーテーションを設定することが可能です。
1 2 3 4 5 |
PARTITIONED BY ( year string, month string, day string ) |
2. 圧縮の使用
- ログファイルをgzipなどで圧縮することで、ストレージコストとクエリ時間を削減できます。
- gzipに圧縮した際は、テーブル定義の
TBLPROPERTIES
内に'compression.type'='gzip'
を追加することを忘れないようにしましょう。
実際に検索する際の最適化
- 必要な列のみを選択
SELECT *
の使用は避け、必要な列のみを指定します。- 例:
SELECT time, elb_status_code, request_url FROM alb_access_logs WHERE ...
- LIMIT句の使用
- 大量のデータを扱う場合、LIMIT句を使用して結果セットを制限します。
- 例:
SELECT * FROM alb_access_logs LIMIT 100;
これらの最適化技術を適用することで、Athenaの使用をより効率的にし、コストを抑えることができます。定期的にクエリのパフォーマンスとコストを監視し、必要に応じて調整を行うことが重要です。
まとめ
Amazon Athenaを使用してS3のログを分析することで、大規模なデータセットに対して効率的かつ柔軟なクエリが可能になります。
主要なポイントは以下の通りです:
- Athenaの基本設定
- クエリ結果の保存場所の指定
- データベースとテーブルの作成
- テーブル設計の重要性
- 適切なカラム定義
- パーティショニングの活用
- 効率的なクエリ実行
- 基本的なSQLクエリの構造
- パーティションを利用したデータフィルタリング
- パフォーマンスとコスト最適化
- 必要な列のみの選択
- LIMIT句の使用
- データの圧縮
Athenaを活用することで、複雑なインフラストラクチャを管理することなく、S3に保存されたログデータから迅速に得ることができます。 パフォーマンスとコストの最適化テクニックを適用することで、より効率的にデータ分析を行うことが可能です。
最後に、常にAWSのベストプラクティスとセキュリティガイドラインに従い、コストとパフォーマンスのバランスを取りながら、Athenaを活用しましょう。
参考文献
https://docs.aws.amazon.com/ja_jp/athena/latest/ug/what-is.html
https://docs.aws.amazon.com/athena/latest/ug/create-alb-access-logs-table.html
次の記事もお楽しみに!