ユースケースおよびアーキパターン
ユースケース
Section titled “ユースケース”1. ログ分析
Section titled “1. ログ分析”シナリオ: - CloudFront / ALB / VPC Flow Logs分析 - S3に保存されたログ - アドホッククエリ
実装: 1. ログをS3に保存 2. Glue Crawlerでテーブル作成 3. Athenaでクエリ 4. QuickSightで可視化2. データレイク分析
Section titled “2. データレイク分析”シナリオ: - 大量データをS3に集約 - 部門横断的な分析 - コスト効率重視
実装: データ収集: - Kinesis Firehose - AWS Glue ETL - Database Migration Service
カタログ: - Glue Crawler - 自動スキーマ管理
分析: - Athena(アドホック) - QuickSight(ダッシュボード)3. コスト分析
Section titled “3. コスト分析”シナリオ: - Cost and Usage Report分析 - リソース使用状況分析 - タグベースコスト配分
実装: 1. CURをS3に出力(Parquet) 2. Glue Crawlerでカタログ作成 3. Athenaでクエリ - サービス別コスト - タグ別集計 - トレンド分析アーキテクチャパターン
Section titled “アーキテクチャパターン”パターン1: 基本的なログ分析
Section titled “パターン1: 基本的なログ分析”graph TB subgraph "Data Source" ALB["Application Load Balancer"] CloudFront["CloudFront"] VPC["VPC Flow Logs"] end
subgraph "Storage" S3["Amazon S3<br/>ログファイル"] end
subgraph "Catalog" Crawler["Glue Crawler<br/>スキーマ検出"] Catalog["Glue Data Catalog<br/>メタデータ"] end
subgraph "Query" Athena["Amazon Athena<br/>SQL クエリ"] end
subgraph "Visualization" QuickSight["Amazon QuickSight<br/>ダッシュボード"] end
ALB -->|ログ出力| S3 CloudFront -->|ログ出力| S3 VPC -->|ログ出力| S3
S3 --> Crawler Crawler --> Catalog
Catalog --> Athena Athena --> QuickSight構成: ALB: - アクセスログ → S3
S3: - ログファイル保存 - パーティション: year/month/day
Glue Crawler: - 自動テーブル作成 - パーティション検出
Athena: - SQLクエリ
QuickSight: - ダッシュボード
SQL例: SELECT request_url, COUNT(*) as access_count, AVG(target_processing_time) as avg_response_time FROM alb_logs WHERE year='2024' AND month='01' GROUP BY request_url ORDER BY access_count DESC LIMIT 10パターン2: データ変換パイプライン
Section titled “パターン2: データ変換パイプライン”構成: ソースデータ(S3): - CSV / JSON - 非最適化
Athena CTAS: - Parquet変換 - パーティション作成 - 圧縮
変換後データ(S3): - Parquet - 最適化済み
Athena: - 高速クエリ - コスト削減
CTAS例: CREATE TABLE optimized_logs WITH ( format='PARQUET', parquet_compression='SNAPPY', partitioned_by=ARRAY['year','month','day'], external_location='s3://bucket/optimized/' ) AS SELECT *, year(timestamp) as year, month(timestamp) as month, day(timestamp) as day FROM raw_logsパターン3: フェデレーテッドクエリ
Section titled “パターン3: フェデレーテッドクエリ”構成: データソース: - S3(履歴データ) - RDS(最新データ) - DynamoDB(メタデータ)
Lambda Data Source Connector: - RDS接続 - DynamoDB接続
Athena: - 横断クエリ - JOIN可能
SQL例: SELECT s3_logs.user_id, COUNT(*) as access_count, rds_users.user_name, rds_users.subscription_tier FROM s3_logs JOIN rds_users ON s3_logs.user_id = rds_users.id WHERE s3_logs.year='2024' GROUP BY s3_logs.user_id, rds_users.user_name, rds_users.subscription_tierパターン4: 準リアルタイム分析
Section titled “パターン4: 準リアルタイム分析”構成: Kinesis Firehose: - データ収集 - S3配信(バッファ60秒) - Parquet変換
Glue Crawler: - 定期実行(5分毎) - パーティション更新
Athena: - 最新データクエリ
QuickSight: - SPICEリフレッシュ - ダッシュボード更新
特徴: - 準リアルタイム(数分遅延) - サーバーレス - コスト効率テーブル作成(DDL)
Section titled “テーブル作成(DDL)”-- 外部テーブル作成CREATE EXTERNAL TABLE IF NOT EXISTS alb_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 string, 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)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.-]*)$')LOCATION 's3://my-bucket/alb-logs/';
-- パーティション追加ALTER TABLE alb_logs ADDPARTITION (year='2024', month='01', day='01')LOCATION 's3://my-bucket/alb-logs/year=2024/month=01/day=01/';
-- パーティション自動検出MSCK REPAIR TABLE alb_logs;CTAS(データ変換)
Section titled “CTAS(データ変換)”-- CSV → Parquet変換CREATE TABLE analytics_events_parquetWITH ( format = 'PARQUET', parquet_compression = 'SNAPPY', partitioned_by = ARRAY['event_date'], external_location = 's3://my-bucket/optimized/events/') ASSELECT user_id, event_type, event_timestamp, properties, CAST(date_format(from_iso8601_timestamp(event_timestamp), '%Y-%m-%d') AS VARCHAR) as event_dateFROM analytics_events_csvWHERE year = '2024' AND month = '01';
-- 集計結果保存CREATE TABLE daily_summaryWITH ( format = 'PARQUET', external_location = 's3://my-bucket/summary/') ASSELECT event_date, event_type, COUNT(DISTINCT user_id) as unique_users, COUNT(*) as total_events, AVG(CAST(json_extract_scalar(properties, '$.duration') AS DOUBLE)) as avg_durationFROM analytics_events_parquetGROUP BY event_date, event_type;クエリ最適化例
Section titled “クエリ最適化例”-- ❌ 非効率SELECT * FROM logsWHERE timestamp > '2024-01-01';
-- ✅ 効率的(パーティション利用)SELECT user_id, event_type, timestampFROM logsWHERE year='2024' AND month='01' AND event_type = 'purchase';
-- ✅ サブクエリ最適化WITH filtered_logs AS ( SELECT user_id, event_type, properties FROM logs WHERE year='2024' AND month='01' AND event_type IN ('purchase', 'signup'))SELECT event_type, COUNT(DISTINCT user_id) as unique_usersFROM filtered_logsGROUP BY event_type;Prepared Statements
Section titled “Prepared Statements”-- クエリパラメータ化PREPARE query_by_date FROMSELECT user_id, event_type, COUNT(*) as countFROM logsWHERE year = ? AND month = ?GROUP BY user_id, event_type;
-- 実行EXECUTE query_by_date USING '2024', '01';アーキテクチャ設計のポイント:
- Parquet/ORC でコスト削減
- パーティション設計でスキャン量削減
- Glue Crawler で自動カタログ管理
- CTAS でデータ最適化
- QuickSight で可視化
- フェデレーテッドクエリで柔軟な分析
- ワークグループでアクセス制御