ความแตกต่างระหว่าง DataFrame ชุดข้อมูลและ RDD ใน Spark


257

ฉันแค่สงสัยว่าอะไรคือความแตกต่างระหว่างRDDและDataFrame (Spark 2.0.0 DataFrame เป็นเพียงนามแฝงประเภทสำหรับDataset[Row])ใน Apache Spark?

คุณสามารถแปลงหนึ่งเป็นอื่นได้หรือไม่

คำตอบ:


232

A DataFrameถูกกำหนดอย่างดีด้วยการค้นหาโดย Google สำหรับ "คำจำกัดความของ DataFrame":

กรอบข้อมูลเป็นตารางหรือโครงสร้างคล้ายอาร์เรย์สองมิติซึ่งแต่ละคอลัมน์มีการวัดในตัวแปรเดียวและแต่ละแถวมีหนึ่งกรณี

ดังนั้น a DataFrameมีข้อมูลเมตาเพิ่มเติมเนื่องจากรูปแบบตารางซึ่งช่วยให้ Spark สามารถเรียกใช้การเพิ่มประสิทธิภาพบางอย่างในแบบสอบถามที่สรุปแล้ว

RDDบนมืออื่น ๆ ที่เป็นเพียงR esilient D istributed D ataset ที่มีมากขึ้นของดำของข้อมูลที่ไม่สามารถเพิ่มประสิทธิภาพการดำเนินงานที่สามารถดำเนินการกับมันไม่ได้เป็นข้อ จำกัด

อย่างไรก็ตามคุณสามารถเปลี่ยนจาก DataFrame เป็นRDDผ่านrddวิธีการของมันและคุณสามารถเปลี่ยนจากRDDa เป็น a DataFrame(ถ้า RDD อยู่ในรูปแบบตาราง) ผ่านtoDFวิธีการ

โดยทั่วไปจะแนะนำให้ใช้DataFrameที่เป็นไปได้เนื่องจากการเพิ่มประสิทธิภาพแบบสอบถามในตัว


6
คำตอบไม่ได้ให้คำอธิบายเกี่ยวกับชุดข้อมูล ตาม Spark- The Definitive Guide ชุดข้อมูลเป็น API โครงสร้างที่ปลอดภัย ดังนั้นคุณสามารถให้ประเภทของสคีมาของคุณไว้ล่วงหน้า
Chintan Pandya

3
ขอบคุณ - ชื่อและคำอธิบายดั้งเดิมได้รับการแก้ไขได้ดีหลังจากคำถามเดิม (ซึ่งไม่รวมชุดข้อมูล)
Justin Pihony

219

สิ่งแรกที่จะได้รับการพัฒนามาจากDataFrameSchemaRDD

depreated วิธีการ SchemaRDD

ใช่ .. การแปลงระหว่างDataframeและRDDเป็นไปได้อย่างแน่นอน

ด้านล่างนี้เป็นตัวอย่างโค้ดบางส่วน

  • df.rdd คือ RDD[Row]

ด้านล่างเป็นตัวเลือกบางส่วนในการสร้างดาต้าเฟรม

  • 1) yourrddOffrow.toDFDataFrameแปลงไป

  • 2) การใช้createDataFrameบริบท sql

    val df = spark.createDataFrame(rddOfRow, schema)

สคีมาจากตัวเลือกด้านล่างบางตัวตามที่อธิบายโดย nice post
จากชั้นกรณีสกาล่าและสกาล่าสะท้อน API

import org.apache.spark.sql.catalyst.ScalaReflection
val schema = ScalaReflection.schemaFor[YourScalacaseClass].dataType.asInstanceOf[StructType]

หรือใช้ Encoders

import org.apache.spark.sql.Encoders
val mySchema = Encoders.product[MyCaseClass].schema

ตามที่อธิบายไว้โดย Schema สามารถสร้างโดยใช้StructTypeและ StructField

val schema = new StructType()
  .add(StructField("id", StringType, true))
  .add(StructField("col1", DoubleType, true))
  .add(StructField("col2", DoubleType, true)) etc...

คำอธิบายภาพ

อันที่จริงตอนนี้มี Apache Apache API 3 ตัวแล้ว

ป้อนคำอธิบายรูปภาพที่นี่

  1. RDD API:

RDD(ยืดหยุ่นกระจายชุดข้อมูล) API ได้รับในการจุดประกายตั้งแต่ปล่อย 1.0

RDDAPI ให้วิธีการมากมายที่เปลี่ยนแปลงเช่นmap() filter() และreduce() สำหรับการดำเนินการคำนวณข้อมูลที่ แต่ละวิธีการเหล่านี้ส่งผลให้เกิดRDDการเปลี่ยนแปลงข้อมูลใหม่ อย่างไรก็ตามวิธีการเหล่านี้เป็นเพียงการกำหนดการดำเนินการที่จะดำเนินการและการแปลงจะไม่ดำเนินการจนกว่าจะเรียกวิธีการกระทำ ตัวอย่างของวิธีการกระทำคือcollect() และ saveAsObjectFile()

ตัวอย่าง RDD:

rdd.filter(_.age > 21) // transformation
   .map(_.last)// transformation
.saveAsObjectFile("under21.bin") // action

ตัวอย่าง: กรองตามคุณสมบัติด้วย RDD

rdd.filter(_.age > 21)
  1. DataFrame API

Spark 1.3 เปิดตัวใหม่ DataFrame APIซึ่งเป็นส่วนหนึ่งของโครงการทังสเตนซึ่งพยายามปรับปรุงประสิทธิภาพและความยืดหยุ่นของ Spark DataFrameแนะนำ API แนวคิดของสคีมาเพื่ออธิบายข้อมูลที่ช่วยจุดประกายในการจัดการสคีมาและเพียงส่งผ่านข้อมูลระหว่างโหนดในทางที่มีประสิทธิภาพมากขึ้นกว่าการใช้ Java อนุกรม

