まとめ
dbt-athenaの処理が完了してるはずなのに、使用メモリが上がり続けてOOMが発生
回避はできたけど詳しい原因はわからないまま
発生した事象
- 環境
- ECS(Fargate)
- dbt-athenaでparquetからicebergに変換
dbt-athenaを使用して、179 modelを一回のdbt runで実行(parquetからicebergへ変換)
するとECS Fargateで下記のOOMエラーが発生\"Reason\":\"OutOfMemoryError: Container killed due to memory usage
全てのmodel(179個)の処理は終了している様子なのに、
dbtが最後に出力する[0m07:48:17 Done. PASS=100 WARN=0 ERROR=2 SKIP=0 TOTAL=102
みたいなlogは出力されないままmemoryが上昇していきout of memoryが発生する
根本解決してないけどわかったこと
一部のmodelでpartitioned_byを設定していて、この設定を除去するとOOMは発生しなくなった
query処理時間が長くかかっているmodelを2つ特定した
そのmodelファイルではconfigでpartitioned_by
を指定していた
{{ config(
materialized=incremental(),
unique_key=unique_keys,
partitioned_by=[
"created_at"
]
) }}
この設定を除去したところout of memoryは発生せず正常終了した
timestampカラムをそのままpartition設定するのは、こちらの使用方法のミス(値の数だけpartitionが設定され意味をなさないから)
まだ不明なこと
partitioned_by
を指定していた modelはquery処理時間が長くかかっていたものの、最終的にはquery実行が成功している
dbt側での用途は不明だが、partitoined_byに指定したカラムをdistinctするsqlが2minほどかかっていた
select distinct created_at from "awsdatacatalog"."target_databasenamehoge"."tablenamehoge__tmp_not_partitioned" order by created_at
dbtはなぜqueryの実行完了を検知できなかったのか、何の処理が走ってmemory使用率が上昇したのかは不明
pollingのtimeout設定を追加できたらな…と思って調べたみたけど、dbt-athenaが「athenaのquery実行をどれくらい待つか」の設定値は存在してないみたい
dbt コミュニティのslackにも同じ事象で詰まっている記載は見つけられなかった
備考: 調査のためにやったこと
- Cluster insightの有効化
- –> Memory使用率を確認するため
- dbt threadsを下げる
- ECS TaskのMemory&CPU を上げる
- Elementary関連のコメントアウト
- Cloud Trailの確認
- –> dbtからAWS側に何かリクエストしているかを確認したけど、特に何もしてなかった
- dbt runに
--no-write-json
オプション追加- –> 成果物(run_results.jsonなど)の生成をOFFにする
- Dockerfileに PYTHONUNBUFFERED=1を設定
- –> Python プログラムの 標準出力(stdout)と標準エラー(stderr)をバッファリングせずに、即時に出力する設定
- これも効果無し
- awslogs mode=を
blocking
に変更- –> コンテナのlogを同期的にcloud watch logsに送られるようにする
- 効果無し
- ECSにloginするための設定
- –> すんなり入れなかった^ 入ったところで何をするか決まっていなかったので諦めた
- dbt-athenaからdbt-athena-communityに変更
- –> 効果はなかったけど、dbt-athenaはメンテされていないのでdbt-athena-communityを使う設定にしておく
- dbt/targetの容量を確認するためentrypoint.shを追加
- –> dbtが成果物の生成を完了させた後、memoryが上昇していっていると判断できた
- dbt-core, dbt-athena-communityをdown grade
- dbtのselectors.yml(tag設定)を設定し、分割してdbt runをおこなった
- –> query処理時間が長くかかっているmodelを2つ特定できた
最後に
まだまだ謎が多い…
思い出としてここに残しておきます