我已在配置单元中使用 saveAsTable
方法,现在当我尝试使用cli命令访问配置单元表数据时 select * from table_name
,它给了我下面的错误:
2016-06-15 10:49:36,866 WARN [HiveServer2-Handler-Pool: Thread-96]:
thrift.ThriftCLIService (ThriftCLIService.java:FetchResults(681)) -
Error fetching results: org.apache.hive.service.cli.HiveSQLException:
java.io.IOException: parquet.io.ParquetDecodingException: Can not read
value at 0 in block -1 in file hdfs:
知道我做错什么了吗?
6条答案
按热度按时间gmxoilav1#
我有一个类似的错误,在我的例子中,我丢失了默认的构造函数
bksxznpy2#
捕捉可能的差异的另一种方法是观察由两个源(比如hive和spark)生成的Parquet文件的模式差异。可以使用Parquet工具转储模式(
brew install parquet-tools
对于macos):b4wnujal3#
这里看起来像是架构不匹配的问题。如果您将模式设置为不可为null,并且创建的Dataframe没有值,spark会抛出valueerror:此字段不可为null,但没有错误。
[皮斯帕克]
但如果你使用自定义项就不是这样了。
使用相同的模式,如果使用udf进行转换,即使udf返回none,也不会抛出valueerror。它是发生数据模式不匹配的地方。
例如:
然后,下面的parquet write and read将抛出parquet.io.parquetdecodingexception错误。
因此,如果您使用的是自定义项,请务必小心空值,并在自定义项中返回正确的数据类型。除非没有必要,请不要在structfield中设置nullable=false。设置nullable=true将解决所有问题。
baubqpgj4#
你能用avro代替Parquet地板来存放你的Hive桌吗?我遇到这个问题是因为我使用的是hive的decimal数据类型,而spark的parquet不能很好地处理decimal。如果发布表架构和一些数据示例,调试将更容易。
另一个可能的选择,来自databricks论坛,是使用double而不是decimal,但这不是我的数据的一个选项,所以我不能报告它是否有效。
gojuced75#
问题:在查询impyla(spark job编写的数据)中的数据时遇到以下问题
根本原因:
这个问题是由于Hive和Spark中使用不同的Parquet约定造成的。在配置单元中,十进制数据类型表示为固定字节(int 32)。在spark 1.4或更高版本中,默认约定是使用十进制数据类型的标准Parquet表示法。根据基于列数据类型精度的标准parquet表示,底层表示会发生变化。
例如:decimal可用于注解以下类型:int32:for 1<=precision<=9 int64:for 1<=precision<=18;精度<10将产生警告
因此,只有在使用在不同的Parquet约定中具有不同表示的数据类型时,才会出现此问题。如果数据类型是decimal(10,3),那么两个约定都将其表示为int32,因此我们不会遇到问题。如果您不知道数据类型的内部表示形式,则可以安全地使用与读取时写入相同的约定。使用Hive,您没有选择Parquet约定的灵活性。但有了Spark,你就知道了。
解决方案:spark用于写入Parquet数据的约定是可配置的。这由属性spark.sql.parquet.writelegacyformat确定,默认值为false。如果设置为“true”,spark将使用与hive相同的约定来写入Parquet数据。这将有助于解决这个问题。
参考文献:
语言手册类型小数位数小数位数
Spark-20937
issues@spark.apache.org
mxg2im7a6#
我也有一个类似的错误(但在非负块中的正索引处),这是因为我创建了带有一些sparkDataframe类型的parquet数据,这些类型在实际为null时被标记为不可为null。
因此,在我的例子中,我将错误解释为spark试图从某个不可为null的类型读取数据,并遇到意外的null值。
更让人困惑的是,在阅读了Parquet文件之后,spark用
printSchema()
所有字段都可以为空,不管它们是否为空。但是,在我的例子中,使它们在原始的parquet文件中真正可为null就解决了这个问题。现在,这个问题发生在“block-1中的0”这一事实是可疑的:实际上看起来几乎没有找到数据,因为block-1看起来spark甚至没有开始读取任何内容(只是一个猜测)。