DataFrameAPI เป็นอย่างรุนแรงแตกต่างจากRDDAPI เพราะเป็น API สำหรับการสร้างแผนแบบสอบถามเชิงสัมพันธ์ที่จุดประกายของการเพิ่มประสิทธิภาพ Catalyst แล้วสามารถดำเนินการ API นั้นเป็นเรื่องธรรมดาสำหรับนักพัฒนาที่คุ้นเคยกับการสร้างแผนคิวรี

ตัวอย่างสไตล์ SQL:

df.filter("age > 21");

ข้อ จำกัด : เนื่องจากโค้ดอ้างถึงข้อมูลแอตทริบิวต์ตามชื่อจึงเป็นไปไม่ได้ที่คอมไพเลอร์จะตรวจจับข้อผิดพลาดใด ๆ หากชื่อแอตทริบิวต์ไม่ถูกต้องจะตรวจพบข้อผิดพลาดเมื่อรันไทม์เท่านั้นเมื่อสร้างแผนแบบสอบถาม

ข้อเสียอีกอย่างหนึ่งของDataFrameAPI ก็คือมันเป็นแบบสกาล่าที่เป็นศูนย์กลางและในขณะที่มันรองรับจาวาการสนับสนุนก็มี จำกัด

ตัวอย่างเช่นเมื่อสร้าง a DataFrameจากRDDวัตถุ Java ที่มีอยู่เครื่องมือเพิ่มประสิทธิภาพ Catalyst ของ Spark ไม่สามารถอนุมานสคีมาและถือว่าวัตถุใด ๆ ใน DataFrame ใช้scala.Productอินเตอร์เฟส Scala case classทำงานนอกกรอบเพราะใช้อินเทอร์เฟซนี้

  1. Dataset API

DatasetAPI ปล่อยภาพตัวอย่าง API ใน Spark 1.6 จุดมุ่งหมายที่จะให้ที่ดีที่สุดของโลกทั้งสอง; สไตล์การเขียนโปรแกรมเชิงวัตถุที่คุ้นเคยและความปลอดภัยประเภทเวลารวบรวมของRDDAPI แต่ด้วยประโยชน์ด้านประสิทธิภาพของเครื่องมือเพิ่มประสิทธิภาพการค้นหา Catalyst ชุดข้อมูลยังใช้กลไกการจัดเก็บข้อมูลนอกฮีปที่มีประสิทธิภาพเช่นเดียวกับ DataFrame API

เมื่อพูดถึงการทำให้เป็นอนุกรมข้อมูลDatasetAPI มีแนวคิดของ ตัวเข้ารหัสซึ่งแปลระหว่างการแทน JVM (วัตถุ) และรูปแบบไบนารีภายในของ Spark Spark มีตัวเข้ารหัสในตัวซึ่งมีความก้าวหน้าสูงมากในการสร้างรหัสไบต์เพื่อโต้ตอบกับข้อมูลนอกกองและให้การเข้าถึงตามความต้องการของแต่ละคุณลักษณะโดยไม่ต้องทำให้วัตถุทั้งหมดเป็นอนุกรม Spark ยังไม่ได้จัดทำ API สำหรับการใช้งานเครื่องเข้ารหัสที่กำหนดเอง แต่มีการวางแผนสำหรับการเปิดตัวในอนาคต

นอกจากนี้DatasetAPI ได้รับการออกแบบให้ทำงานได้ดีกับทั้ง Java และ Scala เมื่อทำงานกับวัตถุ Java เป็นสิ่งสำคัญที่พวกเขาจะสอดคล้องกับถั่วอย่างเต็มที่

ตัวอย่างDatasetสไตล์ API SQL:

dataset.filter(_.age < 21);

การประเมินต่างกัน ระหว่างDataFrame& DataSet: ป้อนคำอธิบายรูปภาพที่นี่

การไหลระดับตัวเร่งปฏิกิริยา . Demystifying DataFrame และงานนำเสนอชุดข้อมูลจากการประชุมสุดยอด spark) ป้อนคำอธิบายรูปภาพที่นี่

อ่านเพิ่มเติม ... บทความชุดข้อมูล - เรื่องราวของสาม Apache Spark APIs: RDDs กับ DataFrames และชุดข้อมูล


ชุดข้อมูลที่พิมพ์อย่างรุนแรงคืออะไร แตกต่างจาก DataFrame อย่างไร
Arvind Kumar

ข้อผิดพลาดการวิเคราะห์ชนิดใดครอบคลุมอยู่ในชุดข้อมูล
Neeleshkumar S

5
@ neelesh-srinivasan: นำตัวอย่างในไวยากรณ์ dataframe df.filter("age > 21");นี้สามารถประเมิน / วิเคราะห์ในเวลาทำงานเท่านั้น ตั้งแต่สตริง ในกรณีของชุดข้อมูลชุดข้อมูลเป็นไปตามถั่ว อายุคือคุณสมบัติของถั่ว ถ้าคุณสมบัติอายุไม่อยู่ในถั่วคุณจะรู้ได้เร็วขึ้นในเวลารวบรวม (เช่นdataset.filter(_.age < 21);) ข้อผิดพลาดการวิเคราะห์สามารถเปลี่ยนชื่อเป็นข้อผิดพลาดการประเมินผล
Ram Ghadiyaram

@NeeleshSrinivasan: สำหรับข้อมูลเพิ่มเติมและรายละเอียดดูapache-spark-api-comparision
Ram Ghadiyaram

ภาพแรกทำให้เข้าใจผิด ชุดข้อมูลไม่พร้อมใช้งานใน Python
Yeikel

135

Apache Spark มี API สามประเภท

  1. RDD
  2. DataFrame
  3. ชุด

การเปรียบเทียบ RDD, Dataframe และ API ชุดข้อมูล

นี่คือการเปรียบเทียบ API ระหว่าง RDD, Dataframe และชุดข้อมูล

RDD

หลัก abstraction Spark ให้เป็นชุดข้อมูลแบบกระจายความยืดหยุ่น (RDD) ซึ่งเป็นชุดขององค์ประกอบที่แบ่งพาร์ติชันข้ามโหนดของคลัสเตอร์ที่สามารถดำเนินการในแบบคู่ขนาน

