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

BigQueryクエリの処理の流れ

 BigQueryクエリの処理の流れ

GoogleCloudPlatformJapan

April 24, 2015
Tweet

More Decks by GoogleCloudPlatformJapan

Other Decks in Programming

Transcript

  1. BigQueryクエリの
    処理の流れ
    Jordan Tigani
    BigQuery Software Engineer

    View Slide

  2. ゴール:BigQueryクエリの一連の処理手順を追う
    注:ここに記されたアーキテクチャの内容や役割は、
    - すぐ古くなったり
    - 詳細は端折られてたり
    - いずれ変更されたり*します
    *これがBigQueryの大きなメリットです。見えないところでつねに
    改善が続けられています

    View Slide

  3. 最近のアーキテクチャ改善の例
    シャッフルのスループットが4倍に
    クラスタサイズが5倍に
    クラスタが追加
    ディスク保存のフォーマットを変更
    (ColumnIOからの置き換え)
    ディスク保存のエンコード形式を変更
    (耐久性の向上、サイズの縮小)
    残念ながら、詳細は紹介できません

    View Slide

  4. クエリを実行してみよう
    SELECT language, SUM(views) as views
    FROM (
    SELECT title, language, MAX(views) as views
    FROM [helixdata2:benchmark.Wiki100B]
    WHERE REGEXP_MATCH(title, "G.*o.*")
    GROUP EACH BY title, language
    )
    GROUP EACH BY language
    ORDER BY views desc

    View Slide

  5. 1000億行に対する複雑なクエリ実行時の性能
    実行時間:21秒
    - 4 TBのデータを読み込み
    - 1000億行に対する正規表現の適用
    - 278 GBのデータをシャッフル
    並列処理しなかったら:
    - 4 TBのディスク読み込みに11.6時間(100 MBpsの場合)
    - 1000億行の正規表現処理に27時間(1行あたり1 μsecの場合)
    - 278 GBのシャッフルに37分(1Gbpsの場合)

    View Slide

  6. curlでクエリを実行する
    curl -H "$(python auth.py)" \
    -H "Content-Type: application/json" \
    -X POST \
    -d {'jobReference': { \
    'jobId': 'job_1429217599', \
    'projectId': 'bigquery-e2e'}, \
    'configuration': { \
    'query': { \
    'query': 'SELECT ...’}}} \
    "https://www.googleapis.com/bigquery/v2/projects/bigquery-e2e/jobs"

    View Slide

  7. リクエストの中身は...
    POST /bigquery/v2/projects/bigquery-e2e/jobs HTTP/1.1
    User-Agent: curl/7.30.0
    Host: www.googleapis.com
    Accept: */*
    Authorization: Bearer
    Content-Type: application/json
    Content-Length: 126
    {'jobReference': {'jobId': 'job_1429217599', 'projectId': 'bigquery-e2e'},
    'configuration': {'query': {'query': 'SELECT 17'}}}

    View Slide

  8. Client
    HTTP
    POST
    GFE
    JSON API
    frontend
    HTTP
    JSON
    HTTP
    BigQuery
    API Server
    protobuf
    gRPC
    ジョブの投入

    View Slide

  9. リクエストがBigQueryに届くまで...
    GFE
    - GoogleネットワークへのHTTP接続を受け付け
    - DoS対策
    - 一般的なHTTPヘッダの処理
    Google API Frontend
    - JSONとProtocol Buffer間の変換
    - HTTPとStubby/gRPC間の変換
    - リクエスト認証

    View Slide

  10. HTTP
    POST
    クエリジョブの状態変化
    HTTP Error
    HTTP
    OK
    OK?
    OK?
    OK?
    PENDING RUNNING
    DONE w/
    errorResult
    DONE
    no
    no
    no
    yes yes
    yes

    View Slide

  11. Client
    HTTP
    POST
    GFE
    200 OK API
    Frontend
    HTTP
    200 OK
    HTTP
    BigQuery
    API Server
    protobuf
    gRPC
    Spanner
    新規ジョブ Stubby
    ジョブ投入の完了

    View Slide

  12. レスポンスヘッダ
    HTTP/1.1 200 OK
    Cache-Control: no-cache, no-store, max-age=0, must-revalidate
    Pragma: no-cache
    Vary: X-Origin
    Content-Type: application/json; charset=UTF-8
    Server: GSE
    Accept-Ranges: none
    Vary: Origin,Accept-Encoding
    Transfer-Encoding: chunked

    View Slide

  13. レスポンスデータ
    {
    "kind": "bigquery#job",
    "id": "bigquery-e2e:job_1429217599",
    "jobReference": {"projectId": "bigquery-e2e", "jobId": "job_1429217599"},
    "configuration": {...}
    "status": {
    "state": "RUNNING"
    },
    "statistics": {
    "creationTime": "1429217642957",
    "startTime": "1429217643549"
    },
    "user_email": "[email protected]"
    }

    View Slide

  14. レスポンスデータ(configuration)
    "configuration": {
    "query": {
    "query": "SELECT ...",
    "destinationTable": {
    "projectId": "bigquery-e2e",
    "datasetId": "_0e32b38e1117b2fcea992287c138bd53acfff7cc",
    "tableId": "anon6163a05d4704b78c589f41813708f340a2df2d1f"
    },
    "createDisposition": "CREATE_IF_NEEDED",
    "writeDisposition": "WRITE_TRUNCATE"
    }
    }

    View Slide

  15. 新しいジョブの開始
    1. 確認フェーズ:
    - 認証チェック
    - クオータのチェック
    - 入力内容の検証
    - キャッシュのチェック
    - 出力テーブルの用意
    2. ジョブをメタデータストアに保存
    3. リクエスト元に正常開始を伝える

    View Slide

  16. ところで:BigQueryのキャッシュの動き
    以下のSHA-1ハッシュ値をとる:
    - データ更新時間
    - 参照テーブル
    以下の場合はキャッシュを使わない:
    - 値が変化する関数を使用(NOW()など)
    - 固定の出力テーブルを指定
    - 参照テーブルがストリーミングバッファを使用
    SHA-1ハッシュ値が出力テーブル名となる
    ユーザー単位でキャッシュされる

    View Slide

  17. BigQuery
    APIサーバ
    Spanner
    テーブル
    メタデータ
    Dremel ゲー
    トウェイ
    Dremel
    クエリ Dremelクラスタ
    us-central-1-a
    Dremelクラスタ
    us-central-2-a
    Dremel
    クエリ
    Dremelクエリの開始

    View Slide

  18. Dremelゲートウェイ
    アクセス可能なレプリカを検索
    以下に基づき、クエリの実行に最適な場所を決定:
    - データからの距離
    - クラスタの負荷状況
    データは部分的にレプリケーションされる場合もある

    View Slide

  19. ところで:BigQueryのレプリケーション
    地理的に離れた複数のゾーン間でレプリケーション
    - 可用性の向上
    - ディザスタリカバリ
    データセンター内でのレプリケーション
    - 永続性の向上
    - リード性能の向上
    - リードソロモンに似たエンコーディングを使用
    小さなテーブルはメタデータ内に保存

    View Slide

  20. ところで:BigQueryのStreaming insert
    Streaming insertされたデータはBigtable上にバッファ
    ワーカによって定期的にColossusに保存
    Dremelクエリ実行時はBigtable上のバッファも読み込み
    バッファ内容はdurableだが、大きな障害時には一時的に読み
    込みできなくなる

    View Slide

  21. Dremel ゲー
    トウェイ
    Dremel Root
    Mixer
    Dremel
    クエリ
    Dremel
    Mixer-1
    Dremel
    Mixer-1
    Dremel
    Mixer-1
    Dremel
    Shard
    Dremel
    Shard
    Dremel
    Shard
    Dremel
    Shard
    Dremel
    Shard
    Dremel
    Shard
    Dremelクエリの実行ツリー

    View Slide

  22. Dremel Root Mixer
    クエリプランの構築
    - クエリを複数のステージに分割
    - 処理内容を並列タスクに分割
    クエリのスケジューリング
    - 利用可能なスロットを各ユーザーに分配
    - クエリの割り込み
    クエリを下位のmixer/shardに転送

    View Slide

  23. Dremel Shard
    実行中のクエリの一部分を実行
    ソースからデータを読み込み
    通常はColossusから
    (Streaming時の)Bigtable、またはCloud Storage
    集約処理を部分的に実行

    View Slide

  24. Dremel
    Shard
    Dremel
    Shard
    Dremel
    Shard
    CFS CFS CFS CFS CFS CFS
    分散メタデータ
    分散ファイル
    分散
    ストレージ
    データの読み込み
    Streaming
    BigTable

    View Slide

  25. ストレージ階層
    Colossusメタデータ
    - ディレクトリ構造
    - ACLs
    Colossusファイル
    - ほとんどフラットな構造
    - 一部のACLs
    - 暗号化
    分散ストレージ
    - ディスクエンコード(RAID的なもの)
    - クラスタ内でレプリケーション

    View Slide

  26. カラムストレージ

    View Slide

  27. ColumnIO
    データを行単位ではなくカラム単位で保存
    圧縮効率が向上
    分散ファイルシステムを利用
    - ローカルディスクではシークが多すぎる
    不要なカラムをスキップ
    - クエリの多くはテーブル内の一部のカラムのみ参照
    制約ヘッダ
    - 各カラムのレンジとカーディナリティを保持
    - ファイルのスキップが可能に

    View Slide

  28. Dremel
    Shard
    CFS CFS CFS CFS
    WHERE
    REGEXP_MATCH(
    title, "G.*o.")
    フィルタリングの実行
    CFS
    CFS
    Drmel
    Shard

    View Slide

  29. Dremel
    Shard
    Dremel
    Shard
    Dremel
    Shard
    データのシャッフル
    Dremel
    Shard
    Dremel
    Shard
    Dremel
    Shard

    View Slide

  30. データのシャッフル
    ハッシュ値でデータをパーティション分割
    - 個々のshardで集約が可能
    大きなパーティションはディスクにあふれる
    パーティションのばらつきも起こりうる
    - 例:3億のユニークユーザーIDのうち10%がユーザーID=0

    View Slide

  31. Dremel
    Shard
    Dremel
    Shard
    Dremel
    Shard
    CFS CFS CFS CFSr CFS CFS
    データのマテリアライズ

    View Slide

  32. 結果の出力
    シャッフルした結果はshardに出力
    - shard内で集約されたデータ
    - 大規模な結果も出力可能
    シャッフル不要の結果はmixerに返す
    - mixerで集約を実行
    - 出力可能なサイズは128MBまで

    View Slide

  33. BigQuery
    APIサーバ
    Spanner
    テーブル
    メタデータ
    Dremel ゲー
    トウェイ
    クエリス
    テータス Dremelクラスタ
    us-central-1-a
    クエリス
    テータス
    クエリ結果の保存

    View Slide

  34. クエリ結果の保存
    保存処理はACID特性を持つ
    - クエリ結果はすべてが返されるか、全く返されないか
    - クエリ結果は次のクエリですぐ利用できる
    小さなクエリ結果はメタデータ内部に保存される
    保存時に以下も可能:
    - CREATE_IF_NEEDED指定時のテーブル作成
    - WRITE_TRUNCATE指定時のテーブルまるめ
    - ジョブのステータスをDONEに

    View Slide

  35. jobs.
    getQueryResu
    lts()
    GFE
    APIフロ
    ントエン

    BigQuery
    APIサーバ
    Spanner
    ジョブ
    結果のポーリング

    View Slide

  36. 結果のポーリング
    jobs.getQueryResults()
    - サーバ側でGETをホールド
    - Jobs.insert()のジョブIDを指定
    - ジョブステータス=DONEを待つ
    - タイムアウトしたらリトライ
    1回に1ページごと結果を返す

    View Slide

  37. curlでクエリ結果を取得
    RESULTS_URL=${JOBS_URL}/${JOB_ID}/results
    curl -H "$(python auth.py)" \
    -H "Content-Type: application/json" \
    -X GET \
    "${RESULTS_URL}"

    View Slide

  38. Questions?
    Thank you!
    Contact info:
    e-mail: [email protected]
    twitter: @jrdntgn
    g+: +JordanTigani

    View Slide