首页 > 其他分享 >0639-6.1.1-Spark读取由Impala创建的Parquet文件异常分析

0639-6.1.1-Spark读取由Impala创建的Parquet文件异常分析

时间:2022-10-04 12:03:31浏览次数:83  
标签:Parquet 6.1 parquet test Spark Impala spark

作者:冉南阳


1

问题重现


  • 测试环境:

1.RedHat7.4

2.CDH6.1.1

3.使用root进行操作


1.使用Impala创建Parquet表并插入数据。


create table test_parquet(id int,name string) stored as parquet;
insert into test_parquet values(1,'test'),(2,'vivi');


0639-6.1.1-Spark读取由Impala创建的Parquet文件异常分析_sql


2.使用Impala查看数据,数据显示正常。


select * from test_parquet;


0639-6.1.1-Spark读取由Impala创建的Parquet文件异常分析_spark_02


3.使用CDH6.1.1中的Spark2.4访问该数据文件。


val df=spark.read.parquet("hdfs://ip-172-31-6-83.ap-southeast-1.compute.internal:8020/user/hive/warehouse/test_parquet")
df.show()


0639-6.1.1-Spark读取由Impala创建的Parquet文件异常分析_spark_03


发现name这个字段string类型显示异常,问题重现。


2

问题分析


1.直接在Spark CLI分析一下该Parquet文件的schema。


df.printSchema()


0639-6.1.1-Spark读取由Impala创建的Parquet文件异常分析_sql_04


应该为String,实际为二进制binary。


2.通过CDH提供的parquet tool进行分析,参考《​​0631-6.2-如何确认一个Parquet文件是否被压缩​​》。


hadoop fs -ls /user/hive/warehouse/test_parquet
hadoop fs -get /user/hive/warehouse/test_parquet/8644d8aba29fa4cf-a9a89e1900000000_325265083_data.0.parq .
/opt/cloudera/parcels/CDH/lib/parquet/bin/parquet-tools schema -d 8644d8aba29fa4cf-a9a89e1900000000_325265083_data.0.parq


0639-6.1.1-Spark读取由Impala创建的Parquet文件异常分析_sql_05


可以发现应该为String,实际为二进制binary。


这是因为Hive/Impala与Spark在Parquet的实现上不一致,Hive/Impala将string类型在Parquet文件中保存为二进制binary,它们查询的时候再进行解析。但Spark的代码查询的时候却没有这样做,而是直接将二进制值查询并展现出来,所以Spark中有一个参数spark.sql.parquet.binaryAsString,默认为false,解释如下:



由其他系统生成的Parquet文件,特别是Impala,Hive和旧版本的Spark SQL,在写Parquet文件的schema时候不区分字符串和二进制。这个参数是告诉Spark SQL将二进制数据解释为字符串,从而保证Spark与其他系统比如Hive或Impala的兼容性。



参考:

​https://spark.apache.org/docs/latest/sql-data-sources-parquet.html#configuration​


3

问题解决


3.1

方法1


直接采用Spark SQL来读取,而不是Spark代码来读取Parquet文件。

1.使用以下语句直接读取Impala创建的这张表的数据。


spark.sql("select * from test_parquet").show()


0639-6.1.1-Spark读取由Impala创建的Parquet文件异常分析_sql_06


发现name字段查询显示正常。


3.2

方法2


通过Spark读取Parquet文件时定义schema


1.首先在Spark Shell中定义schema


import org.apache.spark.sql.types._
val columnsList=List(
| StructField("id",IntegerType),
| StructField("name",StringType))
val testScheme=StructType(columnsList)


0639-6.1.1-Spark读取由Impala创建的Parquet文件异常分析_spark_07


2.使用该schema再去读取之前的Parquet文件。


val df=spark.read.schema(testScheme).parquet("hdfs://ip-172-31-6-83.ap-southeast-1.compute.internal:8020/user/hive/warehouse/test_parquet")
df.show()


0639-6.1.1-Spark读取由Impala创建的Parquet文件异常分析_hive_08


显示正常,问题解决。



3.3

方法3