คุณสมบัติ RDD: -

  • คอลเลกชันแบบกระจาย:
    RDD ใช้การดำเนินการ MapReduce ซึ่งได้รับการยอมรับอย่างกว้างขวางสำหรับการประมวลผลและการสร้างชุดข้อมูลขนาดใหญ่ด้วยอัลกอริทึมแบบกระจายและขนานบนคลัสเตอร์ ช่วยให้ผู้ใช้สามารถเขียนการคำนวณแบบขนานโดยใช้ชุดตัวดำเนินการระดับสูงโดยไม่ต้องกังวลเกี่ยวกับการกระจายงานและการยอมรับข้อบกพร่อง

  • ไม่เปลี่ยนรูป: RDD ประกอบด้วยชุดของระเบียนที่มีการแบ่งพาร์ติชัน พาร์ติชันเป็นหน่วยพื้นฐานของการขนานใน RDD และแต่ละพาร์ติชันเป็นส่วนหนึ่งของข้อมูลที่ไม่เปลี่ยนรูปและสร้างขึ้นผ่านการเปลี่ยนแปลงบางส่วนบนพาร์ติชันที่มีอยู่ความไม่แน่นอนช่วยให้บรรลุความมั่นคงในการคำนวณ

  • ความผิดพลาดที่ยอมรับได้: ในกรณีที่เราสูญเสียพาร์ติชั่นบางส่วนของ RDD เราสามารถเล่นซ้ำการแปลงบนพาร์ติชั่นนั้นเพื่อให้ได้การคำนวณเดียวกันแทนที่จะทำการเรพลิเคทข้อมูลข้ามหลายโหนดคุณสมบัตินี้เป็นประโยชน์ที่ใหญ่ที่สุดของ RDD ความพยายามอย่างมากในการจัดการข้อมูลและการทำซ้ำจึงทำให้สามารถคำนวณได้เร็วขึ้น

  • การประเมิน Lazy: การเปลี่ยนแปลงทั้งหมดใน Spark เป็นสิ่งที่ขี้เกียจซึ่งจะไม่คำนวณผลลัพธ์ในทันที แต่พวกเขาเพียงจำการแปลงที่ใช้กับชุดข้อมูลพื้นฐานบางส่วน การแปลงจะคำนวณได้ก็ต่อเมื่อการกระทำนั้นต้องการผลลัพธ์ที่จะส่งคืนไปยังโปรแกรมไดรเวอร์

  • การเปลี่ยนแปลงเชิงหน้าที่: RDD สนับสนุนการดำเนินการสองประเภท: การแปลงซึ่งสร้างชุดข้อมูลใหม่จากชุดข้อมูลที่มีอยู่และการดำเนินการซึ่งส่งคืนค่าให้กับโปรแกรมไดรเวอร์หลังจากเรียกใช้การคำนวณบนชุดข้อมูล

  • รูปแบบการประมวลผลข้อมูล:
    สามารถประมวลผลข้อมูลได้อย่างง่ายดายและมีประสิทธิภาพซึ่งมีโครงสร้างเช่นเดียวกับข้อมูลที่ไม่มีโครงสร้าง

  • ภาษาโปรแกรมที่รองรับ:
    RDD API มีให้ใน Java, Scala, Python และ R

ข้อ จำกัด RDD: -

  • ไม่มีเครื่องมือเพิ่มประสิทธิภาพ inbuilt: เมื่อทำงานกับข้อมูลที่มีโครงสร้าง RDDs ไม่สามารถใช้ประโยชน์จากเครื่องมือเพิ่มประสิทธิภาพขั้นสูงของ Spark รวมถึงเครื่องมือเพิ่มประสิทธิภาพตัวเร่งปฏิกิริยาและเครื่องมือประมวลผลทังสเตน นักพัฒนาจำเป็นต้องปรับแต่ง RDD ให้เหมาะสมตามคุณสมบัติของมัน

  • การจัดการข้อมูลที่มีโครงสร้าง: ซึ่งแตกต่างจาก Dataframe และชุดข้อมูล RDDs ไม่อนุมานสคีมาของข้อมูลที่ติดเครื่องและต้องการให้ผู้ใช้ระบุ

Dataframes

Spark เปิดตัว Dataframes ในการเปิดตัว Spark 1.3 Dataframe จะเอาชนะความท้าทายที่สำคัญที่ RDDs มี

DataFrame เป็นการรวบรวมข้อมูลแบบกระจายในคอลัมน์ที่มีชื่อ มันเทียบเท่ากับแนวคิดในตารางในฐานข้อมูลเชิงสัมพันธ์หรือ Dataframe R / Python นอกจาก Dataframe แล้ว Spark ยังเปิดตัว catalyst optimizer ซึ่งใช้ประโยชน์จากฟีเจอร์การตั้งโปรแกรมขั้นสูงเพื่อสร้างเครื่องมือเพิ่มประสิทธิภาพการสืบค้นแบบขยายได้

