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

Repro における Presto の安定化・パフォーマンス改善の歩み / Repro Tech Meetup #9

Repro における Presto の安定化・パフォーマンス改善の歩み / Repro Tech Meetup #9

Takeshi Arabiki

June 04, 2019
Tweet

More Decks by Takeshi Arabiki

Other Decks in Technology

Transcript

  1. Repro における
    Presto の安定化・パフォーマンス改善の歩み
    Repro Tech: 実践・並列分散処理基盤 (2019/06/04)
    Repro株式会社
    Takeshi Arabiki (@a_bicky)

    View Slide

  2. • Twitter: @a_bicky
    • Blog: あらびき⽇記
    • 所属: Repro 株式会社 (2017 年 8 ⽉〜)
    • SRE っぽいことをしたり
    • 分析基盤っぽいことをしたり
    • 開発環境整備をしたり
    • Rails アプリケーション触ったり
    • CTO の⼤規模機能開発のレビューをしたり
    ⾃⼰紹介

    View Slide

  3. View Slide

  4. アナリティクス(分析)
    80+ million sessions / day
    700+ million events / day

    View Slide

  5. マーケティング
    150+ million push notifications / day
    6+ million in-app messages / day

    View Slide

  6. Repro における Presto の活⽤箇所

    View Slide

  7. 配信対象設定

    View Slide

  8. • 分散 SQL クエリエンジン
    • Presto ⾃体はデータストレージとしての機能を持たない
    • リクエストを受け付けて Planning などを⾏う coordinator
    • データを処理する worker
    • 様々なデータソースを同時に扱える
    • Hive (Hadoop File System), MySQL, Cassandra etc.
    • 基本的にオンメモリで処理する
    • メモリに収まらないデータは処理できない
    Presto の概要

    View Slide

  9. • 配信対象条件(ユーザセグメンテーション)から SQL を機械的に⽣成
    • 個々の SQL を最適化することが難しい
    • プッシュ通知の配信直前に対象を計算
    • ⻑時間かかる SQL が発⾏されると予定の配信時間に間に合わない
    • ⻑時間 Presto が落ちるとお客様やアプリのエンドユーザに多⼤な迷惑がかかる
    • アプリによってデータの規模も特性も異なる
    • 特定のアプリだけ問題になることもしばしば
    Presto を使った配信対象ユーザの決定

    View Slide

  10. Rails application
    fluentd-forwarder
    scheduled job
    Amazon Simple
    Storage Service (S3)
    fluentd-aggregator
    Hive
    Presto
    Presto 導⼊当初の構成

    View Slide

  11. Rails application
    fluentd-forwarder
    scheduled job
    Amazon Simple
    Storage Service (S3)
    fluentd-aggregator
    Hive
    Presto
    1. セッションデータを S3 に Put
    ① Post events
    ② Forward events
    ③ Put objects (LZO)

    View Slide

  12. Rails application
    fluentd-forwarder
    scheduled job
    Amazon Simple
    Storage Service (S3)
    fluentd-aggregator
    Hive
    Presto
    2. S3 オブジェクトを temporary table の prefix に移動
    ④ SSM (s3-dist-cp)
    ⑤ Move objects

    View Slide

  13. Rails application
    fluentd-forwarder
    scheduled job
    Amazon Simple
    Storage Service (S3)
    fluentd-aggregator
    Hive
    Presto
    3. Hive で temporary table の内容を挿⼊
    ⑥ HiveQL
    ⑦ Get LZO objects in the temp table
    ⑧ Put parquet objects

    View Slide

  14. Rails application
    fluentd-forwarder
    scheduled job
    Amazon Simple
    Storage Service (S3)
    fluentd-aggregator
    Hive
    Presto
    4. Presto を使ってセグメンテーション
    ⑨ Presto SQL
    ⑩ Get parquet objects in the Hive table
    ⑪ user IDs etc.

    View Slide

  15. Repro が直⾯した様々な問題

    View Slide

  16. • presto-server が頻繁に応答しなくなる
    • Hive の bucketed table を使うと遅い
    • presto-cassandra connector の planning が遅い
    Repro が直⾯した様々な問題(抜粋)

    View Slide

  17. • presto-server が頻繁に応答しなくなる
    • Hive の bucketed table を使うと遅い
    • presto-cassandra connector の planning が遅い
    Repro が直⾯した様々な問題(抜粋)

    View Slide

  18. • Presto は 1 worker 応答しなくなるだけでクエリ全体が失敗する
    • com.facebook.presto.spi.PrestoException: Could not communicate with the remote task.
    • 全 worker がほぼ毎⽇死んで⼤量のアラートが届く
    presto-server が頻繁に応答しなくなる

    View Slide

  19. ある EMR インスタンスのログ
    [[email protected] ~]$ dmesg -T | grep -i kill | tail
    [Sun Apr 22 00:12:02 2018] Out of memory: Kill process 4577 (snip)
    [Sun Apr 22 00:12:02 2018] Killed process 4577 (presto-server) (snip)
    [Tue Apr 24 00:12:34 2018] presto-server invoked oom-killer: (snip)
    (snip)
    [Tue Apr 24 00:12:34 2018] Out of memory: Kill process 21281 (snip)
    [Tue Apr 24 00:12:34 2018] Killed process 21281 (presto-server) (snip)
    [Wed Apr 25 00:12:37 2018] thread.rb:70 invoked oom-killer: (snip)
    (snip)
    [Wed Apr 25 00:12:38 2018] Out of memory: Kill process 26967 (snip)
    [Wed Apr 25 00:12:38 2018] Killed process 26967 (presto-server) (snip)

    View Slide

  20. [[email protected] ~]$ dmesg -T | grep -i kill | tail
    [Sun Apr 22 00:12:02 2018] Out of memory: Kill process 4577 (snip)
    [Sun Apr 22 00:12:02 2018] Killed process 4577 (presto-server) (snip)
    [Tue Apr 24 00:12:34 2018] presto-server invoked oom-killer: (snip)
    (snip)
    [Tue Apr 24 00:12:34 2018] Out of memory: Kill process 21281 (snip)
    [Tue Apr 24 00:12:34 2018] Killed process 21281 (presto-server) (snip)
    [Wed Apr 25 00:12:37 2018] thread.rb:70 invoked oom-killer: (snip)
    (snip)
    [Wed Apr 25 00:12:38 2018] Out of memory: Kill process 26967 (snip)
    [Wed Apr 25 00:12:38 2018] Killed process 26967 (presto-server) (snip)
    _⼈⼈⼈⼈⼈⼈⼈_
    > OOM Killer <
     ̄Y^Y^Y^Y^Y^Y^Y^ ̄
    あるインスタンスのログ

    View Slide

  21. • システム全体のメモリ: 60 GB
    • presto-server の RSS: 42 GB
    • yarn ユーザプロセスの合計 RSS: 15 GB
    OMM Killer 発動時の状況
    Hive
    Presto

    View Slide

  22. • Presto と YARN アプリケーションの共存を避ける
    • EMR は Presto と YARN アプリケーションが共存する場合の⾯倒までは⾒ない
    • EMR クラスタは起動に 10 分程度かかるのでホットスタンバイクラスタが欲しい
    • 当時は EMR でマルチマスター構成にできなかった
    Hive ⽤クラスタと Presto ⽤クラスタを分ける

    View Slide

  23. Amazon Simple
    Storage Service (S3)
    fluentd-aggregator
    Hive
    Hive⽤兼ホットスタンバイクラスタ
    Presto
    Presto専⽤クラスタ
    クラスタを分けた後の構成
    Rails application
    fluentd-forwarder
    scheduled job

    View Slide

  24. • presto-server が頻繁に応答しなくなる
    • Hive の bucketed table を使うと遅い
    • presto-cassandra connector の planning が遅い
    Repro が直⾯した様々な問題(抜粋)

    View Slide

  25. • データセットを管理しやすい部分に分割するためのテクニック
    • 「プログラミング Hive」の「9.6 テーブルデータストレージのバケット化」より
    • 複数カラムでパーティションを構成するのに⽐べて次の効果が期待できる
    • 各ファイル(S3 オブジェクト)が⼩さくなり過ぎない
    • メタデータの更新が速い
    • bucket 化するカラムの値から配置する bucket が⼀意に決まる
    • 特定の bucket のデータだけが必要な場合に効率的にデータを取得できる
    • Hive on Tez では hive.tez.bucket.pruning=true, hive.optimize.index.filter=true が必要
    • Presto では特別な設定不要
    Hive の bucketed table

    View Slide

  26. Bucketed table の具体例
    CREATE TABLE users(user_id BIGINT, name STRING)
    PARTITIONED BY(app_id INT) CLUSTERED BY(user_id) INTO 256 BUCKETS;
    INSERT INTO users PARTITION (app_id=1) VALUES (1, 'foo'), (2, 'bar'), (255, 'baz');
    $ hdfs dfs -ls /user/hive/warehouse/users/app_id=1/ | awk '{ print $8 }'
    /user/hive/warehouse/users/app_id=1/000001_0
    /user/hive/warehouse/users/app_id=1/000002_0
    ← user_id % 256

    View Slide

  27. Bucketed table だと特定の worker にデータが集中

    View Slide

  28. Bucketed table だと特定の worker にデータが集中

    View Slide

  29. • 同じテーブルの同じ bucket 番号のファイルは全部同じ worker が処理する
    • テーブル設計を上⼿くやらないと特定の worker にデータが集中する
    • hive.bucket_execution_enabled=false を指定することで無効化できる
    Presto における bucketed table の扱い

    View Slide

  30. hive.bucket_execution_enabled=false の効果
    Elapsed time: 36.72m → 5.67m

    View Slide

  31. • presto-server が頻繁に応答しなくなる
    • Hive の bucketed table を使うと遅い
    • presto-cassandra connector の planning が遅い
    Repro が直⾯した様々な問題(抜粋)

    View Slide

  32. Cassandra の導⼊
    http://joker1007.hatenablog.com/entry/2018/06/29/201400

    View Slide

  33. Cassandra 導⼊背景・効果
    • リアルタイム性の向上
    • 更新処理のシンプル化

    View Slide

  34. Cassandra 導⼊後の構成
    Amazon Simple
    Storage Service (S3)
    Rails application
    fluentd-forwarder
    scheduled job
    Hive
    Hive⽤兼ホットスタンバイクラスタ
    Presto
    Presto専⽤クラスタ
    fluentd-aggregator
    ⼀部で使⽤
    メインで使⽤

    View Slide

  35. Amazon Simple
    Storage Service (S3)
    Rails application
    fluentd-forwarder
    scheduled job
    Hive
    Hive⽤兼ホットスタンバイクラスタ
    Presto
    Presto専⽤クラスタ
    fluentd-aggregator
    1. セッションデータを Cassandra に Insert
    ① Insert data

    View Slide

  36. Amazon Simple
    Storage Service (S3)
    Rails application
    fluentd-forwarder
    scheduled job
    Hive
    Hive⽤兼ホットスタンバイクラスタ
    Presto
    Presto専⽤クラスタ
    fluentd-aggregator
    2. Presto を使ってセグメンテーション
    ② Presto SQL
    ④ user IDs etc.
    ③ Get data in the Cassandra table

    View Slide

  37. 遅い Planning
    {
    "elapsed_time": "80620",
    "execution_time": "6833",
    "distributed_planning_time": "9",
    "analysis_time": "73698"
    }

    View Slide

  38. 遅い Planning
    {
    "elapsed_time": "80620",
    "execution_time": "6833",
    "distributed_planning_time": "9",
    "analysis_time": "73698"
    }
    74 秒!!!!

    View Slide

  39. • Presto の coordinator はパーティションの情報を使って planning する
    • Cassandra はパーティションの有無について情報を保持していない
    • Hive の場合は Hive metastore に保持している
    Presto の Planning

    View Slide

  40. presto-cassandra によるパーティション情報取得
    https://github.com/prestodb/presto/blob/0.203/presto-cassandra/src/main/java/com/facebook/presto/cassandra/NativeCassandraSession.java#L418-L420

    View Slide

  41. presto-cassandra によるパーティション情報取得
    https://github.com/prestodb/presto/blob/0.203/presto-cassandra/src/main/java/com/facebook/presto/cassandra/NativeCassandraSession.java#L418-L420
    WHERE 句に指定されたパーティションの
    組み合わせの数だけ SELECT DISTINCT を発⾏

    View Slide

  42. パーティションの組み合わせの例
    SELECT
    *
    FROM
    cassandra.default.events
    WHERE
    app_id = 1
    AND dt IN ('2019-06-01', '2019-06-02', '2019-06-03', '2019-06-04')
    AND bucket IN (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)
    ;

    View Slide

  43. パーティションの組み合わせの例
    SELECT
    *
    FROM
    cassandra.default.events
    WHERE
    app_id = 1
    AND dt IN ('2019-06-01', '2019-06-02', '2019-06-03', '2019-06-04')
    AND bucket IN (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)
    ;
    1 ✕ 4 ✕ 16 = 64

    View Slide

  44. • Repro の Cassandra の使い⽅だとパーティションはほぼ必ず存在する
    • パーティションのサイズを⼩さくするために bucket 化している
    • パーティションの有無を確認してまで Planning するメリットがほぼない
    • Presto のリポジトリを fork してパーティションの存在チェックをスキップ
    • 改造して⾃前でビルドした presto-cassandra.jar を本番で使⽤
    Planning の⾼速化

    View Slide

  45. presto-cassandra の改造
    https://github.com/reproio/presto/pull/1

    View Slide

  46. presto-cassandra の改造
    https://github.com/reproio/presto/pull/1
    Planning time: 22829 msec → 1060 msec

    View Slide

  47. これからの話

    View Slide

  48. • Presto ⽤クラスタの master node で ReadOps が急激に増えて応答不能になる
    • ⻑時間起動している presto-server のパフォーマンスが著しく劣化する
    • まだ⼀部のデータが Hive (S3) に依存している
    • 定期バッチでしか利⽤しない Hive ⽤クラスタが無駄
    • Hive ⽤の EMR クラスタはバッチで利⽤する時だけ起動したい
    • Presto は EC2 で⾃前運⽤したい
    • coordinator のコールドスタンバイ
    • カスタム AMI の利⽤
    • 安全な auto scaling
    • 最新版の Presto の利⽤
    現在抱えている問題
    Hive
    Hive⽤兼ホットスタンバイクラスタ
    Presto
    Presto専⽤クラスタ

    View Slide

  49. 新しいミドルウェアの導⼊
    https://speakerdeck.com/joker1007/architecture-evolution-in-repro?slide=35

    View Slide

  50. • Twitter: @a_bicky
    • Blog: あらびき⽇記
    • 所属: Repro 株式会社 (2017 年 8 ⽉〜)
    • SRE っぽいことをしたり
    • 分析基盤っぽいことをしたり
    • 開発環境整備をしたり
    • Rails アプリケーション触ったり
    • CTO の⼤規模機能開発のレビューをしたり
    ⾃⼰紹介(再掲)

    View Slide

  51. • Twitter: @a_bicky
    • Blog: あらびき⽇記
    • 所属: Repro 株式会社 (2017 年 8 ⽉〜)
    • SRE っぽいことをしたり
    • 分析基盤っぽいことをしたり
    • 開発環境整備をしたり
    • Rails アプリケーション触ったり
    • CTO の⼤規模機能開発のレビューをしたり
    ⾃⼰紹介(再掲)

    View Slide

  52. • Twitter: @a_bicky
    • Blog: あらびき⽇記
    • 所属: Repro 株式会社 (2017 年 8 ⽉〜)
    • SRE っぽいことをしたり
    • 分析基盤っぽいことをしたり
    • 開発環境整備をしたり
    • Rails アプリケーション触ったり
    • CTO の⼤規模機能開発のレビューをしたり
    ⾃⼰紹介(再掲)

    View Slide

  53. • Twitter: @a_bicky
    • Blog: あらびき⽇記
    • 所属: Repro 株式会社 (2017 年 8 ⽉〜)
    • SRE っぽいことをしたり
    • 分析基盤っぽいことをしたり
    • 開発環境整備をしたり
    • Rails アプリケーション触ったり
    • CTO の⼤規模機能開発のレビューをしたり
    ⾃⼰紹介(再掲)
    ⼈が⾜りない!!

    View Slide

  54. まとめ

    View Slide

  55. • Repro では配信対象ユーザの算出などに Presto を利⽤している
    • Presto と YARN アプリケーションを共存させると OOM Killer に殺される
    • Presto で Hive の bucketed table を使う際はパフォーマンスに注意
    • hive.bucket_execution_enabled=false を指定することでパフォーマンスが改善するかも
    • presto-cassandra はパーティションが⼤量にあると Planning に時間がかかる
    • パーティションの存在有無のチェックをスキップすれば全体の処理時間が速くなるかも
    • Repro にはデータ基盤周りをガンガン改善していく⼈が⾜りない
    • いち早く Amazon Managed Streaming for Kafka を本番で試せるかも!
    まとめ

    View Slide

  56. おまけ

    View Slide

  57. Presto ⼊⾨に是⾮!
    基本的な概念からリモートデバッグ⽅法まで!

    View Slide

  58. Presto 本もうすぐ発売?
    http://shop.oreilly.com/product/0636920206880.do

    View Slide

  59. • クエリの統計情報は BigQuery に保存
    • presto-fluentd で fluentd に QueryStatistics の情報を post
    • fluentd から BigQuery のテーブルに load
    • analysisTime や cpuTime の⼤きなレコードの query を確認
    重い Presto SQL の⾒つけ⽅

    View Slide

  60. • Deduplication に異常に時間がかかる
    • presto-server が頻繁に応答しなくなる
    • Hive の bucketed table を使うと遅い
    • presto-cassandra connector の planning が遅い
    Repro が直⾯した様々な問題(番外編)

    View Slide

  61. Rails application
    fluentd-forwarder
    scheduled job
    Amazon Simple
    Storage Service (S3)
    fluentd-aggregator
    Hive
    Presto
    3. Hive で temporary table の内容を挿⼊(再掲)
    ⑥ HiveQL
    ⑦ Get LZO objects in the temp table
    ⑧ Put parquet objects

    View Slide

  62. • ユーザの属性情報などは 30 分に 1 回の定期ジョブで挿⼊
    • 更新ではなく追記なので同じユーザの同じ属性情報が複数存在
    • ユーザセグメンテーションでは最新の属性値が使われるよう Presto SQL を⼯夫
    • 挿⼊する度に S3 オブジェクトが増えてパフォーマンスが劣化
    Deduplication の必要性

    View Slide

  63. Deduplication の mpa task の実⾏時間

    View Slide

  64. Deduplication の mpa task の実⾏時間

    View Slide

  65. 1 map task に⼩さい S3 オブジェクトが集中
    The number of S3 objects
    task1 task2 task3 task4 task5 task6
    Total S3 bytes read
    task1 task2 task3 task4 task5 task6
    ※当時調べた時のイメージ

    View Slide

  66. 1. s3-dist-cp で S3 オブジェクトを HDFS に転送
    • 5 分⾜らずで転送可能
    2. HDFS 上のファイルに対して S3 と同じ形式でテーブルを作成
    • CREATE TABLE & MSCK REPAIR TABLE
    3. 作成したテーブルを⼊⼒に deduplication
    4. 作成したテーブルを削除
    S3 オブジェクトの取得にかかる時間を削減
    ※ 毎回の INSERT の時に hive.merge.tezfiles=true とするだけで良かったかも

    View Slide

  67. 改善後の mpa task の実⾏時間

    View Slide