Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

Repro における Presto の活⽤箇所

Slide 7

Slide 7 text

配信対象設定

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

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)

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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.

Slide 15

Slide 15 text

Repro が直⾯した様々な問題

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

ある 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)

Slide 20

Slide 20 text

[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^ ̄ あるインスタンスのログ

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

パーティションの組み合わせの例 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) ;

Slide 43

Slide 43 text

パーティションの組み合わせの例 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

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

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

Slide 47

Slide 47 text

これからの話

Slide 48

Slide 48 text

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

Slide 49

Slide 49 text

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

Slide 50

Slide 50 text

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

Slide 51

Slide 51 text

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

Slide 52

Slide 52 text

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

Slide 53

Slide 53 text

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

Slide 54

Slide 54 text

まとめ

Slide 55

Slide 55 text

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

Slide 56

Slide 56 text

おまけ

Slide 57

Slide 57 text

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

Slide 58

Slide 58 text

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

Slide 59

Slide 59 text

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

Slide 60

Slide 60 text

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

Slide 61

Slide 61 text

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

Slide 62

Slide 62 text

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

Slide 63

Slide 63 text

Deduplication の mpa task の実⾏時間

Slide 64

Slide 64 text

Deduplication の mpa task の実⾏時間

Slide 65

Slide 65 text

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 ※当時調べた時のイメージ

Slide 66

Slide 66 text

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

Slide 67

Slide 67 text

改善後の mpa task の実⾏時間