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

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

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

B38b75d449a3b6bc60aaf7a0c44674cf?s=128

Takeshi Arabiki

June 04, 2019
Tweet

Transcript

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

    Arabiki (@a_bicky)
  2. • Twitter: @a_bicky • Blog: あらびき⽇記 • 所属: Repro 株式会社

    (2017 年 8 ⽉〜) • SRE っぽいことをしたり • 分析基盤っぽいことをしたり • 開発環境整備をしたり • Rails アプリケーション触ったり • CTO の⼤規模機能開発のレビューをしたり ⾃⼰紹介
  3. None
  4. アナリティクス(分析) 80+ million sessions / day 700+ million events /

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

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

  7. 配信対象設定

  8. • 分散 SQL クエリエンジン • Presto ⾃体はデータストレージとしての機能を持たない • リクエストを受け付けて Planning

    などを⾏う coordinator • データを処理する worker • 様々なデータソースを同時に扱える • Hive (Hadoop File System), MySQL, Cassandra etc. • 基本的にオンメモリで処理する • メモリに収まらないデータは処理できない Presto の概要
  9. • 配信対象条件(ユーザセグメンテーション)から SQL を機械的に⽣成 • 個々の SQL を最適化することが難しい • プッシュ通知の配信直前に対象を計算

    • ⻑時間かかる SQL が発⾏されると予定の配信時間に間に合わない • ⻑時間 Presto が落ちるとお客様やアプリのエンドユーザに多⼤な迷惑がかかる • アプリによってデータの規模も特性も異なる • 特定のアプリだけ問題になることもしばしば Presto を使った配信対象ユーザの決定
  10. Rails application fluentd-forwarder scheduled job Amazon Simple Storage Service (S3)

    fluentd-aggregator Hive Presto Presto 導⼊当初の構成
  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)
  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
  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
  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.
  15. Repro が直⾯した様々な問題

  16. • presto-server が頻繁に応答しなくなる • Hive の bucketed table を使うと遅い •

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

    presto-cassandra connector の planning が遅い Repro が直⾯した様々な問題(抜粋)
  18. • Presto は 1 worker 応答しなくなるだけでクエリ全体が失敗する • com.facebook.presto.spi.PrestoException: Could not

    communicate with the remote task. • 全 worker がほぼ毎⽇死んで⼤量のアラートが届く presto-server が頻繁に応答しなくなる
  19. ある EMR インスタンスのログ [hadoop@ip-172-31-82-52 ~]$ 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)
  20. [hadoop@ip-172-31-82-52 ~]$ 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^ ̄ あるインスタンスのログ
  21. • システム全体のメモリ: 60 GB • presto-server の RSS: 42 GB

    • yarn ユーザプロセスの合計 RSS: 15 GB OMM Killer 発動時の状況 Hive Presto
  22. • Presto と YARN アプリケーションの共存を避ける • EMR は Presto と

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

    クラスタを分けた後の構成 Rails application fluentd-forwarder scheduled job
  24. • presto-server が頻繁に応答しなくなる • Hive の bucketed table を使うと遅い •

    presto-cassandra connector の planning が遅い Repro が直⾯した様々な問題(抜粋)
  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
  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
  27. Bucketed table だと特定の worker にデータが集中

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

  29. • 同じテーブルの同じ bucket 番号のファイルは全部同じ worker が処理する • テーブル設計を上⼿くやらないと特定の worker にデータが集中する

    • hive.bucket_execution_enabled=false を指定することで無効化できる Presto における bucketed table の扱い
  30. hive.bucket_execution_enabled=false の効果 Elapsed time: 36.72m → 5.67m

  31. • presto-server が頻繁に応答しなくなる • Hive の bucketed table を使うと遅い •

    presto-cassandra connector の planning が遅い Repro が直⾯した様々な問題(抜粋)
  32. Cassandra の導⼊ http://joker1007.hatenablog.com/entry/2018/06/29/201400

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

  34. Cassandra 導⼊後の構成 Amazon Simple Storage Service (S3) Rails application fluentd-forwarder

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

    Hive Hive⽤兼ホットスタンバイクラスタ Presto Presto専⽤クラスタ fluentd-aggregator 1. セッションデータを Cassandra に Insert ① Insert data
  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
  37. 遅い Planning { "elapsed_time": "80620", "execution_time": "6833", "distributed_planning_time": "9", "analysis_time":

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

    "73698" } 74 秒!!!!
  39. • Presto の coordinator はパーティションの情報を使って planning する • Cassandra はパーティションの有無について情報を保持していない

    • Hive の場合は Hive metastore に保持している Presto の Planning
  40. presto-cassandra によるパーティション情報取得 https://github.com/prestodb/presto/blob/0.203/presto-cassandra/src/main/java/com/facebook/presto/cassandra/NativeCassandraSession.java#L418-L420

  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 を発⾏

  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) ;
  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
  44. • Repro の Cassandra の使い⽅だとパーティションはほぼ必ず存在する • パーティションのサイズを⼩さくするために bucket 化している •

    パーティションの有無を確認してまで Planning するメリットがほぼない • Presto のリポジトリを fork してパーティションの存在チェックをスキップ • 改造して⾃前でビルドした presto-cassandra.jar を本番で使⽤ Planning の⾼速化
  45. presto-cassandra の改造 https://github.com/reproio/presto/pull/1

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

  47. これからの話

  48. • Presto ⽤クラスタの master node で ReadOps が急激に増えて応答不能になる • ⻑時間起動している

    presto-server のパフォーマンスが著しく劣化する • まだ⼀部のデータが Hive (S3) に依存している • 定期バッチでしか利⽤しない Hive ⽤クラスタが無駄 • Hive ⽤の EMR クラスタはバッチで利⽤する時だけ起動したい • Presto は EC2 で⾃前運⽤したい • coordinator のコールドスタンバイ • カスタム AMI の利⽤ • 安全な auto scaling • 最新版の Presto の利⽤ 現在抱えている問題 Hive Hive⽤兼ホットスタンバイクラスタ Presto Presto専⽤クラスタ
  49. 新しいミドルウェアの導⼊ https://speakerdeck.com/joker1007/architecture-evolution-in-repro?slide=35

  50. • Twitter: @a_bicky • Blog: あらびき⽇記 • 所属: Repro 株式会社

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

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

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

    (2017 年 8 ⽉〜) • SRE っぽいことをしたり • 分析基盤っぽいことをしたり • 開発環境整備をしたり • Rails アプリケーション触ったり • CTO の⼤規模機能開発のレビューをしたり ⾃⼰紹介(再掲) ⼈が⾜りない!!
  54. まとめ

  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 を本番で試せるかも! まとめ
  56. おまけ

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

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

  59. • クエリの統計情報は BigQuery に保存 • presto-fluentd で fluentd に QueryStatistics

    の情報を post • fluentd から BigQuery のテーブルに load • analysisTime や cpuTime の⼤きなレコードの query を確認 重い Presto SQL の⾒つけ⽅
  60. • Deduplication に異常に時間がかかる • presto-server が頻繁に応答しなくなる • Hive の bucketed

    table を使うと遅い • presto-cassandra connector の planning が遅い Repro が直⾯した様々な問題(番外編)
  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
  62. • ユーザの属性情報などは 30 分に 1 回の定期ジョブで挿⼊ • 更新ではなく追記なので同じユーザの同じ属性情報が複数存在 • ユーザセグメンテーションでは最新の属性値が使われるよう

    Presto SQL を⼯夫 • 挿⼊する度に S3 オブジェクトが増えてパフォーマンスが劣化 Deduplication の必要性
  63. Deduplication の mpa task の実⾏時間

  64. Deduplication の mpa task の実⾏時間

  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 ※当時調べた時のイメージ
  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 とするだけで良かったかも
  67. 改善後の mpa task の実⾏時間