Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Athenaを使ったバッチ処理のTIPS

 Athenaを使ったバッチ処理のTIPS

https://jawsug-bigdata.connpass.com/event/200841/

BigData-JAWS 勉強会#16 LT 資料

UZOUでのAthenaの設計の話はブログにも書いていますので興味があればぜひ
https://tech.speee.jp/entry/2020/11/10/111154

kanga333

March 01, 2021
Tweet

More Decks by kanga333

Other Decks in Programming

Transcript

  1. まずは基本を抑える データをパーティショニングする partition projection を使うとパーティション管理不要で便利 列指向フォーマット+圧縮を使⽤する 列指向 : ORC or

    Parquet おすすめは Parquet 各種SaaSやミドルウェアのサポートが⼿厚い S3 Select とか 圧縮: Snappy or Gzip おすすめは Gzip Athenaはスキャン量課⾦なのでCPUコストより圧縮率が⼤事
  2. クエリ結果のサイズが⼤きいと遅い実例 Parquet形式のALBログ(30ファイル、計1.8GB)から request_url のパス別の件数を 取得するクエリ SELECT url_extract_path(request_url), count(*) FROM alb_logs

    GROUP BY url_extract_path(request_url) 結果 Run time: 4.64 seconds Data scanned: 976.47 MB クエリ結果ファイル: 6KB クエリとしては複雑になってるが素朴なSELECTより遥かに早い クエリ結果ファイルがデカくなるとAthenaは遅くなる
  3. 対応: CTASクエリでデータを書き出してダイレクトにDLする CREATE TABLE AS SELECT ( CTAS )クエリはSELECT結果を新しいテーブルとして作成 できる

    CTASクエリは参照結果を新しいテーブル定義+S3上のデータとして作成する データは分散されたワーカーから複数個に分割されて作成されるので効率が良い バッチのクライアントはCTASでS3に⽣成したデータを直接DLして使⽤する クエリ実⾏時に透過的にCTASで実⾏してくれるモードを持つライブラリ awslabs/aws-data-wrangler speee/go-athena
  4. 実例のクエリをCTASで実⾏すると CREATE TABLE tmp_table WITH (format='PARQUET') AS SELECT request_url FROM

    alb_logs 結果 Run time: 11.68 seconds Data scanned: 976.47 MB CTASで⽣成したデータ: 30ファイル、計977.3 MB 同じデータを出⼒するにしてもCTASの⽅が7倍以上早い
  5. 時系列パーティション、細かく切るか?ざっくり切るか? 例: 2021年1⽉30⽇から2021年2⽉1⽇までのデータを参照したい -- 細く切った場合 year='2021' AND ( (month='01' AND

    day >= '30') OR (month='02' AND day <= '01') ) ) -- ざっくり切った場合 dt BETWEEN '20210130' AND '20210201' ざっくり切った場合は開始と終了だけ指定すれば良いので楽
  6. 細く切っても⼤丈夫!複雑な時間指定でパーティションを絞る DATE_PARSEのような関数を通してもパーティションのフィルタリングは効く WHERE DATE_PARSE(concat(dt, hour),'%Y%m%d%H') >= timestamp '2021-02-01 00:00:00 Asia/Tokyo'

    AND DATE_PARSE(concat(dt, hour),'%Y%m%d%H') < timestamp '2021-02-04 00:00:00 Asia/Tokyo' このクエリとスキャン量の絞り込みは同じ WHERE (dt = '20210131' AND hour >= '15' ) OR dt = '20210201' OR dt = '20210202' OR (dt = '20210203' AND hour < '15' ) ただし関数を通しているケースだとシンプルな絞り込みと⽐べて多少遅い
  7. Parquetを使っていればパーティションはざっくり指定でも⼤丈夫 Parquetを使っていてデータ本体に時刻カラムがある場合パーティションカラムでざっく り絞って時刻カラムでちゃんと絞ってもスキャン量は抑えることでできる こんな感じのクエリ(timeはデータ本体にあるdatetime型のカラムと仮定) WHERE dt BETWEEN '20210131' AND '20210203'

    AND time >= timestamp '2021-02-01 00:00:00 Asia/Tokyo' AND time < timestamp '2021-02-04 00:00:00 Asia/Tokyo' Parquetファイルはフッターに各カラムの統計情報(Max/Min/Count)を持っており Athenaはそこを参照して効率よくスキャンをスキップできる 但しS3のGET APIのコストは余分にかかるので注意
  8. 意外とS3のGetリクエストのコストがかかる AthenaのコストといえばScanのコストばかり気にしがちだがS3へのGetリクエストのコ ストも意外とチリツモでかかる 実験 Parquet形式のALBログ(30ファイル、計1.8GB)に以下のクエリを実⾏ SELECT url_extract_path(request_url), count(*) FROM alb_logs_access

    WHERE elb_status_code = '200' このクエリがS3にアクセスした回数は160回(S3のメトリクスフィルタ調べ) Athenaはスキャン対象の個数 = S3へのリクエスト回数となる訳では無い クエリが早くなるように⾊々最適なアクセスを試みてくれる