คุณสมบัติของ Dataframe: -

  • การรวบรวมแบบกระจายของวัตถุแถว: DataFrame เป็นการรวบรวมข้อมูลแบบกระจายในคอลัมน์ที่มีชื่อ มันเป็นแนวคิดที่เทียบเท่ากับตารางในฐานข้อมูลเชิงสัมพันธ์ แต่มีการเพิ่มประสิทธิภาพที่สมบูรณ์ยิ่งขึ้นภายใต้ประทุน

  • การประมวลผลข้อมูล: การประมวลผลรูปแบบข้อมูลและโครงสร้างที่ไม่มีโครงสร้าง (Avro, CSV, การค้นหายืดหยุ่นและ Cassandra) และระบบจัดเก็บข้อมูล (HDFS, ตาราง HIVE, MySQL, ฯลฯ ) สามารถอ่านและเขียนจากแหล่งข้อมูลต่าง ๆ เหล่านี้ทั้งหมด

  • การเพิ่มประสิทธิภาพโดยใช้เครื่องมือเพิ่มประสิทธิภาพ catalyst: เพิ่มประสิทธิภาพ ทั้งแบบสอบถาม SQL และ DataFrame API Dataframe ใช้เฟรมเวิร์กทรีการแปลงต้นไม้ในสี่ขั้นตอน

     1.Analyzing a logical plan to resolve references
     2.Logical plan optimization
     3.Physical planning
     4.Code generation to compile parts of the query to Java bytecode.
    
  • ความเข้ากันได้ของ Hive: การใช้ Spark SQL คุณสามารถเรียกใช้แบบสอบถาม Hive ที่ไม่ได้แก้ไขบนคลังสินค้า Hive ที่มีอยู่ของคุณ มันนำส่วนหน้า Hive และ MetaStore มาใช้ใหม่และให้ความเข้ากันได้อย่างสมบูรณ์กับข้อมูล Hive ที่มีอยู่การสืบค้นและ UDF

  • ทังสเตน: ทังสเตนมอบแบ็กเอนด์การประมวลผลทางกายภาพซึ่งจัดการหน่วยความจำอย่างชัดแจ้งและสร้างโค้ดไบต์แบบไดนามิกสำหรับการประเมินผลการแสดงออก

  • ภาษาโปรแกรมที่รองรับ:
    Dataframe API มีให้ใน Java, Scala, Python และ R

ข้อ จำกัด ของ Dataframe: -

  • ความปลอดภัยประเภทเวลาคอมไพล์: ตามที่กล่าวไว้ Dataframe API ไม่สนับสนุนความปลอดภัยเวลาคอมไพล์ซึ่ง จำกัด คุณจากการจัดการข้อมูลเมื่อโครงสร้างไม่ทราบ ตัวอย่างต่อไปนี้ทำงานในช่วงเวลารวบรวม อย่างไรก็ตามคุณจะได้รับข้อยกเว้นรันไทม์เมื่อเรียกใช้รหัสนี้

ตัวอย่าง:

case class Person(name : String , age : Int) 
val dataframe = sqlContext.read.json("people.json") 
dataframe.filter("salary > 10000").show 
=> throws Exception : cannot resolve 'salary' given input age , name

สิ่งนี้เป็นสิ่งที่ท้าทายเป็นพิเศษเมื่อคุณทำงานกับขั้นตอนการเปลี่ยนแปลงและการรวมตัวหลายอย่าง

  • ไม่สามารถทำงานกับโดเมนวัตถุ (วัตถุโดเมนที่สูญหาย): เมื่อคุณเปลี่ยนวัตถุโดเมนเป็นดาต้าเฟรมคุณจะไม่สามารถสร้างมันใหม่ได้ ในตัวอย่างต่อไปนี้เมื่อเราสร้าง personDF จาก personRDD เราจะไม่สามารถกู้คืน RDD ดั้งเดิมของคลาสบุคคล (RDD [บุคคล]) ได้

ตัวอย่าง:

case class Person(name : String , age : Int)
val personRDD = sc.makeRDD(Seq(Person("A",10),Person("B",20)))
val personDF = sqlContext.createDataframe(personRDD)
personDF.rdd // returns RDD[Row] , does not returns RDD[Person]

ชุดข้อมูล API

Dataset API เป็นส่วนขยายของ DataFrames ที่จัดเตรียมอินเทอร์เฟซการเขียนโปรแกรมเชิงวัตถุ มันเป็นชุดของวัตถุที่ไม่เปลี่ยนรูปแบบซึ่งได้รับการแมปอย่างมากและถูกแมปกับสคีมาเชิงสัมพันธ์

ที่แกนกลางของชุดข้อมูล API เป็นแนวคิดใหม่ที่เรียกว่าตัวเข้ารหัสซึ่งรับผิดชอบในการแปลงระหว่างวัตถุ JVM และการเป็นตัวแทนตาราง การแสดงแบบตารางจะถูกเก็บไว้โดยใช้รูปแบบไบนารี Spark ภายในของทังสเตนเพื่อให้สามารถดำเนินการกับข้อมูลที่เป็นอนุกรมและการใช้หน่วยความจำที่ดีขึ้น Spark 1.6 มาพร้อมกับการรองรับการสร้างเครื่องเข้ารหัสโดยอัตโนมัติสำหรับหลากหลายประเภทรวมถึงประเภทดั้งเดิม (เช่น String, Integer, Long), คลาสเคส Scala และ Java Beans

คุณสมบัติชุดข้อมูล: -

  • ให้ดีที่สุดทั้ง RDD และ Dataframe: RDD (การเขียนโปรแกรมการใช้งาน, ประเภทปลอดภัย), DataFrame (โมเดลเชิงสัมพันธ์, การเพิ่มประสิทธิภาพการค้นหา, การประมวลผลทังสเตน, การเรียงลำดับและการสับ)

  • ตัวเข้ารหัส: ด้วยการใช้ตัวเข้ารหัสมันเป็นเรื่องง่ายที่จะแปลงวัตถุ JVM ใด ๆ ให้เป็นชุดข้อมูลทำให้ผู้ใช้สามารถทำงานกับข้อมูลที่มีโครงสร้างและไม่มีโครงสร้างซึ่งแตกต่างจาก Dataframe

  • ภาษาโปรแกรมที่รองรับ: ชุดข้อมูล API มีให้บริการเฉพาะใน Scala และ Java Python และ R ไม่รองรับในเวอร์ชัน 1.6 รองรับ Python กำหนดไว้สำหรับเวอร์ชัน 2.0

  • ประเภทความปลอดภัย: ชุดข้อมูล API ให้ความปลอดภัยเวลารวบรวมซึ่งไม่สามารถใช้ได้ใน Dataframes ในตัวอย่างด้านล่างเราสามารถดูว่าชุดข้อมูลสามารถทำงานบนวัตถุโดเมนด้วยฟังก์ชั่นการรวบรวมแลมบ์ดาได้อย่างไร

ตัวอย่าง:

