55
All Right Reserved. Copyright.(C) Recruit Technologies Co.,Ltd. レコメンドバッチ高速化に向けた Spark/MapReduceの 機械学習ライブラリ比較検証 堀越 保徳(リクルートテクノロジーズ) 濱口 智大(NTTデータ) 2015年5月21日

Spark/MapReduceの 機械学習ライブラリ比較検証

Embed Size (px)

Citation preview

All Right Reserved. Copyright.(C) Recruit Technologies Co.,Ltd.

レコメンドバッチ高速化に向けた Spark/MapReduceの 機械学習ライブラリ比較検証

堀越 保徳(リクルートテクノロジーズ)

濱口 智大(NTTデータ)

2015年5月21日

All Right Reserved. Copyright.(C) Recruit Technologies Co.,Ltd.

目次

1

1. レコメンドバッチ高速化検証 • 背景と目的 • 検証内容 • 検証結果 • まとめ

2. Sparkノウハウ共有

• 検証を通じて実感したSparkのメリット • 重要なパラメータ • ハマりどころや注意点

All Right Reserved. Copyright.(C) Recruit Technologies Co.,Ltd.

1.レコメンドバッチ高速化検証

2

All Right Reserved. Copyright.(C) Recruit Technologies Co.,Ltd.

自己紹介

3

氏名: 堀越 保徳 Twitter: @hotoku Blog: http://d.hatena.ne.jp/hotoku/

All Right Reserved. Copyright.(C) Recruit Technologies Co.,Ltd.

目次

4

1. レコメンドバッチ高速化検証 • 背景と目的 • 検証内容 • 検証結果 • まとめ

All Right Reserved. Copyright.(C) Recruit Technologies Co.,Ltd.

背景と目的

5

背景 • これまでデータ分析処理基盤としてHadoop(Hive/Mahout)を活用してきた • 処理性能の課題に関してはスケールアウトで対応してきた

• レコメンドバッチの長時間化が深刻化

• バッチの多様化 レコメンドA、レコメンドB、モニタリングX、モニタリングY、…

• データ量増加 ○千万レコード/日、様々なデータ(PV、CV、各種事業マスタ、…)

• スケールアウト以外のアプローチを模索 • Mahoutがアルゴリズム開発の主軸をMapReduce→Sparkに変更

目的

• 次世代のデータ分析処理基盤としてSparkの実用可能性を探る • インフラ面での検証に先駆けて、アプリ面で実運用に耐えうる有用性を備え

ているか検証する

All Right Reserved. Copyright.(C) Recruit Technologies Co.,Ltd.

目次

6

1. レコメンドバッチ高速化検証 • 背景と目的 • 検証内容 • 検証結果 • まとめ

All Right Reserved. Copyright.(C) Recruit Technologies Co.,Ltd.

検証内容

7

概要 • Spark MLlib VS MapReduce Mahout レコメンドライブラリの比較

検証対象アルゴリズム

• アイテムベース協調フィルタリング • ALS協調フィルタリング

検証環境

• AWS上に2クラスタを構築

比較観点

• 実行時間(実時間) • レコメンド精度(F-尺度) • スケール性

All Right Reserved. Copyright.(C) Recruit Technologies Co.,Ltd.

対象アルゴリズム

8

アルゴリズムの位置づけ

Spark MLlib

アイテムベース ※MLlibに実装がないため新規作成

ALS

MapReduce Mahout

アイテムベース

ALS

処理基盤をSparkにすることで、 実行時間、レコメンド精度は どのように変化するか?

アルゴリズムの違いによって、MapReduce vs Sparkの結果は どのように変化するか?

処理基盤軸

アルゴリズム軸

※現行

All Right Reserved. Copyright.(C) Recruit Technologies Co.,Ltd.

対象アルゴリズム

9

アイテムベース協調フィルタリング: 繰り返し計算はない • 協調フィルタリング:「この商品を見た人は、こんな商品も見ています」 をアイテム間の類似度を基に計算するアルゴリズム

• ユーザの行動履歴からアイテム間の類似度を計算 • ユーザが高い評価を付けたアイテムに似ているアイテムを推薦

