Demo-查询不一致(持续更新)
- 1.hive和spark查询不一致(parquet版本问题)
- 2.impala查询和spark不一致(json表支持问题)
- 3.spark和impala执行不一致的问题(函数使用姿势有区别)
- 4. 修改字段查询null(参数问题)
- 5.spark和impala查询不一致(函数原理不同)
- 6.spark和impala查询不一致(spark有隐式转换)
- 7.spark和impala查询不一致(实现方式不一样)
- 8.spark离线开发查询没有数据,自助分析有数据(spark版本差异)
- 9.spark自助分析可以运行,hive自助分析报错格式问题(sparksql于hive有语法差异)
- 10.Hive select有数据但是select count(*) 的结果不对
- 11.spark3写入数据,spark查询正常,hive引擎查询无数据
- 12.spark3查询count(1)数据对不上
1.hive和spark查询不一致(parquet版本问题)
org.apache.parquet.io.ParquetDecodingException: Can not read value at 0 in block -1 in file xxx
spark产出的数据hive查询异常报错Can not read value at 0 in block -1 in file xxx
hive查询:
spark查询:
解决方式:spark产出数据时添加参数conf spark.sql.parquet.writeLegacyFormat=true
原因:
设置为true时,数据会以Spark1.4和更早的版本的格式写入。比如decimal类型的值会被以Apache Parquet的fixed-length byte array格式写出,该格式是其他系统例如Hive、Impala等使用的。
设置为false时,会使用parquet的新版格式。例如,decimals会以int-based格式写出。如果Spark SQL要以Parquet输出并且结果会被不支持新格式的其他系统使用的话,需要设置为true。
2.impala查询和spark不一致(json表支持问题)
用户业务sql使用impala和spark查询的数据量不一致,impala数据多
解决方式:暂时以spark查询的结果为准。
spark查询:
impala查询:
原因:
表为json表
ROW FORMAT SERDE
'org.openx.data.jsonserde.JsonSerDe'
社区impala目前是不支持读,开发怀疑有bug,目前建议等社区JSON表功能,先用spark读。
3.spark和impala执行不一致的问题(函数使用姿势有区别)
impala:
spark:
原因:
如报错,spark的isnull函数不允许传两个参数。也咨询了spark开发,isnull 只接收一个参数,这里同一个函数,impala和spark有区别,会对用户造成困扰。类似的函数使用姿势不同的问题。希望能有一个说明手册,方便用户使用。
4. 修改字段查询null(参数问题)
直接使用alter table对hive表修改字段名称,修改后hive和spark和impala均为null
原因:
hive和spark和impala均是按列名查parquet文件,修改列名后目前查询均为null解决方式如下
hive查询解决方式
执行ALTER TABLE dwd.dwd_bixin_trade_sviporder_di_123 SET TBLPROPERTIES ('parquet.column.index.access'='true');或者set parquet.column.index.access = true可正常查询,希望可以配置默认该参数为true),目前内部环境该配置应该都没有默认true。
spark解决方式:
与hive类似
spark.sql.hive.convertMetastoreParquet=false
parquet.column.access.index=true
如果设置了 spark.sql.hive.convertMetastoreParquet=false,那就跟 Hive 行为相同;否则忽略这个参数
impala解决方式
目前集群查询parquet配置默认都是name
如需解决这种情况,需要手动在代码前set PARQUET_FALLBACK_SCHEMA_RESOLUTION = position 但该种情况如果是增删列,且不是最后一列,由于查询按position位置,会导致错位。
5.spark和impala查询不一致(函数原理不同)
spark正常
impala乱码
原因:
impala的substr切割得以3个字符为单位,每3个byte是一个中文字符【impala一个中文 3个字符单位】
这里和spark有区别。用户在查询时不会直接清楚怎么去规避这个问题。
6.spark和impala查询不一致(spark有隐式转换)
spark正常
impala无数据
原因:
这是由于datesub类的时间函数和本身过滤的分区条件例如ds的类型不同。我们需要cast成一样的类型。
例如datesub这种时间函数,返回的都是datetime类型的字段,这里表的分区字段ds的字段类型是string。在spark中可能会做隐式转换并去过滤数,在impala中不会这样。所以需要将datesub返回的dateatime强转为string。结果才能保持一致。很多类似的问题都是这个原因。
7.spark和impala查询不一致(实现方式不一样)
该函数用法:
impala正常:
spark获取为null
提取的url如下
原因:这是因为spark和impala内部实现逻辑不一样,Spark 是调用 java.net.URI。java方法判断url中带{}的是非法的url。所以这个函数分析不出对应的字段。而impala的函数底层逻辑是C++实现的。支持识别这种url。
结论:如果数据格式一定是这样,可以使用impala引擎,或者通过自己写udf的形式,使用spark实现。
8.spark离线开发查询没有数据,自助分析有数据(spark版本差异)
离线开发:
自助分析:
原因:spark3修改了日期类型的隐式转换规则,spark里的日期和字符串比较会转换成日期和日期比较,spark2里的日期和字符串比较会转换成字符串和字符串比较。
结论:如果是离线开发spark2运行,会直接比较字符串,那么直接比较后,数据可能会过滤不到,造成没有结果的问题。需要自行截断字符串处理。
9.spark自助分析可以运行,hive自助分析报错格式问题(sparksql于hive有语法差异)
如图,hive无法运行。自助分析spark可以运行。
原因:
sparksql和hive的语法不一样,hive不支持on子句中用or
10.Hive select有数据但是select count(*) 的结果不对
添加参数:set hive.compute.query.using.stats=false;
11.spark3写入数据,spark查询正常,hive引擎查询无数据
表分区字段为timestamp类型,hive string 转timestamp需强制转换,无法隐式转换。推荐用户修改表分区字段类型到string类型即可
12.spark3查询count(1)数据对不上
spark查询得到8w条数据
hive和impala查询出来有35w条数据
说明spark查询有出入,查看spark查询日志发现,实际读到的只有8w条数据
但是count(1)去重后有35w条数据,怀疑可能是有文件损坏
社区官网(https://spark.apache.org/docs/latest/configuration.html)
set spark.sql.files.ignoreCorruptFiles=false;
提供参数在本地进行查询显示了具体报错
具体原因:
由于升级到Spark 3.0+版本,读取Parquet INT96文件时可能会出现日期和时间戳转换的问题。具体来说,警告指出在读取日期早于1582年10月15日或时间戳早于1900年1月1日的数据时,由于Spark 3.0+使用了新的Proleptic Gregorian历法,与Spark 2.x或旧版Hive使用的历法不同,可能导致结果的差异性。
解决方法:
set spark.sql.parquet.int96RebaseModeInRead =LEGACY
增加参数后问题解决。
作者:刘思伟
以上内容对您是否有帮助?