case class Person(name : String , age : Int)
val personRDD = sc.makeRDD(Seq(Person("A",10),Person("B",20)))
val personDF = sqlContext.createDataframe(personRDD)
val ds:Dataset[Person] = personDF.as[Person]
ds.filter(p => p.age > 25)
ds.filter(p => p.salary > 25)
 // error : value salary is not a member of person
ds.rdd // returns RDD[Person]
  • ทำงานร่วมกันได้:ชุดข้อมูลช่วยให้คุณสามารถแปลง RDD และ Dataframes ที่มีอยู่ของคุณเป็นชุดข้อมูลโดยไม่ต้องใช้รหัสสำเร็จรูป

ข้อ จำกัด ของชุดข้อมูล API: -

  • ต้องการการหล่อแบบเป็นสตริง: การ สืบค้นข้อมูลจากชุดข้อมูลในขณะนี้ต้องการให้เราระบุฟิลด์ในคลาสเป็นสตริง เมื่อเราได้ทำการสอบถามข้อมูลแล้วเราถูกบังคับให้ทำการแปลงคอลัมน์เป็นประเภทข้อมูลที่ต้องการ ในทางกลับกันถ้าเราใช้การทำงานของแผนที่บนชุดข้อมูลมันจะไม่ใช้ตัวเพิ่มประสิทธิภาพ Catalyst

ตัวอย่าง:

ds.select(col("name").as[String], $"age".as[Int]).collect()

ไม่รองรับ Python และ R: ตั้งแต่รีลีส 1.6 ชุดข้อมูลสนับสนุน Scala และ Java เท่านั้น รองรับ Python ใน Spark 2.0

API ชุดข้อมูลมีข้อดีหลายประการเหนือกว่า RDD และ Dataframe API ที่มีอยู่ด้วยความปลอดภัยประเภทที่ดีขึ้นและการเขียนโปรแกรมการทำงานด้วยความท้าทายของข้อกำหนดการหล่อแบบใน API คุณจะยังคงไม่ได้รับความปลอดภัยประเภทที่ต้องการและจะทำให้รหัสของคุณเปราะ


2
จากspark.apache.org/docs/latest/… , ใน Scala API, DataFrame เป็นเพียงนามแฝงประเภทของชุดข้อมูล [Row]
Dean Chen

เป็นเช่นนั้นแล้วหรือยังที่จะบอกว่าด้วยชุดข้อมูลเราได้รับความปลอดภัยประเภทและสูญเสียเครื่องมือเพิ่มประสิทธิภาพหรือไม่
Khoa

@BlueSky คุณได้รับความปลอดภัยประเภทและยังมีเครื่องมือเพิ่มประสิทธิภาพ
Gabber

@AmitDubey นั่นไม่ใช่เรื่องจริง Datasetไม่ใช่ LINQ และแลมบ์ดาไม่สามารถตีความได้ว่าเป็นนิพจน์ต้นไม้ ดังนั้นจึงมีกล่องดำและคุณจะสูญเสียประโยชน์ของเครื่องมือเพิ่มประสิทธิภาพ (ถ้าไม่ใช่ทั้งหมด) เพียงส่วนย่อยเล็ก ๆ ของข้อเสียเป็นไปได้: Spark 2.0 ชุดข้อมูล VS DataFrame นอกจากนี้เพียงทำซ้ำสิ่งที่ฉันระบุหลายครั้ง - โดยทั่วไปการตรวจสอบประเภทตั้งแต่ต้นจนจบไม่สามารถทำได้ด้วยDatasetAPI การเข้าร่วมเป็นเพียงตัวอย่างที่โดดเด่นที่สุด
zero323

52

ทั้งหมด (RDD, DataFrame และ DataSet) ในภาพเดียว

RDD กับ DataFrame เทียบกับชุดข้อมูล

เครดิตภาพ

RDD

RDD คือชุดขององค์ประกอบที่สามารถทนต่อความผิดพลาดได้ในแบบคู่ขนาน

DataFrame

DataFrameเป็นชุดข้อมูลที่จัดเป็นคอลัมน์ที่มีชื่อ มันเป็นแนวคิดที่เทียบเท่ากับตารางในฐานข้อมูลเชิงสัมพันธ์หรือกรอบข้อมูลใน R / หลาม, แต่มี optimisations ยิ่งขึ้นภายใต้ประทุน

Dataset

Datasetเป็นการรวบรวมข้อมูลแบบกระจาย ชุดข้อมูลที่เป็นอินเตอร์เฟซใหม่เพิ่มเข้ามาใน Spark 1.6 ที่ให้ประโยชน์ของ RDDs (พิมพ์ strong, ความสามารถในการใช้ฟังก์ชั่นที่มีประสิทธิภาพแลมบ์ดา) กับ ประโยชน์ของเครื่องยนต์ Spark SQL ของการเพิ่มประสิทธิภาพ


บันทึก:

ชุดแถว ( Dataset[Row]) ใน Scala / Java มักจะอ้างเป็น DataFrames


Nice comparison of all of them with a code snippet.

RDD vs DataFrame กับชุดข้อมูลพร้อมรหัส

แหล่ง


ถาม: คุณสามารถแปลงหนึ่งเป็นอื่น ๆ เช่น RDD เป็น DataFrame หรือในทางกลับกันได้หรือไม่?

ใช่ทั้งสองเป็นไปได้

1. RDDถึงDataFrameกับ.toDF()

val rowsRdd: RDD[Row] = sc.parallelize(
  Seq(
    Row("first", 2.0, 7.0),
    Row("second", 3.5, 2.5),
    Row("third", 7.0, 5.9)
  )
)

val df = spark.createDataFrame(rowsRdd).toDF("id", "val1", "val2")

df.show()
+------+----+----+
|    id|val1|val2|
+------+----+----+
| first| 2.0| 7.0|
|second| 3.5| 2.5|
| third| 7.0| 5.9|
+------+----+----+

วิธีเพิ่มเติม: แปลงวัตถุ RDD เป็น Dataframe ใน Spark

2. DataFrame/ DataSetถึงRDDด้วย.rdd()วิธีการ

val rowsRdd: RDD[Row] = df.rdd() // DataFrame to RDD

27

