spark数据集中的kryo编码器v.s.rowencoder

vqlkdk9b  于 2021-05-24  发布在  Spark
关注(0)|答案(2)|浏览(732)

以下示例的目的是了解spark数据集中两个编码器的区别。
我可以做到:

  1. val df = Seq((1, "a"), (2, "d")).toDF("id", "value")
  2. import org.apache.spark.sql.{Encoder, Encoders, Row}
  3. import org.apache.spark.sql.catalyst.encoders.RowEncoder
  4. import org.apache.spark.sql.types._
  5. val myStructType = StructType(Seq(StructField("id", IntegerType), StructField("value", StringType)))
  6. implicit val myRowEncoder = RowEncoder(myStructType)
  7. val ds = df.map{case row => row}
  8. ds.show
  9. //+---+-----+
  10. //| id|value|
  11. //+---+-----+
  12. //| 1| a|
  13. //| 2| d|
  14. //+---+-----+

我也可以这样做:

  1. val df = Seq((1, "a"), (2, "d")).toDF("id", "value")
  2. import org.apache.spark.sql.{Encoder, Encoders, Row}
  3. import org.apache.spark.sql.catalyst.encoders.RowEncoder
  4. import org.apache.spark.sql.types._
  5. implicit val myKryoEncoder: Encoder[Row] = Encoders.kryo[Row]
  6. val ds = df.map{case row => row}
  7. ds.show
  8. //+--------------------+
  9. //| value|
  10. //+--------------------+
  11. //|[01 00 6F 72 67 2...|
  12. //|[01 00 6F 72 67 2...|
  13. //+--------------------+

代码的唯一区别是:一个使用kryo编码器,另一个使用rowcoder。
问题:
使用两者有什么区别?
为什么一个显示编码值,另一个显示可读值?
我们应该什么时候用哪个?

mqxuamgl

mqxuamgl1#

根据spark的文档,sparksql不使用kryo或java序列化(标准)。
kyro用于RDD,而不是Dataframe或数据集。因此问题有点离题了。
kryo对sparksql有帮助吗?这详细说明了自定义对象,但是。。。
空闲时间后更新答案
你的例子并不是我所说的定制类型。它们只是带原语的结构。没问题。
kyro是一个序列化程序,ds,df的使用编码器对列的优势。kyro由spark内部用于洗牌。
此用户定义的示例 case class Foo(name: String, position: Point) 我们可以通过ds或df或kyro来实现。但是钨和催化剂“理解数据结构”有什么意义呢?从而能够优化。使用kyro还可以得到一个二进制值,我发现了一些如何成功使用它的示例,例如join。
kyro示例

  1. import org.apache.spark.sql.{Encoder, Encoders, SQLContext}
  2. import org.apache.spark.{SparkConf, SparkContext}
  3. import spark.implicits._
  4. case class Point(a: Int, b: Int)
  5. case class Foo(name: String, position: Point)
  6. implicit val PointEncoder: Encoder[Point] = Encoders.kryo[Point]
  7. implicit val FooEncoder: Encoder[Foo] = Encoders.kryo[Foo]
  8. val ds = Seq(new Foo("bar", new Point(0, 0))).toDS
  9. ds.show()

退货:

  1. +--------------------+
  2. | value|
  3. +--------------------+
  4. |[01 00 D2 02 6C 6...|
  5. +--------------------+

使用case类示例的ds编码器

  1. import org.apache.spark.sql.{Encoder, Encoders, SQLContext}
  2. import org.apache.spark.{SparkConf, SparkContext}
  3. import spark.implicits._
  4. case class Point(a: Int, b: Int)
  5. case class Foo(name: String, position: Point)
  6. val ds = Seq(new Foo("bar", new Point(0, 0))).toDS
  7. ds.show()

退货:

  1. +----+--------+
  2. |name|position|
  3. +----+--------+
  4. | bar| [0, 0]|
  5. +----+--------+

这给我的印象是Spark,钨,催化剂。
现在,更复杂的事情是当涉及到any时,但是any不是一件好事:

  1. val data = Seq(
  2. ("sublime", Map(
  3. "good_song" -> "santeria",
  4. "bad_song" -> "doesn't exist")
  5. ),
  6. ("prince_royce", Map(
  7. "good_song" -> 4,
  8. "bad_song" -> "back it up")
  9. )
  10. )
  11. val schema = List(
  12. ("name", StringType, true),
  13. ("songs", MapType(StringType, StringType, true), true)
  14. )
  15. val rdd= spark.sparkContext.parallelize(data)
  16. rdd.collect
  17. val df = spark.createDataFrame(rdd)
  18. df.show()
  19. df.printSchema()

退货:

  1. Java.lang.UnsupportedOperationException: No Encoder found for Any.

然后这个例子很有趣,它是一个有效的自定义对象用例,在map[string,java.io.serializable]中找不到java.io.serializable的编码器。但我会远离这些。
结论
kryo vs编码器vs spark中的java序列化?声明kyro代表rdd,但代表legacy;我们可以在内部使用它。不是百分之百正确,而是切中要害。
spark:数据集序列化也是一个信息链接。
东西已经进化了,精神就是不要用kyro来做ds,df。
希望这有帮助。

展开查看全部
v1uwarro

v1uwarro2#

kryo只创建一个编码器,使用kryo序列化t类型的对象
rowencoder是scala中的一个对象,具有apply和其他工厂方法。rowencoder可以从架构创建expressionencoder[row]。在内部,apply为行类型创建一个boundreference,并为输入模式返回expressionencoder[row]、createnamedstruct序列化程序(使用serializer或内部方法)、模式的反序列化程序和行类型
rowencoder了解模式并将其用于序列化和反序列化。
kryo比java序列化要快得多,而且更紧凑(通常高达10x),但并不支持所有可序列化的类型,需要您预先注册要在程序中使用的类以获得最佳性能。
kryo适用于高效存储大型数据集和网络密集型应用。
有关更多信息,请参阅以下链接:
https://jaceklaskowski.gitbooks.io/mastering-spark-sql/content/spark-sql-rowencoder.htmlhttpshttp://jaceklaskowski.gitbooks.io/mastering-spark-sql/content/spark-sql-encoders。htmlhttps://medium.com/@knoldus/kryo-系列化-in-spark-55b53667e7abhttps://stackoverflow.com/questions/58946987/what-are-the-pros-and-cons-of-java-serialization-vs-kryo-serialization#::~:text=kryo%20比%20快了%20,在%20提前%20,性能最好%20。

相关问题