ベクトルの 類似度算出

評価値行列 アイテム類似度行列

ユーザ

アイテム アイテム

アイテム

予測値行列

ユーザ

アイテム アイテム

アイテム ユーザ

アイテム

×

レコメンド

ユーザ

アイテム

上位N件抽出

All Right Reserved. Copyright.(C) Recruit Technologies Co.,Ltd.

対象アルゴリズム

10

ALS協調フィルタリング: 繰り返し計算が多い • 協調フィルタリング:「この商品を見た人はこんな商品も見ています」 を行列因子分解によって求めるアルゴリズム

• 評価値行列をユーザ特徴量行列とアイテム特徴量行列に分解してモデル化 • ユーザ特徴行列×アイテム特徴行列で未評価のアイテムの評価値を予測

評価値行列 ユーザ特徴量行列

アイテム特徴量行列

ユーザ

アイテム

ユーザ

アイテム

)()(),(22

),(

2

),( j juji iuiIji j

T

iji ununvurVUf

●交互最小二乗法(ALS:Alternative Least Square) + WR:Weighted λ Regulation どちらかを固定してどちらかを最適化する それを目的関数が閾値以下となるまで繰り返す

All Right Reserved. Copyright.(C) Recruit Technologies Co.,Ltd.

検証環境

11

AWS構成 • Master × 2台、Slave × 10台 • コア数 4 • メモリ 32GB • ディスク 160GB

主要ソフトウェア • CentOS 6.5 • Java 1.7.0 • Hadoop 2.6.0 • Mahout 0.9 • Spark 1.2.0

使用データ • レコード数 1億3千万件 • ユーザ数 1000万件 • アイテム数 200万件 • サイズ 2GB

Master

Slave

Client EC2 x1

EC2 x2

EC2 x10

Master

Slave

Client EC2 x1

EC2 x2

EC2 X10

Spark用クラスタ MapReduce用クラスタ

レコード数 ユーザ数 アイテム数 データ密度 サイズ(MB)

1 35,872,326 4,765,166 512,882 0.0000147 510

2 61,192,747 6,659,384 865,736 0.0000106 873

3 77,865,758 7,694,202 1,097,982 0.0000092 1,113

4 97,967,251 8,797,225 1,334,746 0.0000083 1,400

5 116,938,309 9,734,990 1,563,344 0.0000077 1,677

6 134,976,806 10,489,833 1,830,912 0.0000070 1,943

All Right Reserved. Copyright.(C) Recruit Technologies Co.,Ltd.

比較観点

12

レコメンド精度(F-尺度) • Recommend : レコメンドされたユーザ×アイテム • Order : 購買されたユーザ×アイテム • Match : レコメンドされ、かつ、購買されたユーザ×アイテム

• 適合率(recall)

• 再現率(precision) • F-尺度(f-measure)

スケール性

• AWSのスレーブノード数を増加させ、実行時間が短縮されるか検証 • ノード数: 5、10、15、20で検証

commendR

Matchrecall

e

Order

Matchpresicion

recallprecision

recallpresicionmeasuref

・・2

Recommend Order

Match

U

All Right Reserved. Copyright.(C) Recruit Technologies Co.,Ltd.

目次

13

1. レコメンドバッチ高速化検証 • 背景と目的 • 検証内容 • 検証結果 • まとめ

All Right Reserved. Copyright.(C) Recruit Technologies Co.,Ltd.

検証結果(1)実行時間

14

Spark vs Mahout(アイテムベース)

⇒ Spark: Mahout の約1/5 に短縮

23分32秒

4分57秒

4.8倍

All Right Reserved. Copyright.(C) Recruit Technologies Co.,Ltd.

検証結果(1)実行時間

15

Spark vs Mahout(ALS)

⇒ Spark: Mahout の1/32 に短縮

6分55秒

3時間41分46秒

3分14秒

36分48秒

32.1倍

ALSは繰り返し計算が多いため、 Sparkの優位性が際立つ

All Right Reserved. Copyright.(C) Recruit Technologies Co.,Ltd.

検証結果(2)レコメンド精度

16

Spark vs Mahout ⇒ ほぼ同等のレコメンド精度を確認

All Right Reserved. Copyright.(C) Recruit Technologies Co.,Ltd.

検証結果(3)スケール性の確認

17

Spark vs Mahout ⇒ Spark/Mahoutともにノード増加に応じて実行時間が短縮

All Right Reserved. Copyright.(C) Recruit Technologies Co.,Ltd.

目次

18

1. レコメンドバッチ高速化検証 • 背景と目的 • 検証内容 • 検証結果 • まとめ

All Right Reserved. Copyright.(C) Recruit Technologies Co.,Ltd.

まとめ

19

実行時間比較(Spark/MapReduce) • アイテムベース : 1/5 • ALS : 1/32

⇒ Spark導入により実行時間の短縮が十分期待できる

レコメンド精度比較 • アイテムベース、ALSともにMapReduceとほぼ同等のレコメンド精度を確認 ⇒ 実用に耐えうる有用性

スケール性比較 • Sparkのスケール性がMapReduceと同等であることを確認 ⇒ データ量増加に対してリソースを増強することで対応可

次世代のレコメンド処理基盤としてSparkの有用性が確認できた

All Right Reserved. Copyright.(C) Recruit Technologies Co.,Ltd.

2.Sparkノウハウ共有

20

All Right Reserved. Copyright.(C) Recruit Technologies Co.,Ltd.

自己紹介

21

氏名: 濱口 智大 所属:

NTTデータ 第三法人事業本部

仕事: 入社してしばらくはレガシーシステムの維持管理 2013年からビッグデータ

今回の検証ではSparkでのアイテムベース実装を担当

All Right Reserved. Copyright.(C) Recruit Technologies Co.,Ltd.

目次

22

2. Sparkノウハウ共有 • 検証を通じて実感したSparkのメリット • 重要なパラメータ • ハマりどころや注意点

All Right Reserved. Copyright.(C) Recruit Technologies Co.,Ltd.

目次

23

2. Sparkノウハウ共有 • 検証を通じて実感したSparkのメリット • 重要なパラメータ • ハマりどころや注意点

All Right Reserved. Copyright.(C) Recruit Technologies Co.,Ltd.

検証を通じて実感したSparkのメリット

24

Ease of Use

Speed

All Right Reserved. Copyright.(C) Recruit Technologies Co.,Ltd.

一般的なプログラム

25

計算方法

CPU

メモリ

ストレージ

: 演算

: 変数

: ファイル

ファイルから変数にデータを読み込み、 あれこれ演算して

結果をファイルに書き出す

All Right Reserved. Copyright.(C) Recruit Technologies Co.,Ltd.

一般的なプログラム

26

WordCountの例

All Right Reserved. Copyright.(C) Recruit Technologies Co.,Ltd.

並列プログラム Hadoopのアプローチ

27

計算方法

CPU

メモリ

ストレージ

CPU

メモリ

ストレージ

CPU

メモリ

ストレージ

: MapReduce

: HDFS

HDFSからデータ読み込み、HDFSに書き出すまでの処理を Map + Reduceのフレームワークに当てはめる

All Right Reserved. Copyright.(C) Recruit Technologies Co.,Ltd.

並列プログラム Hadoopのアプローチ

28

WordCountの例

All Right Reserved. Copyright.(C) Recruit Technologies Co.,Ltd.

並列プログラム Sparkのアプローチ

29

計算方法

CPU

メモリ

ストレージ

CPU

メモリ

ストレージ

CPU

メモリ

ストレージ

: API

: HDFS

HDFSファイルからRDDの変数にデータを読み込み、 RDD用のAPIであれこれ演算して 結果をHDFSファイルに書き出す

: RDD

All Right Reserved. Copyright.(C) Recruit Technologies Co.,Ltd.

並列プログラム Sparkのアプローチ

30

WordCountの例

All Right Reserved. Copyright.(C) Recruit Technologies Co.,Ltd.

並列プログラム Sparkのアプローチ

31

WordCountの例

All Right Reserved. Copyright.(C) Recruit Technologies Co.,Ltd.

Spark-shell

32

インタラクティブなシェルで手軽に動作確認ができる まず、spark-shellでお試し → ある程度の処理の流れができたらアプリケーションにまとめる

All Right Reserved. Copyright.(C) Recruit Technologies Co.,Ltd.

Speedに関する検証結果

33

今回の検証結果: Spark > MapReduce となった • ALS(繰り返し処理が多い) ⇒ 約32倍 • アイテムベース(繰り返し処理がない) ⇒ 約5倍

All Right Reserved. Copyright.(C) Recruit Technologies Co.,Ltd.

Speed Spark > MapReduceの要因考察

34

観点 MapReduce Spark

処理フロー 必ずMap→Reduceのジョブとして作成するため非効率なケースも (無駄なMap/Reduceを挟む)

読み込んだデータをRDDに保持し、次々に処理を適用していくので効率的なフローが実現可

実行スケジューリング Map→Reduceのジョブを人間がスケジュールしてプログラムを書く (基本直列に並べる?)

SparkのDAG実行エンジンが最適化して実行 (ステージ分割、タスク生成、実行スケジューリング)

データアクセス 1ジョブ毎にHDFSに結果を書き出すため、中間データもHDFSに保持

中間データはRDDとしてメモリ(+ローカルディスク)に保持

処理起動のオーバヘッド 連続した処理の場合、1ジョブ毎に1アプリケーションとして実行するため、処理起動のオーバヘッドが発生

連続した全ての処理を1アプリケーションとして実行するため、処理起動のオーバヘッドが小さい

MapReduceとSparkの比較

All Right Reserved. Copyright.(C) Recruit Technologies Co.,Ltd.

目次

35

2. Sparkノウハウ共有 • 検証を通じて実感したSparkのメリット • 重要なパラメータ • ハマりどころや注意点

All Right Reserved. Copyright.(C) Recruit Technologies Co.,Ltd.

重要なパラメータ

36

メモリ関連のパラメータ

並列度関連のパラメータ

All Right Reserved. Copyright.(C) Recruit Technologies Co.,Ltd.

メモリ関連のパラメータ

37

重要パラメータ パラメータ 説明

spark.executor.memory Executorプロセスのヒープサイズ

spark.yarn.executor.memoryOverhead ExecutorプロセスのOFFヒープ

spark.storage.memoryFraction キャッシュ領域のヒープ全体に占める割合

spark.shuffle.memoryFraction シャッフル使用領域のヒープ全体に占める割合

spark.executor.extraJavaOptions –xmn 世代別GCにおけるNew領域のサイズ

ちゃんと設定しないと色んな問題が発生・・・

Container

Container

Executor

Executor

Executor memory(= heap) Executor memory overhead (=off heap)

storage shuffle

New領域 Old領域

Driver

All Right Reserved. Copyright.(C) Recruit Technologies Co.,Ltd.

問題1: Lost executor

38

問題 YARNコンテナで確保できるメモリサイズを超過し、YARNによってExecutorをkillされる

原因

spark.yarn.executor.memoryOverhead の不足によって発生 (spark.executor.memoryが足りなかった場合はOOMで落ちる) エラーメッセージが異なる場合があるので注意!

15/03/03 23:33:54 INFO yarn.YarnAllocationHandler: Completed container

container_1424912468099_0195_01_000009 (state: COMPLETE, exit status: -100)

15/03/03 23:33:54 INFO yarn.YarnAllocationHandler: Container marked as failed:

container_1424912468099_0195_01_000009. Exit status: -100. Diagnostics: Container released on a *lost* node

15/03/03 23:33:54 ERROR cluster.YarnClusterScheduler: Lost executor 5 on spaken410: remote Akka client

disassociated

15/02/25 22:04:54 WARN yarn.YarnAllocationHandler: Container killed by YARN for exceeding memory limits. 17.2

GB of 17.1 GB physical memory used. Consider boosting spark.yarn.executor.memoryOverhead.

15/02/25 22:04:55 ERROR cluster.YarnClusterScheduler: Lost executor 2 on spaken508: remote Akka client

disassociated

All Right Reserved. Copyright.(C) Recruit Technologies Co.,Ltd.

問題1: Lost executor

39

対処 spark.yarn.executor.memoryOverheadを増やす

設定方針

1. Executor実行のために確保する全体メモリサイズを決める

2. spark.executor.memory + spark.yarn.executor.memoryOverhead = 全体メモリサイズ(1.で決めたサイズ) となるように設定

3. Lost executorが発生する場合は、spark.yarn.executor.memoryOverheadを上げ、その分spark.executor.memoryを下げる

All Right Reserved. Copyright.(C) Recruit Technologies Co.,Ltd.

問題2: GC overhead limit exceeded

40

問題 GCが発生しすぎてアプリケーションが落ちる

原因

• そもそもメモリが不足 • メモリの使われ方がGCの仕組みにマッチしていない

考え方 • GCではオブジェクトの生存期間毎にNew/Oldに分けて管理している • Old領域がいっぱいになるとFull GCが走り時間がかかる

• Sparkのメモリの使い方として、キャッシュやシャッフルに使われる

領域のデータは生存期間が長い

All Right Reserved. Copyright.(C) Recruit Technologies Co.,Ltd.

設定方針 Old領域 ≧ キャッシュ領域 + シャッフル領域 つまり New領域 ≦ Executorメモリ全体 ー (キャッシュ領域 + シャッフル領域) spark.executor.extraJavaOptions –xmn ≦ spark.executor.memory × (1 ー (spark.storage.memoryFraction + spark.shuffle.memoryFraction)) となるように設定

それでもGCが頻発するなら、 • 並列度を上げて処理単位を小さくする ※parallelismに関しては後ほど詳しく

• spark.storage.memoryFraction, spark.shuffle.memoryFractionを下げる (メモリに乗らない分はディスクに退避)

問題2: GC overhead limit exceeded

41

All Right Reserved. Copyright.(C) Recruit Technologies Co.,Ltd.

並列度関連のパラメータ

42

重要パラメータ パラメータ 説明

spark.executor.instances(--num-executor) Executorプロセス数

spark.executor.cores(--executor-cores) 1Executor当たりのコア数(同時実行スレッド数)

spark.default.parallelism パーティション数(データの分割数)

チューニングが重要なパラメータ

Container

Container

Executor

Driver

core core core core

Executor プロセス数

Executor当たりのコア数

処理対象データ …

パーティション数

処理窓口数 =Executorプロセス数 × Executor当たりのコア数

総タスク数 =パーティション数

All Right Reserved. Copyright.(C) Recruit Technologies Co.,Ltd.

Parallelismのチューニング

処理のデータ、アルゴリズムによって最適なParallelismを求める • Parallelismが不十分な場合

Executorリソースに対して処理データ量が多い →GC、Shuffle spillにより処理時間が伸びる

• Parallelismが過剰な場合

1タスク当たりの処理時間が短縮されなくなる →タスク数増に比例して処理時間が伸びる

All Right Reserved. Copyright.(C) Recruit Technologies Co.,Ltd.

目次

44

2. Sparkノウハウ共有 • 検証を通じて実感したSparkのメリット • 重要なパラメータ • ハマりどころや注意点

All Right Reserved. Copyright.(C) Recruit Technologies Co.,Ltd.

ハマりどころや注意点

45

偏ったデータ

既存資産の流用 • Task not serializable • マルチスレッド問題

All Right Reserved. Copyright.(C) Recruit Technologies Co.,Ltd.

偏ったデータ

46

問題: 偏ったデータがボトルネックとなる key-value型の処理で特定のキーにデータが集中した場合、 処理の長時間化やOOMによるアプリ停止が発生

対策: 偏ったデータを間引く key-value型の分散処理に共通する課題 ※Spark固有の問題ではない アルゴリズムを変更する対処が必要 精度低下を許容できる範囲でデータを間引いて計算

Web UIでボトルネック発生を確認

All Right Reserved. Copyright.(C) Recruit Technologies Co.,Ltd.

偏ったデータ

47

アイテムベースで発生した問題の対応 SparkのWebUIからボトルネックが発生している箇所を特定 ・レコメンドスコア計算

ratings :1アイテム当たり最大100万超 similarities :1アイテム当たり最大50万超 ⇒ アイテムIDでjoinすると最大100万×50万=5000億レコードが 1つのキーに集中

⇒ 偏ったデータによるボトルネックが発生する

All Right Reserved. Copyright.(C) Recruit Technologies Co.,Ltd.

偏ったデータ

48

アイテムベースで発生した問題の対応 MapReduceもkey-value型なので同じ問題が発生するはず Mahoutではどのように対処しているのか?? Mahoutと同様のオプションを実装することで偏ったデータによる問題を回避

アルゴリズムに手を加えて、偏ったデータを間引いた計算に変更

オプション 意味

--maxPrefsPerUser レコメンド計算に使用するユーザ評価値の1ユーザあたりの評価済みアイテム数の最大値を制限

--maxSimilaritiesPerItem レコメンド計算に使用するアイテム類似度の1アイテムあたりの類似アイテム数の最大値を制限

--maxPrefsInItemSimilarity アイテム類似度計算に使用するユーザ評価値の1ユーザあたりの評価済みアイテム数の最大値を制限

All Right Reserved. Copyright.(C) Recruit Technologies Co.,Ltd.

既存資産の流用

49

問題1: Task not serializable RDDとして保持する対象となるクラスや、RDDの演算時に使用するクラスがSerializableを実装していない場合に発生

※既存のコードをSparkに移植する際にハマりやすいポイント 対策

1. 対象クラスにSerializableを実装する 2. Kryo Serializationを利用する

All Right Reserved. Copyright.(C) Recruit Technologies Co.,Ltd.

既存資産の流用

50

Kryo Serializationを利用する方法 1. org.apache.spark.serializer.KryoRegistratorを継承したクラスを定義 2. SparkContext生成時にSparkConfに1.で作成したクラスを設定する

import com.esotericsoftware.kryo.Kryo import org.apache.spark.serializer.KryoRegistrator

class MyRegistrator extends KryoRegistrator { override def registerClasses(kryo: Kryo) { kryo.register(classOf[MyClass]) } } val conf = new SparkConf() conf.set("spark.serializer", "org.apache.spark.serializer.KryoSerializer") conf.set("spark.kryo.registrator", "MyRegistrator") val sc = new SparkContext(conf)

All Right Reserved. Copyright.(C) Recruit Technologies Co.,Ltd.

既存資産の流用

51

問題2: マルチスレッド問題 SparkのExecutorはマルチスレッドでタスクを処理するため、各タスク内の処理をスレッドセーフにする必要がある 既存のコードがスレッドセーフでない場合、Sparkに移植すると問題が発生 タイミングの問題のため、毎回同じ例外が発生する訳ではなく、解析が難しい ※今回の検証ではFastByIDMapというクラスを使用した処理で以下の例外が発生 ・ArrayIndexOutOfBoundsException ・NullPointerException

対策

1. スレッドセーフでないクラスをスレッドセーフなクラスに置き換える 2. Executorがマルチスレッドで動作しないような設定にする

All Right Reserved. Copyright.(C) Recruit Technologies Co.,Ltd.

既存資産の流用

52

Executorがマルチスレッドで動作しないような設定 考え方

1. Executor数を使用可能なコア数と同数にする 2. Executor当たりのコア数を1にする

例: Workerノード数が10、各ノードのコア数が4コアの場合 → 使用可能なコア数: 40コア ※ただし、基本的にはマルチスレッドの方が処理効率がいいので 問題がなければマルチスレッドを推奨

マルチスレッド設定 非マルチスレッド設定

Executor数 spark.executor.instances (--num-executors)

10 40

Executor当たりのコア数 spark.executor.cores (--executor-cores)

4 1

All Right Reserved. Copyright.(C) Recruit Technologies Co.,Ltd.

まとめ

53

Sparkのメリット • 直感的なプログラミング • 処理速度

重要なパラメータ

• メモリ関連パラメータ • 並列度関連パラメータ

ハマりどころや注意点

• 偏ったデータに注意 • 既存資産の流用時に注意

All Right Reserved. Copyright.(C) Recruit Technologies Co.,Ltd. 54