เนื่องจากDataFrameพิมพ์อย่างอ่อนและผู้พัฒนาไม่ได้รับประโยชน์จากระบบพิมพ์ ตัวอย่างเช่นสมมติว่าคุณต้องการอ่านบางอย่างจาก SQL และเรียกใช้การรวมบางอย่าง:

val people = sqlContext.read.parquet("...")
val department = sqlContext.read.parquet("...")

people.filter("age > 30")
  .join(department, people("deptId") === department("id"))
  .groupBy(department("name"), "gender")
  .agg(avg(people("salary")), max(people("age")))

เมื่อคุณพูดว่าpeople("deptId")คุณไม่ได้รับคืนIntหรือLongคุณได้รับColumnวัตถุที่คุณต้องเปิดใช้งานกลับมา ในภาษาที่มีระบบที่มีรูปแบบหลากหลายเช่น Scala คุณจะสูญเสียความปลอดภัยของประเภททั้งหมดซึ่งจะเพิ่มจำนวนข้อผิดพลาดขณะทำงานสำหรับสิ่งต่าง ๆ ที่สามารถค้นพบได้ในเวลารวบรวม

ในทางตรงกันข้ามDataSet[T]พิมพ์ เมื่อคุณทำ:

val people: People = val people = sqlContext.read.parquet("...").as[People]

คุณจะได้Peopleวัตถุกลับมาซึ่งdeptIdเป็นประเภทอินทิกรัลจริงและไม่ใช่ประเภทคอลัมน์ดังนั้นจึงใช้ประโยชน์จากระบบประเภท

ในฐานะของ Spark 2.0 DataFrame และชุดข้อมูล API ที่จะรวมเป็นหนึ่งเดียวที่จะเป็นนามแฝงประเภทสำหรับDataFrameDataSet[Row]


5
เพื่อความแม่นยำสำหรับ Spark 2.0 Dataframe เป็นเพียงนามแฝงสำหรับDataset[Row]
zero323

1
@ zero323 ใช่แน่นอน แต่มันก็ยังพิมพ์ออกมาอ่อนแอนั่นคือสิ่งที่ฉันพยายามสื่อ
Yuval Itzchakov

ใช่ แต่มันเป็นเรื่องของค่าที่เก็บไว้มากกว่าคอนเทนเนอร์เอง แม้แต่ใน 1.6 ทั้งสองก็พูดเหมือนกันในทางเทคนิคและเหตุผลหลักที่ทำให้แยกต่างหากDataFrameก็คือการหลีกเลี่ยงการเปลี่ยนแปลง API อย่างไรก็ตามเพียงแค่ต้องการชี้ให้เห็น ขอบคุณสำหรับการแก้ไขและ upvote จากฉัน
zero323

25

ง่ายๆRDDคือส่วนประกอบหลัก แต่DataFrameเป็น API ที่เปิดตัวใน spark 1.30

RDD

RDDการเก็บข้อมูลของพาร์ทิชันที่เรียกว่า สิ่งเหล่านี้RDDต้องเป็นไปตามคุณสมบัติบางประการเช่น:

  • ไม่เปลี่ยนรูป
  • Fault Tolerant
  • กระจาย
  • มากกว่า.

ที่นี่RDDมีโครงสร้างหรือไม่มีโครงสร้าง

DataFrame

DataFrameเป็น API ที่มีอยู่ใน Scala, Java, Python และ R ช่วยให้สามารถประมวลผลข้อมูลที่มีโครงสร้างและกึ่งโครงสร้างได้ทุกประเภท การกําหนดการเก็บรวบรวมข้อมูลการกระจายจัดลงในคอลัมน์ชื่อเรียกว่าDataFrame DataFrameคุณสามารถเพิ่มประสิทธิภาพในRDDs DataFrameคุณสามารถประมวลผลข้อมูล JSON ข้อมูลปาร์เก้, ข้อมูล HiveQL DataFrameได้ตลอดเวลาโดยใช้

val sampleRDD = sqlContext.jsonFile("hdfs://localhost:9000/jsondata.json")

val sample_DF = sampleRDD.toDF()

นี่ Sample_DF DataFrameพิจารณาเป็น sampleRDDคือ (ข้อมูลดิบ) RDDที่เรียกว่า


12

คำตอบส่วนใหญ่นั้นถูกต้องเพียงต้องการเพิ่มจุดเดียวที่นี่

ใน Spark 2.0 APIs สองตัว (DataFrame + DataSet) จะถูกรวมเข้าด้วยกันเป็น API เดียว

"Unifying DataFrame และชุดข้อมูล: ใน Scala และ Java, DataFrame และชุดข้อมูลได้รับการรวมเป็นหนึ่งนั่นคือ DataFrame เป็นเพียงนามแฝงประเภทสำหรับชุดข้อมูลของ Row ใน Python และ R เนื่องจากขาดความปลอดภัยของประเภท DataFrame เป็นอินเตอร์เฟสโปรแกรมหลัก"

ชุดข้อมูลคล้ายกับ RDDs อย่างไรก็ตามแทนที่จะใช้ Java serialization หรือ Kryo พวกเขาใช้ Encoder พิเศษเพื่อทำให้เป็นอันดับวัตถุสำหรับการประมวลผลหรือส่งผ่านเครือข่าย

Spark SQL สนับสนุนวิธีการสองวิธีที่แตกต่างกันสำหรับการแปลง RDD ที่มีอยู่ไปเป็นชุดข้อมูล วิธีแรกใช้การสะท้อนเพื่ออนุมาน schema ของ RDD ที่มีประเภทของวัตถุที่เฉพาะเจาะจง วิธีการที่ใช้การสะท้อนนี้นำไปสู่รหัสที่กระชับมากขึ้นและทำงานได้ดีเมื่อคุณทราบสคีมาแล้วในขณะที่เขียนแอปพลิเคชัน Spark ของคุณ

