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

[Tech × Marketing meetup #4] 秒間1万のイベントログをDHWにETLするまで

[Tech × Marketing meetup #4] 秒間1万のイベントログをDHWにETLするまで

Hiromu Kobayashi (himu)

October 14, 2020
Tweet

Other Decks in Technology

Transcript

  1. 最初はAthenaを使っていた メリット • 手軽 • S3に置いたログをそのまま読める デメリット • 遅い •

    テーブル定義が面倒(スキーマの変更に弱い) • パーティションの作られるタイミングが謎 社内ではBigQueryをよく使ってるし、そっちに乗っけてしまいたい…
  2. Lambda • s3:ObjectCreated でトリガー • パス構造、オブジェクト名そのままにコピーするだけ for record in event['Records']:

    stream = io.BytesIO() s3_bucket = record['s3']['bucket']['name'] key = unquote_plus(record['s3']['object']['key']) s3_client.download_fileobj (s3_bucket, key, stream) gcs_bucket = gcs_client.bucket('hogehoge') blob = gcs_bucket.blob(key) blob.upload_from_string (stream.getvalue())
  3. BigQuery External Table • 雑に言うと「GCP版Athena」 • Google Cloud Storageなどに置いたファイルをBigQueryで読める •

    Loadできるフォーマットなら使える (CSV, JSON Lines, etc.) • HIVEパーティションが使える • Cloud Storage ソースで使ってみた感じ、かなり速い bq mk --external_table_definition=tabledef.json dataset.table
  4. 外部テーブル定義ファイルはJSON { "csvOptions": { "fieldDelimiter" : "", "quote": "" },

    "schema": { "fields": [ { "name": "fields", "type": "STRING" } ] }, "sourceFormat" : "CSV", "sourceUris": [ "gs://hogehoge/*.gz" ], "hivePartitioningOptions" : { "mode": "STRINGS", "sourceUriPrefix" : "gs://hogehoge/" , "requirePartitionFilter" : true } } ここに制御文字を使いたい 課金事故を防ぐために クエリ時のパーティション指定を強制
  5. 怒られる File ".../bq/third_party/yaml/lib2/reader.py", line 144, in check_printable 'unicode', "special characters

    are not allowed") ReaderError: unacceptable character #x0001: special characters are not allowed in "tabledef.json", position 174
  6. BigQuery Scheduled Queries • 指定クエリを定期実行してくれる ◦ 1日ごと、1時間ごと、cronもどきなど • クエリパラメータに実行時間を使える ◦

    @run_time (TIMESTAMP型) • クエリ結果のテーブルを作れる ◦ destination table ◦ テーブル名に実行時間をフォーマットして使える ▪ table_{run_time+8h|"%Y%m%d"} • 1時間前のデータを1時間後にクエリするので+8h
  7. クエリ抜粋 SELECT JSON_EXTRACT_SCALAR(fields, '$.req.id') AS `req_id`, STRUCT< `creative_id` STRING, `price`

    FLOAT64 >( JSON_EXTRACT_SCALAR(fields, '$.res.creative_id'), CAST(JSON_EXTRACT_SCALAR(fields, '$.res.price') AS FLOAT64) ) AS `res`, JSON_EXTRACT(fields, '$.debug') AS `debug`, FROM `hogehoge` WHERE ts = FORMAT_TIMESTAMP('%Y%m%d%H', TIMESTAMP_ADD(@run_time, INTERVAL -1 HOUR))
  8. まとめ • BigQueryは便利だぞ! • External Tableは銀の弾丸かも ◦ ゆるふわスキーマもOK ◦ bq

    load に悩まされることもない ◦ 速いは正義 • Scheduled Queriesは癖があるけど使いこなせると便利