背景故事

先看报错信息:
mismatched input ‘-’ expecting ‘:’
在这里插入图片描述
报错的意思就是说,在这个表里面,字段名中存在特殊符号“-”,无法解析报错。
这个问题会发生在CDHspark中。如果不是CDHspark版本的程序,可以跳过此文章

解决方案:

不要使用CDH版本的spark就好了。比如我这里出现报错的时候,使用的版本是2.4.0-cdh6.1.1 那么把这个版本修改为2.4.0就好了。

过程分析

过程早就分析完了,下面写一篇结果:

环境版本
  • spark-sql_2.11
    2.4.0-cdh6.1.1
  • spark-hive_2.11
    2.4.0-cdh6.1.1

测试数据准备

        SparkSession spark = SparkSession.builder().master("local").getOrCreate();
        ArrayList<Row> rows = new ArrayList<>();
        for (int i = 0; i < 4; i++) {
            rows.add(RowFactory.create(1, "张三", 18,"12345678"));
        }
        StructType schema = DataTypes.createStructType(new StructField[]{
                DataTypes.createStructField("id", DataTypes.IntegerType, true),
                DataTypes.createStructField("name", DataTypes.StringType, true),
                DataTypes.createStructField("user-age", DataTypes.IntegerType, true),
                DataTypes.createStructField("number", DataTypes.StringType, true)
        });
        spark.createDataFrame(rows,schema).write().orc("/Users/codes/testspark/src/orc");
        spark.stop();

测试数据样例(当然:
在这里插入图片描述
现在将spark的版本切换为2.4.0-cdh6.1.1开始读取这个数据/Users/codes/testspark/src/orc
果不其然,出现如下所示的报错信息,开始调试这个程序:
在这里插入图片描述
断点打到ParseDriver.scala里面的withCommand的方法
在这里插入图片描述
Ideadebug栏里面看到:
这个user-age字段被解析成了三个内容:user-age.所以是这里出现了问题。
在这里插入图片描述
在非CDH版本的spark当中,这块儿变量会是什么样子呢?如下图所示:
在这里插入图片描述
在这个图里面,user-age被成功解析了,并且套上了一对反引号。
那么,是什么东西造成了这样的不同呢?

核心原因:

原因是在CDHspark中,有一个类org.apache.orc.TypeDescription在解析数据schema的过程中,不能正确识别字段中含有的特殊符号(cdh版本的该类与开源版本相比缺失了一些解析字段名称的方法),也就不能给这些含有特殊符号的字段名称添加一对反引号。导致最后生成的。schema信息过不去词法分析器步骤,所以报错。
具体的原因是在这表的结构信息转换成protobuf格式的时候:
这块地方是cdh版本的spark调用的toString()方法中的printToBuffer()方法里面的详细内容:
在这里插入图片描述
这个是开源版本的:
在这里插入图片描述
这里多调用了一个printFieldName的方法,我们开看看方法:
在这里插入图片描述
这里就是为了给字段名中添加反引号的地方了。
到这里,全部解释完毕了。

总结

原因找到了那么接下来的解决方案就好办了,可以对症下药。写到这里,如果各位大佬有什么更好的建议,请在下方留言:
在这里插入图片描述

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