วิธีที่สองสำหรับการสร้างชุดข้อมูลคือผ่านส่วนต่อประสานแบบเป็นโปรแกรมที่อนุญาตให้คุณสร้างสคีมาแล้วนำไปใช้กับ RDD ที่มีอยู่ ในขณะที่วิธีนี้เป็น verbose มากขึ้นก็ช่วยให้คุณสามารถสร้างชุดข้อมูลเมื่อคอลัมน์และประเภทของพวกเขาไม่เป็นที่รู้จักกันจนถึงรันไทม์

ที่นี่คุณสามารถค้นหาคำตอบการสนทนากรอบข้อมูล RDD ได้

วิธีการแปลงวัตถุ rdd เป็น dataframe ใน spark


8

DataFrame เทียบเท่ากับตารางใน RDBMS และสามารถจัดการในลักษณะที่คล้ายคลึงกับคอลเลกชันแบบกระจาย "ดั้งเดิม" ใน RDD ซึ่งแตกต่างจาก RDDs Dataframes ติดตาม schema และสนับสนุนการดำเนินการเชิงสัมพันธ์ที่หลากหลายซึ่งนำไปสู่การดำเนินการที่เหมาะสมที่สุด แต่ละ DataFrame วัตถุแสดงถึงแผนลอจิคัล แต่เนื่องจากลักษณะ "สันหลังยาว" ของพวกเขาไม่มีการดำเนินการเกิดขึ้นจนกว่าผู้ใช้เรียก "การดำเนินงานเอาท์พุท" ที่เฉพาะเจาะจง


2
RDDs ยังขี้เกียจโดยวิธี
kon Psych

6

ข้อมูลเชิงลึกบางประการจากมุมมองการใช้งาน RDD vs DataFrame

  1. RDD นั้นน่าทึ่งมาก! เนื่องจากมันให้ความยืดหยุ่นแก่เราในการจัดการกับข้อมูลเกือบทุกชนิด ข้อมูลที่ไม่มีโครงสร้างกึ่งโครงสร้างและมีโครงสร้าง เนื่องจากหลายครั้งที่ข้อมูลไม่พร้อมที่จะใส่ลงใน DataFrame (แม้แต่ JSON) สามารถใช้ RDD เพื่อทำการประมวลผลข้อมูลล่วงหน้าเพื่อให้สามารถใส่ใน dataframe ได้ RDDs เป็นข้อมูลหลักที่เป็นนามธรรมใน Spark
  2. การแปลงไม่ทั้งหมดที่เป็นไปได้บน RDD เป็นไปได้ใน DataFrames ตัวอย่างการลบ () สำหรับ RDD vs ยกเว้น () สำหรับ DataFrame
  3. เนื่องจาก DataFrames เป็นเหมือนตารางที่สัมพันธ์กันพวกเขาจึงปฏิบัติตามกฎที่เข้มงวดเมื่อใช้การแปลงชุด / ทฤษฎีเชิงสัมพันธ์ตัวอย่างเช่นหากคุณต้องการรวมสอง dataframes ความต้องการคือ dfs ทั้งสองมีจำนวนคอลัมน์และคอลัมน์ข้อมูลที่เชื่อมโยงกัน ชื่อคอลัมน์อาจแตกต่างกัน กฎเหล่านี้ใช้ไม่ได้กับ RDD นี่คือแบบฝึกหัดที่ดีที่อธิบายข้อเท็จจริงเหล่านี้
  4. มีประสิทธิภาพเพิ่มขึ้นเมื่อใช้ DataFrames เหมือนที่คนอื่นได้อธิบายไปแล้วในเชิงลึก
  5. การใช้ DataFrames คุณไม่จำเป็นต้องผ่านฟังก์ชั่นตามอำเภอใจเช่นเดียวกับการเขียนโปรแกรมด้วย RDD
  6. คุณต้องใช้ SQLContext / HiveContext เพื่อเขียนโปรแกรม dataframes เนื่องจากอยู่ในพื้นที่ SparkSQL ของระบบ eco spark แต่สำหรับ RDD คุณต้องใช้ SparkContext / JavaSparkContext ซึ่งอยู่ในไลบรารี Spark Core เท่านั้น
  7. คุณสามารถสร้าง df จาก RDD หากคุณสามารถกำหนดสคีมาได้
  8. คุณยังสามารถแปลง df เป็น rdd และ rdd เป็น df

ฉันหวังว่ามันจะช่วย!


5

Dataframe เป็นวัตถุ RDD ของแถวซึ่งแต่ละอันแทนระเบียน Dataframe ยังรู้ schema (เช่นเขตข้อมูล) ของแถว ในขณะที่ Dataframes ดูเหมือน RDD ปกติ แต่ภายในจะเก็บข้อมูลในลักษณะที่มีประสิทธิภาพมากกว่าโดยใช้ประโยชน์จากสคีมาของพวกเขา นอกจากนี้ยังมีการดำเนินการใหม่ที่ไม่พร้อมใช้งานบน RDD เช่นความสามารถในการเรียกใช้แบบสอบถาม SQL Dataframes สามารถสร้างขึ้นได้จากแหล่งข้อมูลภายนอกจากผลลัพธ์ของการสืบค้นหรือจาก RDD ปกติ

