SlideShare a Scribd company logo
1 of 39
Download to read offline
石崎 一明
日本アイ・ビー・エム(株)東京基礎研究所
@kiszk
DataFrameとDatasetの内部をのぞいてみる
1
About Me – Kazuaki Ishizaki
▪ IBM Research – Tokyoで研究員をしています
https://ibm.biz/ishizaki
– コンパイラ最適化、言語処理系実装、並列処理、が専門
▪ 1996年より、IBM Java(今はOpen J9)の実装にかかわる
– 特に、PowerPC用の実行時コンパイラの実装リード
▪ 2018年9月より、Apache Sparkコミッタ(SQLモジュール)
– 現在、Apache Sparkコミッタは日本に4人
▪ 2018年よりACM Distinguished Member
▪ SNS
– @kiszk
– Slideshare: https://www.slideshare.net/ishizaki
2 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki
今日のお話
▪ DataFrameとDatasetでできることの違い
▪ DataFrameとDatasetで同じ処理を行ったときの、性能差は?
▪ DataFrameとDatasetは、内部をのぞいて見るとどのように違うか?
▪ Spark 2.xでどんな性能改善がされてきたか?
▪ まだ残されている性能改善の余地は?
3 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki
こんなことを知って役に立つのか?
▪ アプリケーションプログラマにとって
– 高速に処理可能なMLパイプラインを書く助けになる
▪ 機械学習(ML)ライブラリ開発者にとって
– RDDの代わりに、Datasetを使いたくなる かもしれない
– Issueを投げたくなる
▪ SQLモジュールのコントリビュータにとって
– プルリクを投げる余地があることが分かる
4 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki
DataFrame、Dataset、(とおまけでRDD)
5 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki
SQLDataFrame (DF) Dataset (DS)
RDD
ラムダ式を使って処理を記述
コンパイル時に変数の型が分かる
SQLのオペレータで処理を記述
df = (1 to 100).toDF.cache
df.selectExpr(“value + 1”)
ds = (1 to 100).toDS.cache
ds.map(value => value + 1)
rdd = sc.parallelize(
(1 to 100)).cache
rdd.map(value => value + 1)
DataFrameもDatasetもできること
▪ 単純な演算
▪ 合計などの集合演算
6 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki
DataFrame (DF) Dataset (DS)
df = (1 to 100).toDF
df.agg(sum(“value”))
ds = (1 to 100).toDS
ds.reduce(_ + _)
ds = (1 to 100).toDS
ds.map(value => value + 1)
df = (1 to 100).toDF
df.selectExpr(“value + 1”)
DataFrameができなくてDatasetができること
▪ ループの記述
7 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki
DataFrame (DF) Dataset (DS)
ds = (1 to 100).toDS
ds.map(value => {
int a = 1;
for (int i = 1; i <= value; i++) {
a *= i;
}
return a;
})
ループが無いと、機械学習のアルゴリズムが書けない…
DF, DS, RDDはSpark内部でどう処理されているのか?
– 書いたプログラムが直接実行されるのではなく、生成されたJavaコードが実
行される
8 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki
From Structuring Apache Spark 2.0: SQL, DataFrames, Datasets And Streaming - by Michael Armbrust
DS
DF
Catalyst 最適化器
// generated Java code
// for DF and DS
while (itr.hasNext()) {
Row r = (Row)itr.next();
int v = r.getInt(0);
…
}
DF, DS, RDDはSpark内部でどう処理されているのか?
– 書いたプログラムが直接実行されるのではなく、生成されたJavaコードが実
行される
– DFとDSを使ったプログラムは同じ最適化パスを通るので、
同様に最適化され、同じコードが生成され、同じ性能が出るはず?9 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki
From Structuring Apache Spark 2.0: SQL, DataFrames, Datasets And Streaming - by Michael Armbrust
DS
DF
Catalyst 最適化器
// generated Java code
// for DF and DS
while (itr.hasNext()) {
Row r = (Row)itr.next();
int v = r.getInt(0);
…
}
単純な処理のDatasetプログラムでも遅い @Spark 2.0
▪ スカラ整数変数への足し算が、DataFrameに比べて1.7倍遅い
10 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki
0 0.5 1 1.5 2
DataFrameの実行時間に対する相対値
DataFrame Dataset
All experiments are done using
16-core Intel E2667-v3 3.2GHz, with 384GB mem, Ubuntu 16.04,
OpenJDK 1.8.0u212-b13 with 256GB heap, Spark master=local[1]
Spark branch-2.0 and branch-2.2, ds/df/rdd are cached
左のほうが高速
ds.map(value => value + 1)
df.selectExpr(“value + 1”)
配列のDatasetプログラムではもっと遅い @Spark 2.0
▪ 整数配列の生成が、DataFrameに比べて54倍遅い
11 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki
左のほうが高速
0 10 20 30 40 50 60
DataFrameの実行時間に対する相対値
DataFrame Dataset
SPARK-16070参照
ds = Seq(Array(…), Array(…), …)
.toDS.cache
ds.map(a => Array(a(0)))
df = Seq(Array(…), Array(…), …)
.toDF(“a”).cache
df.selectExpr(“Array(a[0])”)
Spark 2.2では、これらのプログラムを高速化しました
▪ スカラ整数変数への足し算は、1.6倍速く
▪ 整数配列の生成は、4.5倍速く
12 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki
どうやって?
Catalystとコード生成を改良しました
ds.map(value => value + 1)
ds = Seq(Array(…), Array(…), …)
.toDS.cache
ds.map(a => Array(a(0)))
このあとの話の流れ
▪ DataFrameとDatasetの紹介と現状
▪ 先程の2つの例を深掘り
– なぜDatasetは遅いのか?
– Spark 2.2ではどのように改善したか?
▪ 別の例を深掘り
– なぜDatasetは遅いのか?
– 将来のSparkで改善する余地はどこにあるのか?
▪ DatasetはSpark MLパイプラインでどのように使われているか?
▪ 終わりに
13 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki
DataFrameでのスカラ整数を扱うプログラム
▪ 全てSparkが生成したコードを実行する
▪ int型の足し算を実行する、きれいなJavaコードが生成される
– DataframeがSpark内でvalueがint型であることを知っている
– Project Tungstenで高速化のために導入した列の独自データ構造表現から、整
数を読み出し、intを使ったJavaコードを生成する
14
while (itr.hasNext()) { // execute a row
// get a value from a row in DF
int value =((Row)itr.next()).getInt(0);
// compute a new value
int mapValue = value + 1;
// store a new value to a row in DF
outRow.write(0, mapValue);
append(outRow);
}
// df: DataFrame for int …
df.selectExpr(“value + 1”)
コード
生成
DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki
Catalystで
Javaコードを
生成
列の独自データ構造(Row)
row.getInt(0)
outRow.write(0, …)
Datasetでのスカラ整数を扱うプログラム@Spark 2.0
▪ ラムダ式はScalacのコードを、それ以外はSparkが生成したコードを実行
▪ 4つのデータ型変換(intとIntegerオブジェクト)を含む、複雑なJavaコー
ドが生成される
– Scalaのラムダ式の標準インタフェース apply(Object) を使うため、Integerオブ
ジェクトを使う必要がある
15
コード
生成
DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki
Catalystで
Javaコードを
生成
// ds: Dataset[Int] …
ds.map(value => value + 1)
while (itr.hasNext()) {
int value = ((Row)itr.next()).getInt(0);
Object objValue = new Integer(value);
int mapValue = ((Integer)
mapFunc.apply(objVal)).toValue();
outRow.write(0, mapValue);
append(outRow);
}
Object apply(Object obj) {
int value = Integer(obj).toValue();
return new Integer(apply$II(value));
}
int apply$II(int value) { return value + 1; }
Scalacがラムダ式から
生成したコード
Spark 2.2でどのように改善したか?
▪ DataFrameと同様に、 int型の足し算を実行する、きれいなJavaコードを
生成する(SPARK-19008)
– Scalacが apply$II(int) というコードを出すことを知って、Sparkが生成した
コードからをObjectを使わず、apply$II(int)を直呼びするコードを生成する
16
コード
生成
DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki
Catalystで
Javaコードを
生成
// ds: Dataset[Int] …
ds.map(value => value + 1)
while (itr.hasNext()) {
int value = ((Row)itr.next()).getInt(0);
int mapValue = mapFunc.apply$II(value);
outRow.write(0, mapValue);
append(outRow);
}
int apply$II(int value) { return value + 1; }
Scalacがラムダ式から
生成したコード
Spark 2.2では、この場合はもう遅くない!
▪ Spark 2.0に比べて、1.6倍高速化された
– DataFrameとの差は、わずか9%
17 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki
0 0.5 1 1.5 2
DataFrameの実行時間に対する相対値
DataFrame Dataset
左側のほうが高速
1.6xds.map(value => value + 1)
df.selectExpr(“value + 1”)
RDDとも比べてみると @ Spark 2.2
▪ 性能差は、大きく縮まった
18 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki
0 0.5 1 1.5 2
DataFrameの実行時間に対する相対値
RDD DataFrame Dataset
9%
5%
左側のほうが高速
ds.map(value => value + 1)
df.selectExpr(“value + 1”)
df.map(value => value + 1)
生成されたJavaコードを見るには
▪ .debugCode()をつける
– DataFrame
– Dataset @ Spark 2.0
19 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki
scala> import org.apache.spark.sql.execution.debug._
scala> spark.range(1, 100).selectExpr("id + 1").debugCodegen
...
/* 099 */ boolean project_isNull = false;
/* 100 */
/* 101 */ long project_value = -1L;
/* 102 */ project_value = range_value + 1L;
/* 103 */ project_rowWriter.write(0, project_value);
/* 104 */ append(project_result);
/* 105 */
...
scala> import org.apache.spark.sql.execution.debug._
scala> spark.range(1, 100).map(value => value + 1).debugCodegen
...
/* 100 */
/* 101 */ boolean mapelements_isNull = false || deserializetoobject_isNull;
/* 102 */ final long mapelements_value = mapelements_isNull ?
-1L : (Long) mapelements_value1.apply(deserializetoobject_value);
/* 103 */
...
ここで見てるのは
ほんの一部です
生成されたJavaコードを見るのがしんどい人は
▪ .explain() をつけて、Catalystが最適化した結果の実行プランを見ると雰
囲気がわかる
– DataFrame
– Dataset @ Spark 2.0
– Dataset @ Spark 2.2
20 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki
scala> (1 to 100).toDF.selectExpr("value + 1").explain
== Physical Plan ==
LocalTableScan [(value + 1)#14]
scala> (1 to 100).toDS.map(value => value + 1).explain
== Physical Plan ==
*SerializeFromObject [input[0, int, false] AS value#24]
+- *MapElements <function1>, obj#23: int
+- *DeserializeToObject value#19: int, obj#22: int
+- LocalTableScan [value#19]
scala> (1 to 100).toDS.map(value => value + 1).explain
== Physical Plan ==
*SerializeFromObject [input[0, int, true] AS value#14]
+- *MapElements <function1>, obj#13: int
+- *DeserializeToObject value#9: int, obj#12: int
+- LocalTableScan [value#9]
このあとの話の流れ
▪ DataFrameとDatasetの紹介と現状
▪ 先程の2つの例を深掘り
– なぜDatasetは遅いのか?
– Spark 2.2ではどのように改善したか?
▪ 別の例を深掘り
– なぜDatasetは遅いのか?
– 将来のSparkで改善する余地はどこにあるのか?
▪ DatasetはSpark MLパイプラインでどのように使われているか?
▪ 終わりに
21 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki
DataFrameでの整数配列を扱うプログラム
▪ Project Tungstenで高速化のために導入した、配列用の独自データ構造を
通して、配列操作を行う
22 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki
ArrayData inArray, outArray;
while (itr.hasNext()) {
inArray = ((Row)itr.next()).getArray(0);
int value = inArray.getInt(0)); //a[0]
outArray = new UnsafeArrayData(); ...
outArray.setInt(0, value); //Array(a[0])
outArray.writeToMemory(outRow);
append(outRow);
}
配列の独自データ構造(ArrayData)
inArray.getInt(0)
outArray.setInt(0, …)
// df: DataFrame for Array(Int) …
df.selectExpr(“Array(a[0])”)
Catalystで
Javaコードを
生成
コード
生成
Datasetでの整数配列を扱うプログラム
▪ ラムダ式用のJavaバイトコードでは、Project Tungstenの独自データ構造
を操作できないため、Javaオブジェクトとの間でserialization/
deserialzation (Ser/De)が必要になる
23 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki
ArrayData inArray, outArray;
while (itr.hasNext()) {
inArray = ((Row)itr.next()).getArray(0);
append(outRow);
}
配列の独自データ構造(ArrayData)
// ds: DataSet[Array(Int)] …
ds.map(a => Array(a(0)))
Catalystで
Javaコードを
生成
コード
生成
Ser/De
int[] mapArray = Array(a(0));
Ser/De
Javaオブジェクト
ラムダ式用の
Javaバイトコード Deserialization
Serialization
Ser/Deをさらに深掘りすると…
▪ 遅い操作がてんこ盛り
– Integer オブジェクトとintの間の
データ変換
– 配列要素単位のコピー
24 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki
// ds: DataSet[Array(Int)] …
ds.map(a => Array(a(0)))
Catalystで
Javaコードを
生成
コード
生成
ArrayData inArray, outArray;
while (itr.hasNext()) {
inArray = ((Row)itr.next().getArray(0);
append(outRow);
}
データ変換
配列要素単位のコピー
配列要素単位のコピー
データ変換
配列要素単位のコピー Null checkを伴うデータコピー
int[] mapArray = Array(a(0));
データ変換
配列要素単位のコピー
Ser
De
Javaオブジェクトの作成 or 参照を伴う変換
Spark 2.2でどのように改善したか?
▪ 遅いSer/Deを、速いarraycopyで置き換えたコードを生成する
(SPARK-15985、SPARK-17490、SPARK-15962)
25 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki
// ds: DataSet[Array(Int)] …
ds.map(a => Array(a(0)))
Catalystで
Javaコードを
生成
コード
生成
ArrayData inArray, outArray;
while (itr.hasNext()) {
inArray = ((Row)itr.next().getArray(0);
append(outRow);
}
int[] mapArray = Array(a(0));
arraycopy()を使う配列全体のコピー
配列全体のコピー
配列全体のコピー
配列全体のコピー
Spark 2.2では、超極端には遅くない!
▪ でも、まだ12倍遅いです…
26 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki
0 10 20 30 40 50 60
DataFrameの実行時間に対する相対値
DataFrame Dataset
4.5x
12x
左側のほうが高速
ds = Seq(Array(…), Array(…), …)
.toDS.cache
ds.map(a => Array(a(0)))
df = Seq(Array(…), Array(…), …)
.toDF(“a”).cache
df.selectExpr(“Array(a[0])”)
map()メソッドで、計算時間がかかる
処理をしたら、無視できる …といいな
RDDとも比べてみると
▪ DataFrame版は、RDD版より速い
27 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki
ds = Seq(Array(…), Array(…), …)
.toDS.cache
ds.map(a => Array(a(0)))
df = Seq(Array(…), Array(…), …)
.toDF(“a”).cache
df.selectExpr(“Array(a[0])”)
0 5 10 15
DataFrameの実行時間に対する相対値
RDD DataFrame Dataset
1.2
12
左側のほうが高速
rdd = sc.parallelize(Seq(
Array(…), Array(…), …)).cache
rdd.map(a => Array(a(0)))
実行プランを見てみると
▪ DataFrame
▪ DataSet @ Spark 2.0
▪ Dataset @ Spark 2.2
28 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki
scala> sc.parallelize(Seq(Array(1)), 1).toDF.selectExpr("Array(value[0])").explain
== Physical Plan ==
*Project [array(value#39[0]) AS array(value[0])#47]
+- *SerializeFromObject [staticinvoke(class org.apache.spark.sql.catalyst.expressions.UnsafeArrayData,
ArrayType(IntegerType,false), fromPrimitiveArray, input[0, [I, true], true) AS value#39]
+- Scan ExternalRDDScan[obj#38]
scala> sc.parallelize(Seq(Array(1)), 1).toDS.map(a => Array(a(0))).explain
== Physical Plan ==
*SerializeFromObject [newInstance(class org.apache.spark.sql.catalyst.util.GenericArrayData) AS value#11]
+- *MapElements <function1>, obj#10: [I
+- *DeserializeToObject cast(value#6 as array<int>).toIntArray, obj#9: [I
+- Scan ExistingRDD[value#6]
scala> sc.parallelize(Seq(Array(1)), 1).toDS.map(a => Array(a(0))).explain
== Physical Plan ==
*SerializeFromObject [staticinvoke(class org.apache.spark.sql.catalyst.expressions.UnsafeArrayData,
ArrayType(IntegerType,false), fromPrimitiveArray, input[0, [I, true], true) AS value#34]
+- *MapElements <function1>, obj#33: [I
+- Scan ExternalRDDScan[obj#28]
ラムダ式が、独自データ構造を操作できないなら
▪ ラムダ式がProject Tungsten用の独自データ構造を操作できるように、ラ
ムダ式を書き換えてしまえばよい
▪ プロトタイプを作ってみたところ、 Ser/Deを無くすことができて大きく
性能が改善された
29 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki
while (itr.hasNext()) {
inArray = ((Row)itr.next().getArray(0);
outArray = mapFunc.applyTungsten(inArray);
outArray.writeToMemory(outRow);
append(outRow);
}
// ds: DataSet[Array(Int)] …
ds.map(a => Array(a(0)))
Catalystで
Javaコードを
生成
コード
生成
“Accelerating Spark Datasets by inlining deserialization”, IPDPS2017という学会で発表済
配列の独自データ構造
1
1
apply(Object)
1011
applyTungsten
(ArrayData)
バイトコード
変換
a.getInt(0)
a.setInt(0, …)
このあとの話の流れ
▪ DataFrameとDatasetの紹介と現状
▪ 先程の2つの例を深掘り
– なぜDatasetは遅いのか?
– Spark 2.2ではどのように改善したか?
▪ 別の例を深掘り
– なぜDatasetは遅いのか?
– 将来のSparkで改善する余地はどこにあるのか?
▪ DatasetはSpark MLパイプラインでどのように使われているか?
▪ 終わりに
30 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki
単純処理が続くDatasetプログラムも遅い @Spark 2.2
▪ スカラ整数変数への足し算を2回続けて実行すると、DataFrameに比べ
て1.1倍遅い
31 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki
左のほうが高速
ds.map(value => value + 1)
.map(value => value + 2)
df.selectExpr(“value + 1”)
.selectExpr(“value + 2”)
rdd.map(value => value + 1)
.map(value => value + 2)
0 0.5 1 1.5
DataFrameの実行時間に対する相対値
RDD DataFrame Dataset
DataFrameでは、2つの足し算が1つになる
▪ Catalyst最適化器が、selectExpr()の中の式を足し算である、と理解し
て2つの足し算をコード生成前に計算して、value+3、に変換する
32 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki
while (itr.hasNext()) {
Row row = (Row)itr.next();
int value = row.getInt(0);
int mapValue = value + 3;
projectRow.write(0, mapValue);
append(projectRow);
}
df.selectExpr(“value + 1”)
.selectExpr(“value + 2”)
Catalystで
Javaコードを
生成
コード
生成
Datasetでは、足し算のメソッド呼び出しが残ったまま
▪ Catalyst最適化器は、メソッド呼び出しの先にあるscalacが生成したJava
バイトコードが、整数の足し算である、と理解できないので、そのまま
残る
33 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki
while (itr.hasNext()) {
int value = ((Row)itr.next()).getInt(0);
int mapValue = mapFunc1.apply$II(value);
mapValue += mapFunc2.apply$II(mapValue);
outRow.write(0, mapValue);
append(outRow);
}
// ds: Dataset[Int] …
ds.map(value => value + 1)
.map(value => value + 2)
Catalystで
Javaコードを
生成
コード
生成
class MapFunc1 {
int apply$II(int value) { return value + 1;}}
class MapFunc2 {
int apply$II(int value) { return value + 2;}}
Scalacがラムダ式から
生成したコード
CatalystがJavaバイトコードを理解できないのなら…
▪ 理解できるように改善すればいい(SPARK-14083)
– 残念ながら、2年近く塩漬けのプルリクとなってる
– 個人的には、このプルリクは前に進めたい
34 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki
while (itr.hasNext()) {
int value = ((Row)itr.next()).getInt(0);
int mapValue = value + 3;
outRow.write(0, mapValue);
append(outRow);
}
// ds: Dataset[Int] …
ds.map(value => value + 1)
.map(value => value + 2)
Catalystで
Javaコードを
生成
コード
生成
class MapFunc1 {
int apply$II(int value) { return value + 1;}}
class MapFunc2 {
int apply$II(int value) { return value + 2;}}
Scalacがラムダ式から
生成したコード
このあとの話の流れ
▪ DataFrameとDatasetの紹介と現状
▪ 先程の2つの例を深掘り
– なぜDatasetは遅いのか?
– Spark 2.2ではどのように改善したか?
▪ 別の例を深掘り
– なぜDatasetは遅いのか?
– 将来のSparkで改善する余地はどこにあるのか?
▪ DatasetはSpark MLパイプラインでどのように使われているか?
▪ 終わりに
35 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki
DatasetはSpark ML pipelineの中でどう使われている?
▪ ML Pipelineを構築するために、Datasetは使われている
▪ 個々のMLアルゴリズムを見ると、実は内部ではRDDに変換して処理を
行っている
– 主に記述力(ループ、その他)の問題?
– RDDとDatasetの変換は実行時オーバヘッドを発生する
36 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki
val trainingDS: Dataset = ...
val tokenizer = new Tokenizer()
val hashingTF = new HashingTF()
val lr = new LogisticRegression()
val pipeline = new Pipeline().setStages(
Array(tokenizer, hashingTF, lr))
val model = pipeline.fit(trainingDS)
def fit(ds: Dataset[_]) = {
...
train(ds)
}
def train(ds:Dataset[_]):LogisticRegressionModel = {
val instances: RDD[Instance] =
ds.select(...).rdd.map { // convert DS to RDD
case Row(...) => ...
}
instances.persist(...)
instances.treeAggregate(...)
}
ML pipeline Machine learning algorithm (LogisticRegression)
もし、DatasetをMLアルゴリズムの記述に使ったら
▪ ML Pipelineを構築するために、Datasetを使う
▪ MLアルゴリズムもDataset上のデータに対して処理を行う
– データ変換オーバヘッドが無くなる
– Catalystによる最適化が適用される(もしSPARK-14083がマージされたら)
37 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki
val trainingDataset: Dataset = ...
val tokenizer = new Tokenizer()
val hashingTF = new HashingTF()
val lr = new LogisticRegression()
val pipeline = new Pipeline().setStages(
Array(tokenizer, hashingTF, lr))
val model = pipeline.fit(trainingDataset)
def train(ds:Dataset[_]):LogisticRegressionModel = {
val instances: Dataset[Instance] =
ds.select(...).rdd.map {
case Row(...) => ...
}
instances.persist(...)
instances.treeAggregate(...)
}
ML pipeline
Machine learning algorithm (LogisticRegression)
終わりに
▪ Datasetは、Spark 2.2以降でかなり速くなった
▪ Datasetの性能改善の源泉
– 無駄なデータ変換をへらす
– Serialization/Deserializationをなくす
– (ToDo)Catalystにおけるラムダ式の扱いの改善
▪ Datasetは、ニワトリと卵、状態に陥ってしまっている
– 性能が出ないから使わない
– 使わないから、性能が出なくてもissueが上がらない
▪ ぜひ、Datasetを使ってください
– そしてissueを投げて声をあげてみてください
– できればプルリクも ☺
38 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki
Sparkコミュニティに飛び込もう!
by Apache Spark コミッタ 猿田さん
https://www.slideshare.net/hadoopxnttdata/apache-spark-commnity-nttdata-sarutak
Thank you
▪ @sameeragarwal, @hvanhovell, @gatorsmile, @cloud-fan, @ueshin,
@davies, @rxin, @joshrosen, @maropu, @viirya
▪ IBM CODAIT
39 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki

More Related Content

What's hot

Scalar IST のご紹介
Scalar IST のご紹介 Scalar IST のご紹介
Scalar IST のご紹介 Scalar, Inc.
 
分析指向データレイク実現の次の一手 ~Delta Lake、なにそれおいしいの?~(NTTデータ テクノロジーカンファレンス 2020 発表資料)
分析指向データレイク実現の次の一手 ~Delta Lake、なにそれおいしいの?~(NTTデータ テクノロジーカンファレンス 2020 発表資料)分析指向データレイク実現の次の一手 ~Delta Lake、なにそれおいしいの?~(NTTデータ テクノロジーカンファレンス 2020 発表資料)
分析指向データレイク実現の次の一手 ~Delta Lake、なにそれおいしいの?~(NTTデータ テクノロジーカンファレンス 2020 発表資料)NTT DATA Technology & Innovation
 
AngularとSpring Bootで作るSPA + RESTful Web Serviceアプリケーション
AngularとSpring Bootで作るSPA + RESTful Web ServiceアプリケーションAngularとSpring Bootで作るSPA + RESTful Web Serviceアプリケーション
AngularとSpring Bootで作るSPA + RESTful Web Serviceアプリケーションssuser070fa9
 
【旧版】Oracle Gen 2 Exadata Cloud@Customer:サービス概要のご紹介 [2021年12月版]
【旧版】Oracle Gen 2 Exadata Cloud@Customer:サービス概要のご紹介 [2021年12月版]【旧版】Oracle Gen 2 Exadata Cloud@Customer:サービス概要のご紹介 [2021年12月版]
【旧版】Oracle Gen 2 Exadata Cloud@Customer:サービス概要のご紹介 [2021年12月版]オラクルエンジニア通信
 
Data platformdesign
Data platformdesignData platformdesign
Data platformdesignRyoma Nagata
 
Scalar DB: Universal Transaction Manager
Scalar DB: Universal Transaction ManagerScalar DB: Universal Transaction Manager
Scalar DB: Universal Transaction ManagerScalar, Inc.
 
それでも環境依存は残っている~起きたり起きなかったりする問題のお話~
それでも環境依存は残っている~起きたり起きなかったりする問題のお話~それでも環境依存は残っている~起きたり起きなかったりする問題のお話~
それでも環境依存は残っている~起きたり起きなかったりする問題のお話~Hiroki Tateno
 
[Oracle DBA & Developer Day 2014] しばちょう先生による特別講義! RMANの運用と高速化チューニング
[Oracle DBA & Developer Day 2014] しばちょう先生による特別講義! RMANの運用と高速化チューニング[Oracle DBA & Developer Day 2014] しばちょう先生による特別講義! RMANの運用と高速化チューニング
[Oracle DBA & Developer Day 2014] しばちょう先生による特別講義! RMANの運用と高速化チューニングオラクルエンジニア通信
 
AWSで作る分析基盤
AWSで作る分析基盤AWSで作る分析基盤
AWSで作る分析基盤Yu Otsubo
 
【旧版】Oracle Database Cloud Service:サービス概要のご紹介 [2021年7月版]
【旧版】Oracle Database Cloud Service:サービス概要のご紹介 [2021年7月版]【旧版】Oracle Database Cloud Service:サービス概要のご紹介 [2021年7月版]
【旧版】Oracle Database Cloud Service:サービス概要のご紹介 [2021年7月版]オラクルエンジニア通信
 
大量のデータ処理や分析に使えるOSS Apache Sparkのご紹介(Open Source Conference 2020 Online/Kyoto ...
大量のデータ処理や分析に使えるOSS Apache Sparkのご紹介(Open Source Conference 2020 Online/Kyoto ...大量のデータ処理や分析に使えるOSS Apache Sparkのご紹介(Open Source Conference 2020 Online/Kyoto ...
大量のデータ処理や分析に使えるOSS Apache Sparkのご紹介(Open Source Conference 2020 Online/Kyoto ...NTT DATA Technology & Innovation
 
TECHTALK 20210218 Qlikデータ統合製品によるSAPデータのリアルタイムDWHの実現
TECHTALK 20210218 Qlikデータ統合製品によるSAPデータのリアルタイムDWHの実現TECHTALK 20210218 Qlikデータ統合製品によるSAPデータのリアルタイムDWHの実現
TECHTALK 20210218 Qlikデータ統合製品によるSAPデータのリアルタイムDWHの実現QlikPresalesJapan
 
Oracle運用Tips大放出! ~ RAC環境のRMANのパラレル化を極める 編 ~ @2016-02-23 JPOUG
Oracle運用Tips大放出! ~ RAC環境のRMANのパラレル化を極める 編 ~ @2016-02-23 JPOUG Oracle運用Tips大放出! ~ RAC環境のRMANのパラレル化を極める 編 ~ @2016-02-23 JPOUG
Oracle運用Tips大放出! ~ RAC環境のRMANのパラレル化を極める 編 ~ @2016-02-23 JPOUG Yuya Ohta
 
SQL Server 使いのための Azure Synapse Analytics - Spark 入門
SQL Server 使いのための Azure Synapse Analytics - Spark 入門SQL Server 使いのための Azure Synapse Analytics - Spark 入門
SQL Server 使いのための Azure Synapse Analytics - Spark 入門Daiyu Hatakeyama
 
[Oracle DBA & Developer Day 2012] 高可用性システムに適した管理性と性能を向上させるASM と RMAN の魅力
[Oracle DBA & Developer Day 2012] 高可用性システムに適した管理性と性能を向上させるASM と RMAN の魅力[Oracle DBA & Developer Day 2012] 高可用性システムに適した管理性と性能を向上させるASM と RMAN の魅力
[Oracle DBA & Developer Day 2012] 高可用性システムに適した管理性と性能を向上させるASM と RMAN の魅力オラクルエンジニア通信
 
統計情報のリセットによるautovacuumへの影響について(第39回PostgreSQLアンカンファレンス@オンライン 発表資料)
統計情報のリセットによるautovacuumへの影響について(第39回PostgreSQLアンカンファレンス@オンライン 発表資料)統計情報のリセットによるautovacuumへの影響について(第39回PostgreSQLアンカンファレンス@オンライン 発表資料)
統計情報のリセットによるautovacuumへの影響について(第39回PostgreSQLアンカンファレンス@オンライン 発表資料)NTT DATA Technology & Innovation
 

What's hot (20)

Scalar IST のご紹介
Scalar IST のご紹介 Scalar IST のご紹介
Scalar IST のご紹介
 
Oracle GoldenGate入門
Oracle GoldenGate入門Oracle GoldenGate入門
Oracle GoldenGate入門
 
分析指向データレイク実現の次の一手 ~Delta Lake、なにそれおいしいの?~(NTTデータ テクノロジーカンファレンス 2020 発表資料)
分析指向データレイク実現の次の一手 ~Delta Lake、なにそれおいしいの?~(NTTデータ テクノロジーカンファレンス 2020 発表資料)分析指向データレイク実現の次の一手 ~Delta Lake、なにそれおいしいの?~(NTTデータ テクノロジーカンファレンス 2020 発表資料)
分析指向データレイク実現の次の一手 ~Delta Lake、なにそれおいしいの?~(NTTデータ テクノロジーカンファレンス 2020 発表資料)
 
AngularとSpring Bootで作るSPA + RESTful Web Serviceアプリケーション
AngularとSpring Bootで作るSPA + RESTful Web ServiceアプリケーションAngularとSpring Bootで作るSPA + RESTful Web Serviceアプリケーション
AngularとSpring Bootで作るSPA + RESTful Web Serviceアプリケーション
 
【旧版】Oracle Gen 2 Exadata Cloud@Customer:サービス概要のご紹介 [2021年12月版]
【旧版】Oracle Gen 2 Exadata Cloud@Customer:サービス概要のご紹介 [2021年12月版]【旧版】Oracle Gen 2 Exadata Cloud@Customer:サービス概要のご紹介 [2021年12月版]
【旧版】Oracle Gen 2 Exadata Cloud@Customer:サービス概要のご紹介 [2021年12月版]
 
Data platformdesign
Data platformdesignData platformdesign
Data platformdesign
 
Oracle GoldenGate Veridata概要
Oracle GoldenGate Veridata概要Oracle GoldenGate Veridata概要
Oracle GoldenGate Veridata概要
 
Scalar DB: Universal Transaction Manager
Scalar DB: Universal Transaction ManagerScalar DB: Universal Transaction Manager
Scalar DB: Universal Transaction Manager
 
それでも環境依存は残っている~起きたり起きなかったりする問題のお話~
それでも環境依存は残っている~起きたり起きなかったりする問題のお話~それでも環境依存は残っている~起きたり起きなかったりする問題のお話~
それでも環境依存は残っている~起きたり起きなかったりする問題のお話~
 
[Oracle DBA & Developer Day 2014] しばちょう先生による特別講義! RMANの運用と高速化チューニング
[Oracle DBA & Developer Day 2014] しばちょう先生による特別講義! RMANの運用と高速化チューニング[Oracle DBA & Developer Day 2014] しばちょう先生による特別講義! RMANの運用と高速化チューニング
[Oracle DBA & Developer Day 2014] しばちょう先生による特別講義! RMANの運用と高速化チューニング
 
AWSで作る分析基盤
AWSで作る分析基盤AWSで作る分析基盤
AWSで作る分析基盤
 
【旧版】Oracle Database Cloud Service:サービス概要のご紹介 [2021年7月版]
【旧版】Oracle Database Cloud Service:サービス概要のご紹介 [2021年7月版]【旧版】Oracle Database Cloud Service:サービス概要のご紹介 [2021年7月版]
【旧版】Oracle Database Cloud Service:サービス概要のご紹介 [2021年7月版]
 
大量のデータ処理や分析に使えるOSS Apache Sparkのご紹介(Open Source Conference 2020 Online/Kyoto ...
大量のデータ処理や分析に使えるOSS Apache Sparkのご紹介(Open Source Conference 2020 Online/Kyoto ...大量のデータ処理や分析に使えるOSS Apache Sparkのご紹介(Open Source Conference 2020 Online/Kyoto ...
大量のデータ処理や分析に使えるOSS Apache Sparkのご紹介(Open Source Conference 2020 Online/Kyoto ...
 
TECHTALK 20210218 Qlikデータ統合製品によるSAPデータのリアルタイムDWHの実現
TECHTALK 20210218 Qlikデータ統合製品によるSAPデータのリアルタイムDWHの実現TECHTALK 20210218 Qlikデータ統合製品によるSAPデータのリアルタイムDWHの実現
TECHTALK 20210218 Qlikデータ統合製品によるSAPデータのリアルタイムDWHの実現
 
Oracle運用Tips大放出! ~ RAC環境のRMANのパラレル化を極める 編 ~ @2016-02-23 JPOUG
Oracle運用Tips大放出! ~ RAC環境のRMANのパラレル化を極める 編 ~ @2016-02-23 JPOUG Oracle運用Tips大放出! ~ RAC環境のRMANのパラレル化を極める 編 ~ @2016-02-23 JPOUG
Oracle運用Tips大放出! ~ RAC環境のRMANのパラレル化を極める 編 ~ @2016-02-23 JPOUG
 
SQL Server 使いのための Azure Synapse Analytics - Spark 入門
SQL Server 使いのための Azure Synapse Analytics - Spark 入門SQL Server 使いのための Azure Synapse Analytics - Spark 入門
SQL Server 使いのための Azure Synapse Analytics - Spark 入門
 
Helidon 概要
Helidon 概要Helidon 概要
Helidon 概要
 
[Oracle DBA & Developer Day 2012] 高可用性システムに適した管理性と性能を向上させるASM と RMAN の魅力
[Oracle DBA & Developer Day 2012] 高可用性システムに適した管理性と性能を向上させるASM と RMAN の魅力[Oracle DBA & Developer Day 2012] 高可用性システムに適した管理性と性能を向上させるASM と RMAN の魅力
[Oracle DBA & Developer Day 2012] 高可用性システムに適した管理性と性能を向上させるASM と RMAN の魅力
 
統計情報のリセットによるautovacuumへの影響について(第39回PostgreSQLアンカンファレンス@オンライン 発表資料)
統計情報のリセットによるautovacuumへの影響について(第39回PostgreSQLアンカンファレンス@オンライン 発表資料)統計情報のリセットによるautovacuumへの影響について(第39回PostgreSQLアンカンファレンス@オンライン 発表資料)
統計情報のリセットによるautovacuumへの影響について(第39回PostgreSQLアンカンファレンス@オンライン 発表資料)
 
Oracle Database Applianceのご紹介(詳細)
Oracle Database Applianceのご紹介(詳細)Oracle Database Applianceのご紹介(詳細)
Oracle Database Applianceのご紹介(詳細)
 

Similar to hscj2019_ishizaki_public

Sparkのクエリ処理系と周辺の話題
Sparkのクエリ処理系と周辺の話題Sparkのクエリ処理系と周辺の話題
Sparkのクエリ処理系と周辺の話題Takeshi Yamamuro
 
Introduction new features in Spark 3.0
Introduction new features in Spark 3.0Introduction new features in Spark 3.0
Introduction new features in Spark 3.0Kazuaki Ishizaki
 
Node.js勉強会 Framework Koa
Node.js勉強会 Framework KoaNode.js勉強会 Framework Koa
Node.js勉強会 Framework Koakamiyam .
 
Apache Torqueについて
Apache TorqueについてApache Torqueについて
Apache Torqueについてtako pons
 
Taming Distributed/Parallel Query Execution Engine of Apache Spark
Taming Distributed/Parallel Query Execution Engine of Apache SparkTaming Distributed/Parallel Query Execution Engine of Apache Spark
Taming Distributed/Parallel Query Execution Engine of Apache SparkTakeshi Yamamuro
 
React Native GUIDE
React Native GUIDEReact Native GUIDE
React Native GUIDEdcubeio
 
StackStormを活用した運用自動化の実践
StackStormを活用した運用自動化の実践StackStormを活用した運用自動化の実践
StackStormを活用した運用自動化の実践Shu Sugimoto
 
言語アップデート -Scala編-
言語アップデート -Scala編-言語アップデート -Scala編-
言語アップデート -Scala編-Kota Mizushima
 
Hadoop基盤上のETL構築実践例 ~多様なデータをどう扱う?~
Hadoop基盤上のETL構築実践例 ~多様なデータをどう扱う?~Hadoop基盤上のETL構築実践例 ~多様なデータをどう扱う?~
Hadoop基盤上のETL構築実践例 ~多様なデータをどう扱う?~Sotaro Kimura
 
G-Tech2015 Hadoop/Sparkを中核としたビッグデータ基盤_20151006
G-Tech2015 Hadoop/Sparkを中核としたビッグデータ基盤_20151006G-Tech2015 Hadoop/Sparkを中核としたビッグデータ基盤_20151006
G-Tech2015 Hadoop/Sparkを中核としたビッグデータ基盤_20151006Cloudera Japan
 
JavaScript.Next
JavaScript.NextJavaScript.Next
JavaScript.Nextdynamis
 
Asakusa FrameworkとScalaの密かな関係
Asakusa FrameworkとScalaの密かな関係Asakusa FrameworkとScalaの密かな関係
Asakusa FrameworkとScalaの密かな関係hishidama
 
Oracle Cloud Developers Meetup@東京
Oracle Cloud Developers Meetup@東京Oracle Cloud Developers Meetup@東京
Oracle Cloud Developers Meetup@東京tuchimur
 
Hive on Spark を活用した高速データ分析 - Hadoop / Spark Conference Japan 2016
Hive on Spark を活用した高速データ分析 - Hadoop / Spark Conference Japan 2016Hive on Spark を活用した高速データ分析 - Hadoop / Spark Conference Japan 2016
Hive on Spark を活用した高速データ分析 - Hadoop / Spark Conference Japan 2016Nagato Kasaki
 

Similar to hscj2019_ishizaki_public (20)

Sparkのクエリ処理系と周辺の話題
Sparkのクエリ処理系と周辺の話題Sparkのクエリ処理系と周辺の話題
Sparkのクエリ処理系と周辺の話題
 
Introduction new features in Spark 3.0
Introduction new features in Spark 3.0Introduction new features in Spark 3.0
Introduction new features in Spark 3.0
 
PostgreSQL 12の話
PostgreSQL 12の話PostgreSQL 12の話
PostgreSQL 12の話
 
Node.js勉強会 Framework Koa
Node.js勉強会 Framework KoaNode.js勉強会 Framework Koa
Node.js勉強会 Framework Koa
 
Apache Torqueについて
Apache TorqueについてApache Torqueについて
Apache Torqueについて
 
Gorinphp0729
Gorinphp0729Gorinphp0729
Gorinphp0729
 
Gorinphp0729
Gorinphp0729Gorinphp0729
Gorinphp0729
 
Taming Distributed/Parallel Query Execution Engine of Apache Spark
Taming Distributed/Parallel Query Execution Engine of Apache SparkTaming Distributed/Parallel Query Execution Engine of Apache Spark
Taming Distributed/Parallel Query Execution Engine of Apache Spark
 
React Native GUIDE
React Native GUIDEReact Native GUIDE
React Native GUIDE
 
ScalaCL in ScalaKaigi
ScalaCL in ScalaKaigiScalaCL in ScalaKaigi
ScalaCL in ScalaKaigi
 
StackStormを活用した運用自動化の実践
StackStormを活用した運用自動化の実践StackStormを活用した運用自動化の実践
StackStormを活用した運用自動化の実践
 
scala-kaigi1-sbt
scala-kaigi1-sbtscala-kaigi1-sbt
scala-kaigi1-sbt
 
言語アップデート -Scala編-
言語アップデート -Scala編-言語アップデート -Scala編-
言語アップデート -Scala編-
 
Hadoop基盤上のETL構築実践例 ~多様なデータをどう扱う?~
Hadoop基盤上のETL構築実践例 ~多様なデータをどう扱う?~Hadoop基盤上のETL構築実践例 ~多様なデータをどう扱う?~
Hadoop基盤上のETL構築実践例 ~多様なデータをどう扱う?~
 
G-Tech2015 Hadoop/Sparkを中核としたビッグデータ基盤_20151006
G-Tech2015 Hadoop/Sparkを中核としたビッグデータ基盤_20151006G-Tech2015 Hadoop/Sparkを中核としたビッグデータ基盤_20151006
G-Tech2015 Hadoop/Sparkを中核としたビッグデータ基盤_20151006
 
Altanative macro
Altanative macroAltanative macro
Altanative macro
 
JavaScript.Next
JavaScript.NextJavaScript.Next
JavaScript.Next
 
Asakusa FrameworkとScalaの密かな関係
Asakusa FrameworkとScalaの密かな関係Asakusa FrameworkとScalaの密かな関係
Asakusa FrameworkとScalaの密かな関係
 
Oracle Cloud Developers Meetup@東京
Oracle Cloud Developers Meetup@東京Oracle Cloud Developers Meetup@東京
Oracle Cloud Developers Meetup@東京
 
Hive on Spark を活用した高速データ分析 - Hadoop / Spark Conference Japan 2016
Hive on Spark を活用した高速データ分析 - Hadoop / Spark Conference Japan 2016Hive on Spark を活用した高速データ分析 - Hadoop / Spark Conference Japan 2016
Hive on Spark を活用した高速データ分析 - Hadoop / Spark Conference Japan 2016
 

More from Kazuaki Ishizaki

20230105_TITECH_lecture_ishizaki_public.pdf
20230105_TITECH_lecture_ishizaki_public.pdf20230105_TITECH_lecture_ishizaki_public.pdf
20230105_TITECH_lecture_ishizaki_public.pdfKazuaki Ishizaki
 
20221226_TITECH_lecture_ishizaki_public.pdf
20221226_TITECH_lecture_ishizaki_public.pdf20221226_TITECH_lecture_ishizaki_public.pdf
20221226_TITECH_lecture_ishizaki_public.pdfKazuaki Ishizaki
 
Make AI ecosystem more interoperable
Make AI ecosystem more interoperableMake AI ecosystem more interoperable
Make AI ecosystem more interoperableKazuaki Ishizaki
 
Enabling Vectorized Engine in Apache Spark
Enabling Vectorized Engine in Apache SparkEnabling Vectorized Engine in Apache Spark
Enabling Vectorized Engine in Apache SparkKazuaki Ishizaki
 
SQL Performance Improvements At a Glance in Apache Spark 3.0
SQL Performance Improvements At a Glance in Apache Spark 3.0SQL Performance Improvements At a Glance in Apache Spark 3.0
SQL Performance Improvements At a Glance in Apache Spark 3.0Kazuaki Ishizaki
 
In-Memory Evolution in Apache Spark
In-Memory Evolution in Apache SparkIn-Memory Evolution in Apache Spark
In-Memory Evolution in Apache SparkKazuaki Ishizaki
 
Looking back at Spark 2.x and forward to 3.0
Looking back at Spark 2.x and forward to 3.0Looking back at Spark 2.x and forward to 3.0
Looking back at Spark 2.x and forward to 3.0Kazuaki Ishizaki
 
20180109 titech lecture_ishizaki_public
20180109 titech lecture_ishizaki_public20180109 titech lecture_ishizaki_public
20180109 titech lecture_ishizaki_publicKazuaki Ishizaki
 
20171212 titech lecture_ishizaki_public
20171212 titech lecture_ishizaki_public20171212 titech lecture_ishizaki_public
20171212 titech lecture_ishizaki_publicKazuaki Ishizaki
 
Demystifying DataFrame and Dataset
Demystifying DataFrame and DatasetDemystifying DataFrame and Dataset
Demystifying DataFrame and DatasetKazuaki Ishizaki
 
Transparent GPU Exploitation for Java
Transparent GPU Exploitation for JavaTransparent GPU Exploitation for Java
Transparent GPU Exploitation for JavaKazuaki Ishizaki
 
Making Hardware Accelerator Easier to Use
Making Hardware Accelerator Easier to UseMaking Hardware Accelerator Easier to Use
Making Hardware Accelerator Easier to UseKazuaki Ishizaki
 
20160906 pplss ishizaki public
20160906 pplss ishizaki public20160906 pplss ishizaki public
20160906 pplss ishizaki publicKazuaki Ishizaki
 
Easy and High Performance GPU Programming for Java Programmers
Easy and High Performance GPU Programming for Java ProgrammersEasy and High Performance GPU Programming for Java Programmers
Easy and High Performance GPU Programming for Java ProgrammersKazuaki Ishizaki
 
20151112 kutech lecture_ishizaki_public
20151112 kutech lecture_ishizaki_public20151112 kutech lecture_ishizaki_public
20151112 kutech lecture_ishizaki_publicKazuaki Ishizaki
 

More from Kazuaki Ishizaki (20)

20230105_TITECH_lecture_ishizaki_public.pdf
20230105_TITECH_lecture_ishizaki_public.pdf20230105_TITECH_lecture_ishizaki_public.pdf
20230105_TITECH_lecture_ishizaki_public.pdf
 
20221226_TITECH_lecture_ishizaki_public.pdf
20221226_TITECH_lecture_ishizaki_public.pdf20221226_TITECH_lecture_ishizaki_public.pdf
20221226_TITECH_lecture_ishizaki_public.pdf
 
Make AI ecosystem more interoperable
Make AI ecosystem more interoperableMake AI ecosystem more interoperable
Make AI ecosystem more interoperable
 
Enabling Vectorized Engine in Apache Spark
Enabling Vectorized Engine in Apache SparkEnabling Vectorized Engine in Apache Spark
Enabling Vectorized Engine in Apache Spark
 
SQL Performance Improvements At a Glance in Apache Spark 3.0
SQL Performance Improvements At a Glance in Apache Spark 3.0SQL Performance Improvements At a Glance in Apache Spark 3.0
SQL Performance Improvements At a Glance in Apache Spark 3.0
 
SparkTokyo2019NovIshizaki
SparkTokyo2019NovIshizakiSparkTokyo2019NovIshizaki
SparkTokyo2019NovIshizaki
 
SparkTokyo2019
SparkTokyo2019SparkTokyo2019
SparkTokyo2019
 
In-Memory Evolution in Apache Spark
In-Memory Evolution in Apache SparkIn-Memory Evolution in Apache Spark
In-Memory Evolution in Apache Spark
 
icpe2019_ishizaki_public
icpe2019_ishizaki_publicicpe2019_ishizaki_public
icpe2019_ishizaki_public
 
Looking back at Spark 2.x and forward to 3.0
Looking back at Spark 2.x and forward to 3.0Looking back at Spark 2.x and forward to 3.0
Looking back at Spark 2.x and forward to 3.0
 
20180109 titech lecture_ishizaki_public
20180109 titech lecture_ishizaki_public20180109 titech lecture_ishizaki_public
20180109 titech lecture_ishizaki_public
 
20171212 titech lecture_ishizaki_public
20171212 titech lecture_ishizaki_public20171212 titech lecture_ishizaki_public
20171212 titech lecture_ishizaki_public
 
Demystifying DataFrame and Dataset
Demystifying DataFrame and DatasetDemystifying DataFrame and Dataset
Demystifying DataFrame and Dataset
 
Transparent GPU Exploitation for Java
Transparent GPU Exploitation for JavaTransparent GPU Exploitation for Java
Transparent GPU Exploitation for Java
 
Making Hardware Accelerator Easier to Use
Making Hardware Accelerator Easier to UseMaking Hardware Accelerator Easier to Use
Making Hardware Accelerator Easier to Use
 
20160906 pplss ishizaki public
20160906 pplss ishizaki public20160906 pplss ishizaki public
20160906 pplss ishizaki public
 
Exploiting GPUs in Spark
Exploiting GPUs in SparkExploiting GPUs in Spark
Exploiting GPUs in Spark
 
Easy and High Performance GPU Programming for Java Programmers
Easy and High Performance GPU Programming for Java ProgrammersEasy and High Performance GPU Programming for Java Programmers
Easy and High Performance GPU Programming for Java Programmers
 
Exploiting GPUs in Spark
Exploiting GPUs in SparkExploiting GPUs in Spark
Exploiting GPUs in Spark
 
20151112 kutech lecture_ishizaki_public
20151112 kutech lecture_ishizaki_public20151112 kutech lecture_ishizaki_public
20151112 kutech lecture_ishizaki_public
 

hscj2019_ishizaki_public

  • 2. About Me – Kazuaki Ishizaki ▪ IBM Research – Tokyoで研究員をしています https://ibm.biz/ishizaki – コンパイラ最適化、言語処理系実装、並列処理、が専門 ▪ 1996年より、IBM Java(今はOpen J9)の実装にかかわる – 特に、PowerPC用の実行時コンパイラの実装リード ▪ 2018年9月より、Apache Sparkコミッタ(SQLモジュール) – 現在、Apache Sparkコミッタは日本に4人 ▪ 2018年よりACM Distinguished Member ▪ SNS – @kiszk – Slideshare: https://www.slideshare.net/ishizaki 2 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki
  • 3. 今日のお話 ▪ DataFrameとDatasetでできることの違い ▪ DataFrameとDatasetで同じ処理を行ったときの、性能差は? ▪ DataFrameとDatasetは、内部をのぞいて見るとどのように違うか? ▪ Spark 2.xでどんな性能改善がされてきたか? ▪ まだ残されている性能改善の余地は? 3 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki
  • 4. こんなことを知って役に立つのか? ▪ アプリケーションプログラマにとって – 高速に処理可能なMLパイプラインを書く助けになる ▪ 機械学習(ML)ライブラリ開発者にとって – RDDの代わりに、Datasetを使いたくなる かもしれない – Issueを投げたくなる ▪ SQLモジュールのコントリビュータにとって – プルリクを投げる余地があることが分かる 4 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki
  • 5. DataFrame、Dataset、(とおまけでRDD) 5 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki SQLDataFrame (DF) Dataset (DS) RDD ラムダ式を使って処理を記述 コンパイル時に変数の型が分かる SQLのオペレータで処理を記述 df = (1 to 100).toDF.cache df.selectExpr(“value + 1”) ds = (1 to 100).toDS.cache ds.map(value => value + 1) rdd = sc.parallelize( (1 to 100)).cache rdd.map(value => value + 1)
  • 6. DataFrameもDatasetもできること ▪ 単純な演算 ▪ 合計などの集合演算 6 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki DataFrame (DF) Dataset (DS) df = (1 to 100).toDF df.agg(sum(“value”)) ds = (1 to 100).toDS ds.reduce(_ + _) ds = (1 to 100).toDS ds.map(value => value + 1) df = (1 to 100).toDF df.selectExpr(“value + 1”)
  • 7. DataFrameができなくてDatasetができること ▪ ループの記述 7 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki DataFrame (DF) Dataset (DS) ds = (1 to 100).toDS ds.map(value => { int a = 1; for (int i = 1; i <= value; i++) { a *= i; } return a; }) ループが無いと、機械学習のアルゴリズムが書けない…
  • 8. DF, DS, RDDはSpark内部でどう処理されているのか? – 書いたプログラムが直接実行されるのではなく、生成されたJavaコードが実 行される 8 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki From Structuring Apache Spark 2.0: SQL, DataFrames, Datasets And Streaming - by Michael Armbrust DS DF Catalyst 最適化器 // generated Java code // for DF and DS while (itr.hasNext()) { Row r = (Row)itr.next(); int v = r.getInt(0); … }
  • 9. DF, DS, RDDはSpark内部でどう処理されているのか? – 書いたプログラムが直接実行されるのではなく、生成されたJavaコードが実 行される – DFとDSを使ったプログラムは同じ最適化パスを通るので、 同様に最適化され、同じコードが生成され、同じ性能が出るはず?9 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki From Structuring Apache Spark 2.0: SQL, DataFrames, Datasets And Streaming - by Michael Armbrust DS DF Catalyst 最適化器 // generated Java code // for DF and DS while (itr.hasNext()) { Row r = (Row)itr.next(); int v = r.getInt(0); … }
  • 10. 単純な処理のDatasetプログラムでも遅い @Spark 2.0 ▪ スカラ整数変数への足し算が、DataFrameに比べて1.7倍遅い 10 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki 0 0.5 1 1.5 2 DataFrameの実行時間に対する相対値 DataFrame Dataset All experiments are done using 16-core Intel E2667-v3 3.2GHz, with 384GB mem, Ubuntu 16.04, OpenJDK 1.8.0u212-b13 with 256GB heap, Spark master=local[1] Spark branch-2.0 and branch-2.2, ds/df/rdd are cached 左のほうが高速 ds.map(value => value + 1) df.selectExpr(“value + 1”)
  • 11. 配列のDatasetプログラムではもっと遅い @Spark 2.0 ▪ 整数配列の生成が、DataFrameに比べて54倍遅い 11 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki 左のほうが高速 0 10 20 30 40 50 60 DataFrameの実行時間に対する相対値 DataFrame Dataset SPARK-16070参照 ds = Seq(Array(…), Array(…), …) .toDS.cache ds.map(a => Array(a(0))) df = Seq(Array(…), Array(…), …) .toDF(“a”).cache df.selectExpr(“Array(a[0])”)
  • 12. Spark 2.2では、これらのプログラムを高速化しました ▪ スカラ整数変数への足し算は、1.6倍速く ▪ 整数配列の生成は、4.5倍速く 12 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki どうやって? Catalystとコード生成を改良しました ds.map(value => value + 1) ds = Seq(Array(…), Array(…), …) .toDS.cache ds.map(a => Array(a(0)))
  • 13. このあとの話の流れ ▪ DataFrameとDatasetの紹介と現状 ▪ 先程の2つの例を深掘り – なぜDatasetは遅いのか? – Spark 2.2ではどのように改善したか? ▪ 別の例を深掘り – なぜDatasetは遅いのか? – 将来のSparkで改善する余地はどこにあるのか? ▪ DatasetはSpark MLパイプラインでどのように使われているか? ▪ 終わりに 13 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki
  • 14. DataFrameでのスカラ整数を扱うプログラム ▪ 全てSparkが生成したコードを実行する ▪ int型の足し算を実行する、きれいなJavaコードが生成される – DataframeがSpark内でvalueがint型であることを知っている – Project Tungstenで高速化のために導入した列の独自データ構造表現から、整 数を読み出し、intを使ったJavaコードを生成する 14 while (itr.hasNext()) { // execute a row // get a value from a row in DF int value =((Row)itr.next()).getInt(0); // compute a new value int mapValue = value + 1; // store a new value to a row in DF outRow.write(0, mapValue); append(outRow); } // df: DataFrame for int … df.selectExpr(“value + 1”) コード 生成 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki Catalystで Javaコードを 生成 列の独自データ構造(Row) row.getInt(0) outRow.write(0, …)
  • 15. Datasetでのスカラ整数を扱うプログラム@Spark 2.0 ▪ ラムダ式はScalacのコードを、それ以外はSparkが生成したコードを実行 ▪ 4つのデータ型変換(intとIntegerオブジェクト)を含む、複雑なJavaコー ドが生成される – Scalaのラムダ式の標準インタフェース apply(Object) を使うため、Integerオブ ジェクトを使う必要がある 15 コード 生成 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki Catalystで Javaコードを 生成 // ds: Dataset[Int] … ds.map(value => value + 1) while (itr.hasNext()) { int value = ((Row)itr.next()).getInt(0); Object objValue = new Integer(value); int mapValue = ((Integer) mapFunc.apply(objVal)).toValue(); outRow.write(0, mapValue); append(outRow); } Object apply(Object obj) { int value = Integer(obj).toValue(); return new Integer(apply$II(value)); } int apply$II(int value) { return value + 1; } Scalacがラムダ式から 生成したコード
  • 16. Spark 2.2でどのように改善したか? ▪ DataFrameと同様に、 int型の足し算を実行する、きれいなJavaコードを 生成する(SPARK-19008) – Scalacが apply$II(int) というコードを出すことを知って、Sparkが生成した コードからをObjectを使わず、apply$II(int)を直呼びするコードを生成する 16 コード 生成 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki Catalystで Javaコードを 生成 // ds: Dataset[Int] … ds.map(value => value + 1) while (itr.hasNext()) { int value = ((Row)itr.next()).getInt(0); int mapValue = mapFunc.apply$II(value); outRow.write(0, mapValue); append(outRow); } int apply$II(int value) { return value + 1; } Scalacがラムダ式から 生成したコード
  • 17. Spark 2.2では、この場合はもう遅くない! ▪ Spark 2.0に比べて、1.6倍高速化された – DataFrameとの差は、わずか9% 17 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki 0 0.5 1 1.5 2 DataFrameの実行時間に対する相対値 DataFrame Dataset 左側のほうが高速 1.6xds.map(value => value + 1) df.selectExpr(“value + 1”)
  • 18. RDDとも比べてみると @ Spark 2.2 ▪ 性能差は、大きく縮まった 18 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki 0 0.5 1 1.5 2 DataFrameの実行時間に対する相対値 RDD DataFrame Dataset 9% 5% 左側のほうが高速 ds.map(value => value + 1) df.selectExpr(“value + 1”) df.map(value => value + 1)
  • 19. 生成されたJavaコードを見るには ▪ .debugCode()をつける – DataFrame – Dataset @ Spark 2.0 19 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki scala> import org.apache.spark.sql.execution.debug._ scala> spark.range(1, 100).selectExpr("id + 1").debugCodegen ... /* 099 */ boolean project_isNull = false; /* 100 */ /* 101 */ long project_value = -1L; /* 102 */ project_value = range_value + 1L; /* 103 */ project_rowWriter.write(0, project_value); /* 104 */ append(project_result); /* 105 */ ... scala> import org.apache.spark.sql.execution.debug._ scala> spark.range(1, 100).map(value => value + 1).debugCodegen ... /* 100 */ /* 101 */ boolean mapelements_isNull = false || deserializetoobject_isNull; /* 102 */ final long mapelements_value = mapelements_isNull ? -1L : (Long) mapelements_value1.apply(deserializetoobject_value); /* 103 */ ... ここで見てるのは ほんの一部です
  • 20. 生成されたJavaコードを見るのがしんどい人は ▪ .explain() をつけて、Catalystが最適化した結果の実行プランを見ると雰 囲気がわかる – DataFrame – Dataset @ Spark 2.0 – Dataset @ Spark 2.2 20 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki scala> (1 to 100).toDF.selectExpr("value + 1").explain == Physical Plan == LocalTableScan [(value + 1)#14] scala> (1 to 100).toDS.map(value => value + 1).explain == Physical Plan == *SerializeFromObject [input[0, int, false] AS value#24] +- *MapElements <function1>, obj#23: int +- *DeserializeToObject value#19: int, obj#22: int +- LocalTableScan [value#19] scala> (1 to 100).toDS.map(value => value + 1).explain == Physical Plan == *SerializeFromObject [input[0, int, true] AS value#14] +- *MapElements <function1>, obj#13: int +- *DeserializeToObject value#9: int, obj#12: int +- LocalTableScan [value#9]
  • 21. このあとの話の流れ ▪ DataFrameとDatasetの紹介と現状 ▪ 先程の2つの例を深掘り – なぜDatasetは遅いのか? – Spark 2.2ではどのように改善したか? ▪ 別の例を深掘り – なぜDatasetは遅いのか? – 将来のSparkで改善する余地はどこにあるのか? ▪ DatasetはSpark MLパイプラインでどのように使われているか? ▪ 終わりに 21 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki
  • 22. DataFrameでの整数配列を扱うプログラム ▪ Project Tungstenで高速化のために導入した、配列用の独自データ構造を 通して、配列操作を行う 22 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki ArrayData inArray, outArray; while (itr.hasNext()) { inArray = ((Row)itr.next()).getArray(0); int value = inArray.getInt(0)); //a[0] outArray = new UnsafeArrayData(); ... outArray.setInt(0, value); //Array(a[0]) outArray.writeToMemory(outRow); append(outRow); } 配列の独自データ構造(ArrayData) inArray.getInt(0) outArray.setInt(0, …) // df: DataFrame for Array(Int) … df.selectExpr(“Array(a[0])”) Catalystで Javaコードを 生成 コード 生成
  • 23. Datasetでの整数配列を扱うプログラム ▪ ラムダ式用のJavaバイトコードでは、Project Tungstenの独自データ構造 を操作できないため、Javaオブジェクトとの間でserialization/ deserialzation (Ser/De)が必要になる 23 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki ArrayData inArray, outArray; while (itr.hasNext()) { inArray = ((Row)itr.next()).getArray(0); append(outRow); } 配列の独自データ構造(ArrayData) // ds: DataSet[Array(Int)] … ds.map(a => Array(a(0))) Catalystで Javaコードを 生成 コード 生成 Ser/De int[] mapArray = Array(a(0)); Ser/De Javaオブジェクト ラムダ式用の Javaバイトコード Deserialization Serialization
  • 24. Ser/Deをさらに深掘りすると… ▪ 遅い操作がてんこ盛り – Integer オブジェクトとintの間の データ変換 – 配列要素単位のコピー 24 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki // ds: DataSet[Array(Int)] … ds.map(a => Array(a(0))) Catalystで Javaコードを 生成 コード 生成 ArrayData inArray, outArray; while (itr.hasNext()) { inArray = ((Row)itr.next().getArray(0); append(outRow); } データ変換 配列要素単位のコピー 配列要素単位のコピー データ変換 配列要素単位のコピー Null checkを伴うデータコピー int[] mapArray = Array(a(0)); データ変換 配列要素単位のコピー Ser De Javaオブジェクトの作成 or 参照を伴う変換
  • 25. Spark 2.2でどのように改善したか? ▪ 遅いSer/Deを、速いarraycopyで置き換えたコードを生成する (SPARK-15985、SPARK-17490、SPARK-15962) 25 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki // ds: DataSet[Array(Int)] … ds.map(a => Array(a(0))) Catalystで Javaコードを 生成 コード 生成 ArrayData inArray, outArray; while (itr.hasNext()) { inArray = ((Row)itr.next().getArray(0); append(outRow); } int[] mapArray = Array(a(0)); arraycopy()を使う配列全体のコピー 配列全体のコピー 配列全体のコピー 配列全体のコピー
  • 26. Spark 2.2では、超極端には遅くない! ▪ でも、まだ12倍遅いです… 26 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki 0 10 20 30 40 50 60 DataFrameの実行時間に対する相対値 DataFrame Dataset 4.5x 12x 左側のほうが高速 ds = Seq(Array(…), Array(…), …) .toDS.cache ds.map(a => Array(a(0))) df = Seq(Array(…), Array(…), …) .toDF(“a”).cache df.selectExpr(“Array(a[0])”) map()メソッドで、計算時間がかかる 処理をしたら、無視できる …といいな
  • 27. RDDとも比べてみると ▪ DataFrame版は、RDD版より速い 27 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki ds = Seq(Array(…), Array(…), …) .toDS.cache ds.map(a => Array(a(0))) df = Seq(Array(…), Array(…), …) .toDF(“a”).cache df.selectExpr(“Array(a[0])”) 0 5 10 15 DataFrameの実行時間に対する相対値 RDD DataFrame Dataset 1.2 12 左側のほうが高速 rdd = sc.parallelize(Seq( Array(…), Array(…), …)).cache rdd.map(a => Array(a(0)))
  • 28. 実行プランを見てみると ▪ DataFrame ▪ DataSet @ Spark 2.0 ▪ Dataset @ Spark 2.2 28 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki scala> sc.parallelize(Seq(Array(1)), 1).toDF.selectExpr("Array(value[0])").explain == Physical Plan == *Project [array(value#39[0]) AS array(value[0])#47] +- *SerializeFromObject [staticinvoke(class org.apache.spark.sql.catalyst.expressions.UnsafeArrayData, ArrayType(IntegerType,false), fromPrimitiveArray, input[0, [I, true], true) AS value#39] +- Scan ExternalRDDScan[obj#38] scala> sc.parallelize(Seq(Array(1)), 1).toDS.map(a => Array(a(0))).explain == Physical Plan == *SerializeFromObject [newInstance(class org.apache.spark.sql.catalyst.util.GenericArrayData) AS value#11] +- *MapElements <function1>, obj#10: [I +- *DeserializeToObject cast(value#6 as array<int>).toIntArray, obj#9: [I +- Scan ExistingRDD[value#6] scala> sc.parallelize(Seq(Array(1)), 1).toDS.map(a => Array(a(0))).explain == Physical Plan == *SerializeFromObject [staticinvoke(class org.apache.spark.sql.catalyst.expressions.UnsafeArrayData, ArrayType(IntegerType,false), fromPrimitiveArray, input[0, [I, true], true) AS value#34] +- *MapElements <function1>, obj#33: [I +- Scan ExternalRDDScan[obj#28]
  • 29. ラムダ式が、独自データ構造を操作できないなら ▪ ラムダ式がProject Tungsten用の独自データ構造を操作できるように、ラ ムダ式を書き換えてしまえばよい ▪ プロトタイプを作ってみたところ、 Ser/Deを無くすことができて大きく 性能が改善された 29 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki while (itr.hasNext()) { inArray = ((Row)itr.next().getArray(0); outArray = mapFunc.applyTungsten(inArray); outArray.writeToMemory(outRow); append(outRow); } // ds: DataSet[Array(Int)] … ds.map(a => Array(a(0))) Catalystで Javaコードを 生成 コード 生成 “Accelerating Spark Datasets by inlining deserialization”, IPDPS2017という学会で発表済 配列の独自データ構造 1 1 apply(Object) 1011 applyTungsten (ArrayData) バイトコード 変換 a.getInt(0) a.setInt(0, …)
  • 30. このあとの話の流れ ▪ DataFrameとDatasetの紹介と現状 ▪ 先程の2つの例を深掘り – なぜDatasetは遅いのか? – Spark 2.2ではどのように改善したか? ▪ 別の例を深掘り – なぜDatasetは遅いのか? – 将来のSparkで改善する余地はどこにあるのか? ▪ DatasetはSpark MLパイプラインでどのように使われているか? ▪ 終わりに 30 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki
  • 31. 単純処理が続くDatasetプログラムも遅い @Spark 2.2 ▪ スカラ整数変数への足し算を2回続けて実行すると、DataFrameに比べ て1.1倍遅い 31 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki 左のほうが高速 ds.map(value => value + 1) .map(value => value + 2) df.selectExpr(“value + 1”) .selectExpr(“value + 2”) rdd.map(value => value + 1) .map(value => value + 2) 0 0.5 1 1.5 DataFrameの実行時間に対する相対値 RDD DataFrame Dataset
  • 32. DataFrameでは、2つの足し算が1つになる ▪ Catalyst最適化器が、selectExpr()の中の式を足し算である、と理解し て2つの足し算をコード生成前に計算して、value+3、に変換する 32 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki while (itr.hasNext()) { Row row = (Row)itr.next(); int value = row.getInt(0); int mapValue = value + 3; projectRow.write(0, mapValue); append(projectRow); } df.selectExpr(“value + 1”) .selectExpr(“value + 2”) Catalystで Javaコードを 生成 コード 生成
  • 33. Datasetでは、足し算のメソッド呼び出しが残ったまま ▪ Catalyst最適化器は、メソッド呼び出しの先にあるscalacが生成したJava バイトコードが、整数の足し算である、と理解できないので、そのまま 残る 33 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki while (itr.hasNext()) { int value = ((Row)itr.next()).getInt(0); int mapValue = mapFunc1.apply$II(value); mapValue += mapFunc2.apply$II(mapValue); outRow.write(0, mapValue); append(outRow); } // ds: Dataset[Int] … ds.map(value => value + 1) .map(value => value + 2) Catalystで Javaコードを 生成 コード 生成 class MapFunc1 { int apply$II(int value) { return value + 1;}} class MapFunc2 { int apply$II(int value) { return value + 2;}} Scalacがラムダ式から 生成したコード
  • 34. CatalystがJavaバイトコードを理解できないのなら… ▪ 理解できるように改善すればいい(SPARK-14083) – 残念ながら、2年近く塩漬けのプルリクとなってる – 個人的には、このプルリクは前に進めたい 34 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki while (itr.hasNext()) { int value = ((Row)itr.next()).getInt(0); int mapValue = value + 3; outRow.write(0, mapValue); append(outRow); } // ds: Dataset[Int] … ds.map(value => value + 1) .map(value => value + 2) Catalystで Javaコードを 生成 コード 生成 class MapFunc1 { int apply$II(int value) { return value + 1;}} class MapFunc2 { int apply$II(int value) { return value + 2;}} Scalacがラムダ式から 生成したコード
  • 35. このあとの話の流れ ▪ DataFrameとDatasetの紹介と現状 ▪ 先程の2つの例を深掘り – なぜDatasetは遅いのか? – Spark 2.2ではどのように改善したか? ▪ 別の例を深掘り – なぜDatasetは遅いのか? – 将来のSparkで改善する余地はどこにあるのか? ▪ DatasetはSpark MLパイプラインでどのように使われているか? ▪ 終わりに 35 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki
  • 36. DatasetはSpark ML pipelineの中でどう使われている? ▪ ML Pipelineを構築するために、Datasetは使われている ▪ 個々のMLアルゴリズムを見ると、実は内部ではRDDに変換して処理を 行っている – 主に記述力(ループ、その他)の問題? – RDDとDatasetの変換は実行時オーバヘッドを発生する 36 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki val trainingDS: Dataset = ... val tokenizer = new Tokenizer() val hashingTF = new HashingTF() val lr = new LogisticRegression() val pipeline = new Pipeline().setStages( Array(tokenizer, hashingTF, lr)) val model = pipeline.fit(trainingDS) def fit(ds: Dataset[_]) = { ... train(ds) } def train(ds:Dataset[_]):LogisticRegressionModel = { val instances: RDD[Instance] = ds.select(...).rdd.map { // convert DS to RDD case Row(...) => ... } instances.persist(...) instances.treeAggregate(...) } ML pipeline Machine learning algorithm (LogisticRegression)
  • 37. もし、DatasetをMLアルゴリズムの記述に使ったら ▪ ML Pipelineを構築するために、Datasetを使う ▪ MLアルゴリズムもDataset上のデータに対して処理を行う – データ変換オーバヘッドが無くなる – Catalystによる最適化が適用される(もしSPARK-14083がマージされたら) 37 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki val trainingDataset: Dataset = ... val tokenizer = new Tokenizer() val hashingTF = new HashingTF() val lr = new LogisticRegression() val pipeline = new Pipeline().setStages( Array(tokenizer, hashingTF, lr)) val model = pipeline.fit(trainingDataset) def train(ds:Dataset[_]):LogisticRegressionModel = { val instances: Dataset[Instance] = ds.select(...).rdd.map { case Row(...) => ... } instances.persist(...) instances.treeAggregate(...) } ML pipeline Machine learning algorithm (LogisticRegression)
  • 38. 終わりに ▪ Datasetは、Spark 2.2以降でかなり速くなった ▪ Datasetの性能改善の源泉 – 無駄なデータ変換をへらす – Serialization/Deserializationをなくす – (ToDo)Catalystにおけるラムダ式の扱いの改善 ▪ Datasetは、ニワトリと卵、状態に陥ってしまっている – 性能が出ないから使わない – 使わないから、性能が出なくてもissueが上がらない ▪ ぜひ、Datasetを使ってください – そしてissueを投げて声をあげてみてください – できればプルリクも ☺ 38 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki Sparkコミュニティに飛び込もう! by Apache Spark コミッタ 猿田さん https://www.slideshare.net/hadoopxnttdata/apache-spark-commnity-nttdata-sarutak
  • 39. Thank you ▪ @sameeragarwal, @hvanhovell, @gatorsmile, @cloud-fan, @ueshin, @davies, @rxin, @joshrosen, @maropu, @viirya ▪ IBM CODAIT 39 DataFrameとDatasetの内部をのぞいてみる - Kazuaki Ishizaki