मेरी टीम कच्चे सीमांकित टेक्स्ट फ़ाइलों को स्पार्क का उपयोग करते हुए एक लकड़ी के आधार पर "डेटा झील" में लोड करने के लिए एक ईटीएल प्रक्रिया का निर्माण कर रही है। लकड़ी के कॉलम स्टोर के वादे में से एक यह है कि एक प्रश्न केवल आवश्यक "कॉलम पट्टियों" को पढ़ेगा।अपाचे स्पार्क ने नेस्टेड संरचनाओं के भीतर अनावश्यक लकड़ी के कॉलम क्यों पढ़े हैं?
लेकिन हम नेस्टेड स्कीमा संरचनाओं के लिए अप्रत्याशित कॉलम पढ़ रहे हैं।
प्रदर्शित करने के लिए, यहाँ स्काला और स्पार्क 2.0.1 खोल का उपयोग कर एक POC है:
// Preliminary setup
sc.setLogLevel("INFO")
import org.apache.spark.sql.types._
import org.apache.spark.sql._
// Create a schema with nested complex structures
val schema = StructType(Seq(
StructField("F1", IntegerType),
StructField("F2", IntegerType),
StructField("Orig", StructType(Seq(
StructField("F1", StringType),
StructField("F2", StringType))))))
// Create some sample data
val data = spark.createDataFrame(
sc.parallelize(Seq(
Row(1, 2, Row("1", "2")),
Row(3, null, Row("3", "ABC")))),
schema)
// Save it
data.write.mode(SaveMode.Overwrite).parquet("data.parquet")
फिर हम कॉलम के एक सबसेट के लिए एक DataFrame और परियोजना में वापस फ़ाइल को पढ़ने:
// Read it back into another DataFrame
val df = spark.read.parquet("data.parquet")
// Select & show a subset of the columns
df.select($"F1", $"Orig.F1").show
जब यह चलाता है हम उम्मीद उत्पादन देखें:
+---+-------+
| F1|Orig_F1|
+---+-------+
| 1| 1|
| 3| 3|
+---+-------+
लेकिन ... क्वेरी योजना एक से थोड़ा एडवेंचर्स से पता चलता टी कहानी:
"अनुकूलित योजना" पता चलता है:
val projected = df.select($"F1", $"Orig.F1".as("Orig_F1"))
projected.queryExecution.optimizedPlan
// Project [F1#18, Orig#20.F1 AS Orig_F1#116]
// +- Relation[F1#18,F2#19,Orig#20] parquet
और "समझाने" शो:
projected.explain
// == Physical Plan ==
// *Project [F1#18, Orig#20.F1 AS Orig_F1#116]
// +- *Scan parquet [F1#18,Orig#20] Format: ParquetFormat, InputPaths: hdfs://sandbox.hortonworks.com:8020/user/stephenp/data.parquet, PartitionFilters: [], PushedFilters: [], ReadSchema: struct<F1:int,Orig:struct<F1:string,F2:string>>
और जानकारी निष्पादन के दौरान तैयार किए गए लॉग भी पुष्टि करते हैं कि Orig.F2 स्तंभ है अप्रत्याशित रूप से पढ़ें:
16/10/21 15:13:15 INFO parquet.ParquetReadSupport: Going to read the following fields from the Parquet file:
Parquet form:
message spark_schema {
optional int32 F1;
optional group Orig {
optional binary F1 (UTF8);
optional binary F2 (UTF8);
}
}
Catalyst form:
StructType(StructField(F1,IntegerType,true), StructField(Orig,StructType(StructField(F1,StringType,true), StructField(F2,StringType,true)),true))
Dremel paper औरके अनुसार, जटिल नेस्टेड संरचनाओं के लिए कॉलम स्वतंत्र रूप से संग्रहीत और स्वतंत्र रूप से पुनर्प्राप्त करने योग्य होना चाहिए।
सवाल:
- इस व्यवहार वर्तमान स्पार्क क्वेरी इंजन की एक सीमा है? दूसरे शब्दों में, क्या Parquet समर्थन इस क्वेरी को निष्पादित करने का समर्थन करता है, लेकिन स्पार्क की क्वेरी प्लानर बेवकूफ है?
- या, क्या यह वर्तमान लकड़ी के कार्यान्वयन की सीमा है?
- या, क्या मैं स्पार्क एपीआई का सही ढंग से उपयोग नहीं कर रहा हूं?
- या, क्या मैं गलत समझ रहा हूं कि ड्रेमल/पैराक्वेट कॉलम संग्रहण कैसे काम करना चाहिए?
संभवतः संबंधित: Why does the query performance differ with nested columns in Spark SQL?
यह एक स्पार्क क्वेरी इंजन मुद्दा है। –
@LostInOverflow, क्या आपको पता है कि यह स्पार्क मुद्दे ट्रैकर में है या नहीं? https://issues.apache.org/jira/browse/SPARK/?selectedTab=com.atlassian.jira.jira-projects-plugin:issues-panel –
ऐसा प्रतीत होता है कि लकड़ी को इस परिदृश्य का समर्थन @ julien-le- डेम https://twitter.com/J_/status/789584704169123841 –