การอ้างอิง: Zaharia M. , et al. Learning Spark (O'Reilly, 2015)


1

Spark RDD (resilient distributed dataset) :

RDD เป็น API ข้อมูลนามธรรมหลักและมีให้บริการตั้งแต่รุ่น Spark แรก (Spark 1.0) เป็น API ระดับต่ำกว่าสำหรับจัดการการรวบรวมข้อมูลแบบกระจาย RDD APIs แสดงวิธีการที่มีประโยชน์อย่างยิ่งซึ่งสามารถนำมาใช้เพื่อควบคุมโครงสร้างข้อมูลทางกายภาพพื้นฐานอย่างเข้มงวด มันคือการรวบรวมข้อมูลที่แบ่งพาร์ติชันแบบไม่กระจาย (อ่านอย่างเดียว) บนเครื่องต่างๆ RDD ช่วยให้การคำนวณในหน่วยความจำบนคลัสเตอร์ขนาดใหญ่เพื่อเพิ่มความเร็วในการประมวลผลข้อมูลขนาดใหญ่ในลักษณะที่ทนต่อความผิดพลาด เพื่อเปิดใช้งานการยอมรับข้อบกพร่อง RDD ใช้ DAG (กราฟ Directed Acyclic) ซึ่งประกอบด้วยชุดจุดยอดและขอบ จุดยอดและขอบใน DAG แสดงถึง RDD และการดำเนินการที่จะใช้กับ RDD นั้นตามลำดับ การแปลงที่กำหนดไว้ใน RDD ขี้เกียจและดำเนินการเฉพาะเมื่อมีการกระทำที่เรียกว่า

Spark DataFrame :

Spark 1.3 แนะนำ Abstraction API ใหม่สองตัวคือ DataFrame และ DataSet DataFrame APIs จัดระเบียบข้อมูลลงในคอลัมน์ที่มีชื่อเหมือนตารางในฐานข้อมูลเชิงสัมพันธ์ ช่วยให้โปรแกรมเมอร์กำหนดสคีมาในการรวบรวมข้อมูลแบบกระจาย แต่ละแถวใน DataFrame เป็นแถวประเภทวัตถุ เช่นเดียวกับตาราง SQL แต่ละคอลัมน์ต้องมีจำนวนแถวเท่ากันใน DataFrame ในระยะสั้น DataFrame คือการประเมินแผนอย่างเกียจคร้านซึ่งระบุการดำเนินงานที่ต้องดำเนินการในการรวบรวมข้อมูลแบบกระจาย DataFrame ยังเป็นคอลเลกชันที่ไม่เปลี่ยนรูป

Spark DataSet :

ในฐานะที่เป็นส่วนขยายของ DataFrame APIs Spark 1.3 ยังได้เปิดตัวชุดข้อมูล API ซึ่งให้บริการการเขียนโปรแกรมและการเขียนโปรแกรมเชิงวัตถุใน Spark มันคือการรวบรวมข้อมูลแบบกระจายที่ไม่เปลี่ยนรูปแบบและปลอดภัย เช่นเดียวกับ DataFrame ชุดข้อมูล API ยังใช้เอ็นจิ้น Catalyst เพื่อเปิดใช้งานการเพิ่มประสิทธิภาพการดำเนินการ ชุดข้อมูลเป็นส่วนขยายของ DataFrame API

Other Differences -

ป้อนคำอธิบายรูปภาพที่นี่


0

DataFrameเป็น RDD ที่มีสคีมา คุณสามารถคิดว่ามันเป็นตารางฐานข้อมูลเชิงสัมพันธ์ในแต่ละคอลัมน์มีชื่อและประเภทที่รู้จัก พลังของDataFramesมาจากข้อเท็จจริงที่ว่าเมื่อคุณสร้าง DataFrame จากชุดข้อมูลที่มีโครงสร้าง (Json, Parquet .. ) Spark สามารถสรุปโครงสร้างได้โดยการส่งผ่านชุดข้อมูล (Json, Parquet .. ) ทั้งหมด กำลังโหลด จากนั้นเมื่อคำนวณแผนการดำเนินการ Spark สามารถใช้สคีมาและทำการเพิ่มประสิทธิภาพการคำนวณที่ดีขึ้นอย่างมีนัยสำคัญ โปรดทราบว่าDataFrameถูกเรียกว่า SchemaRDD ก่อน Spark v1.3.0


0

Apache Spark - RDD, DataFrame และชุดข้อมูล

Spark RDD -

RDD ย่อมาจากชุดข้อมูลที่กระจายความยืดหยุ่น มันคือการรวบรวมบันทึกพาร์ติชันแบบอ่านอย่างเดียว RDD เป็นโครงสร้างข้อมูลพื้นฐานของ Spark จะช่วยให้โปรแกรมเมอร์ทำการคำนวณในหน่วยความจำในกลุ่มขนาดใหญ่ในลักษณะที่ทนต่อความผิดพลาด ดังนั้นเร่งงาน

Spark Dataframe -

ไม่เหมือนกับ RDD ข้อมูลถูกจัดระเบียบในคอลัมน์ที่มีชื่อ ตัวอย่างเช่นตารางในฐานข้อมูลเชิงสัมพันธ์ เป็นการรวบรวมข้อมูลที่ไม่เปลี่ยนรูปแบบ DataFrame in Spark ช่วยให้นักพัฒนาสามารถกำหนดโครงสร้างลงในการรวบรวมข้อมูลแบบกระจายซึ่งช่วยให้เกิดนามธรรมในระดับที่สูงขึ้น

ชุดข้อมูล Spark -

ชุดข้อมูลใน Apache Spark เป็นส่วนเสริมของ DataFrame API ซึ่งมีอินเตอร์เฟสการเขียนโปรแกรมเชิงวัตถุ ชุดข้อมูลใช้ประโยชน์จากเครื่องมือเพิ่มประสิทธิภาพ Catalyst ของ Spark โดยการเปิดเผยนิพจน์และเขตข้อมูลไปยังตัววางแผนคิวรี


-1

คุณสามารถใช้ RDD กับโครงสร้างและไม่มีโครงสร้างที่เป็น Dataframe / ชุดข้อมูลสามารถประมวลผลข้อมูลที่มีโครงสร้างและกึ่งโครงสร้าง (มันมีสคีมาที่เหมาะสม)


-2

คำตอบที่ยอดเยี่ยมและการใช้ API แต่ละข้อนั้นดีพอสมควร ชุดข้อมูลถูกสร้างขึ้นเพื่อเป็น super API เพื่อแก้ปัญหาจำนวนมาก แต่หลายครั้ง RDD ยังคงทำงานได้ดีที่สุดถ้าคุณเข้าใจข้อมูลของคุณและหากอัลกอริทึมการประมวลผลได้รับการปรับให้เหมาะสมในการทำสิ่งต่างๆมากมายใน Single pass

การรวบรวมโดยใช้ชุดข้อมูล API ยังคงใช้หน่วยความจำและจะดีขึ้นเมื่อเวลาผ่านไป

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.