Mic*_*sen 5 scala apache-spark apache-spark-sql
我正在开发一个自定义的Spark数据源,并希望模式包含一行原始字节数组类型.
我的问题是结果字节数组中的字节被装箱:输出然后有类型WrappedArray$ofRef.这意味着每个字节都表示为java.lang.Object.虽然我可以解决这个问题,但我担心的是计算和内存开销,这对我的应用程序至关重要.我真的只想要原始数组!
下面是一个演示此行为的最小示例.
class DefaultSource extends SchemaRelationProvider with DataSourceRegister {
override def shortName(): String = "..."
override def createRelation(
sqlContext: SQLContext,
parameters: Map[String, String],
schema: StructType = new StructType()
): BaseRelation = {
new DefaultRelation(sqlContext)
}
}
class DefaultRelation(val sqlContext: SQLContext) extends BaseRelation with PrunedFilteredScan {
override def schema = {
StructType(
Array(
StructField("key", ArrayType(ByteType))
)
)
}
override def buildScan(
requiredColumnNames: Array[String],
filterArr: Array[Filter]
): RDD[Row] = {
testRDD
}
def testRDD = sqlContext.sparkContext.parallelize(
List(
Row(
Array[Byte](1)
)
)
)
}
Run Code Online (Sandbox Code Playgroud)
使用此示例数据源如下:
def schema = StructType(Array(StructField("key", ArrayType(ByteType))))
val rows = sqlContext
.read
.schema(schema)
.format("testdatasource")
.load
.collect()
println(rows(0)(0).getClass)
Run Code Online (Sandbox Code Playgroud)
然后生成以下输出:
class scala.collection.mutable.WrappedArray$ofRef
Run Code Online (Sandbox Code Playgroud)
在调试器中进一步检查结果类型确认WrappedArray中的字节确实是盒装的 - 并且由于某种原因,它们的类型一直被擦除java.lang.Object(而不是到java.lang.Byte).
请注意,直接使用RDD而不通过数据源API会导致原始字节数组的预期结果.
任何关于如何解决这个问题的建议将不胜感激.
好吧,对于原始字节数组,我应该使用BinaryType而不是Array(Byte)列类型.这解决了这个问题.
出于好奇,如果我们改变ArrayType(ByteType)到例如ArrayType(LongType)上面的例子中,我们实际上得到一个运行时异常,表明期望盒装长.因此,似乎Spark SQL数组中的原语总是被装箱.
| 归档时间: |
|
| 查看次数: |
698 次 |
| 最近记录: |