启动spark-shell的时候带上启动参数

1.使用以下参数重新启动spark-shell


spark-shell --conf spark.sql.parquet.binaryAsString=true


0639-6.1.1-Spark读取由Impala创建的Parquet文件异常分析_spark_09


2.再次用同样的代码读取之前的Parquet文件。


val df=spark.read.parquet("hdfs://ip-172-31-6-83.ap-southeast-1.compute.internal:8020/user/hive/warehouse/test_parquet")
df.show()


0639-6.1.1-Spark读取由Impala创建的Parquet文件异常分析_hive_10


显示正常,问题解决。


4

问题总结


1.使用Impala创建的Parquet文件,如果包含字符串类型,由Spark代码直接读取该Parquet文件时会显示异常,将字符串的值显示为二进制binary。


2.主要原因是因为由其他系统生成的Parquet文件,特别是Impala,Hive和旧版本的Spark SQL,在写Parquet文件的schema时候不区分字符串和二进制。所以Spark提供了一个参数spark.sql.parquet.binaryAsString来解决该问题,参考:

​https://spark.apache.org/docs/latest/sql-data-sources-parquet.html#configuration​


3.对于该问题的解决方案有三种,具体可以参考第三个章节:

    a)直接采用Spark SQL来读取,而不是Spark代码来读取Parquet文件。

    b)通过Spark读取Parquet文件时定义schema

    c)启动spark-shell的时候带上启动参数

    

标签:Parquet,6.1,parquet,test,Spark,Impala,spark
From: https://blog.51cto.com/u_14049791/5731168

相关文章

  • 0637-5.16.1-CDH集群中var目录占用空间大问题分析
    作者:唐辉1文档编写目的Fayson今天在观察集群的时候,发现CM节点/var目录使用空间异常的大,使用率达到93%,为防止目录空间使用满,导致CM界面告警。于是对该目录进行详细分析测试......
  • 0565-6.1.0-NFS异常导致Host Monitor及Agent服务错误
    温馨提示:如果使用电脑查看图片不清晰,可以使用手机打开文章单击文中的图片放大查看高清原图。Fayson的github:​​https://github.com/fayson/cdhproject​​提示:代码块部分可......
  • 0555-6.1.0-使用Python并发访问认证和非认证集群
    作者:李继武1文档编写目的Fayson在前面的文章《​​0553-6.1.0-如何使用Java代码同时访问安全和非安全CDH集群​​》和《​​0554-6.1.0-同一java进程中同时访问认证和非认证......
  • 0530-6.1-如何只是迁移NameNode或JournalNode
    温馨提示:如果使用电脑查看图片不清晰,可以使用手机打开文章单击文中的图片放大查看高清原图。Fayson的github:​​https://github.com/fayson/cdhproject​​提示:代码块部分可......
  • 0805-CDH5中的Parquet迁移至CDP中兼容性验证
    文档编写目的因为CDH5中的Parquet版本为1.5,而CDP7中的Parquet版本为1.10,我们在从CDH5升级到CDP7后,无论是原地升级还是迁移升级,都可能会碰到一个问题,以前在CDH5中使用Hive/Im......
  • (4)SparkSQL中如何定义UDF和使用UDF
    SparkSQL中用户自定义函数,用法和SparkSQL中的内置函数类似;是saprkSQL中内置函数无法满足要求,用户根据业务需求自定义的函数。首先定义一个UDF函数:packagecom.udf;import......
  • Spark:RDD
    概念与特性RDD(ResilientDistributedDataset)弹性分布式数据集,是Spark中最基本的数据处理模型。弹性存储:内存和磁盘的自动切换容错:数据丢失可以自动恢复计算:计算......
  • spark知识点
                             ......
  • pyspark rdd转json字符串
    +--------+--------------------+|objectid|$geometry|+--------+--------------------+|5|[106.366970696000...|+--------+--------------------+......
  • Apache Spark源码剖析 pdf
    高清扫描版下载链接:https://pan.baidu.com/s/1ho509WqYxsS6twPUD2tyiw点击这里获取提取码 ......