【问题标题】:java.lang.ClassCastException: org.apache.hadoop.hive.ql.io.orc.OrcStruct cannot be cast to org.apache.hadoop.io.Text. Error with json serdejava.lang.ClassCastException: org.apache.hadoop.hive.ql.io.orc.OrcStruct 无法转换为 org.apache.hadoop.io.Text。 json serde 出错
【发布时间】:2018-03-05 16:44:19
【问题描述】:

我是在 hive 上处理 json 数据的新手。我正在开发一个获取 json 数据并将其存储到配置单元表中的 spark 应用程序。我有一个这样的json:

展开后的样子:

我能够将 json 读入数据帧并将其保存在 HDFS 上的某个位置。但是让 hive 能够读取数据是困难的部分。

例如在网上搜索后,我尝试这样做:

对所有 json 字段使用 STRUCT,然后使用 column.element 访问元素。

例如:

web_app_security 将是表内的列(STRUCT 类型)的名称,其中的其他 json 像 config_web_cms_authentication, web_threat_intel_alert_external 也将是结构(以 ratingrating_numeric 作为字段) .

我尝试使用 json serde 创建表。这是我的表定义:

CREATE EXTERNAL TABLE jsons (
web_app_security struct<config_web_cms_authentication: struct<rating: string, rating_numeric: float>, web_threat_intel_alert_external: struct<rating: string, rating_numeric: float>, web_http_security_headers: struct<rating: string, rating_numeric: float>, rating: string, rating_numeric: float>,
dns_security struct<domain_hijacking_protection: struct<rating: string, rating_numeric: float>, rating: string, rating_numeric: float, dns_hosting_providers: struct<rating:string, rating_numeric: float>>,
email_security struct<rating: string, email_encryption_enabled: struct<rating: string, rating_numeric: float>, rating_numeric: float, email_hosting_providers: struct<rating: string, rating_numeric: float>, email_authentication: struct<rating: string, rating_numeric: float>>,
threat_intell struct<rating: string, threat_intel_alert_internal_3: struct<rating: string, rating_numeric: float>, threat_intel_alert_internal_1: struct<rating: string, rating_numeric: float>, rating_numeric: float,  threat_intel_alert_internal_12: struct<rating: string, rating_numeric: float>, threat_intel_alert_internal_6: struct<rating: string, rating_numeric: float>>,
data_loss struct<data_loss_6: struct<rating: string, rating_numeric: float>, rating: string, data_loss_36plus: struct<rating: string, rating_numeric: float>, rating_numeric: float,  data_loss_36: struct<rating: string, rating_numeric: float>, data_loss_12: struct<rating: string, rating_numeric: float>, data_loss_24: struct<rating: string, rating_numeric: float>>,
system_hosting struct<host_hosting_providers: struct<rating: string, rating_numeric: float>,  hosting_countries: struct<rating: string, rating_numeric: float>, rating: string, rating_numeric: float>,
defensibility struct<attack_surface_web_ip: struct<rating: string, rating_numeric: float>, shared_hosting: struct<rating: string, rating_numeric: float>, defensibility_hosting_providers: struct<rating: string, rating_numeric: float>, rating: string, rating_numeric: float, attack_surface_web_hostname: struct<rating: string, rating_numeric: float>>,
software_patching struct<patching_web_cms: struct<rating: string, rating_numeric: float>, rating: string, patching_web_server: struct<rating: string, rating_numeric: float>, patching_vuln_open_ssl: struct<rating: string, rating_numeric: float>, patching_app_server: struct<rating: string, rating_numeric: float>, rating_numeric: float>,
governance struct<governance_customer_base: struct<rating: string, rating_numeric: float>, governance_security_certifications: struct<rating: string, rating_numeric: float>, governance_regulatory_requirements: struct<rating: string, rating_numeric: float>, rating: string, rating_numeric: float>
)ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe'
STORED AS orc
LOCATION 'hdfs://nameservice1/data/gis/final/rr_current_analysis'

我尝试使用 json serde 解析行。将一些数据保存到表后,尝试查询时出现以下错误:

Error: java.io.IOException: java.lang.ClassCastException: org.apache.hadoop.hive.ql.io.orc.OrcStruct cannot be cast to org.apache.hadoop.io.Text (state=,code=0)

我不确定我的做法是否正确。

我也愿意以任何其他方式将数据存储到表中。任何帮助,将不胜感激。谢谢。

【问题讨论】:

    标签: json hadoop hive hive-serde


    【解决方案1】:

    这是因为您将 ORC 作为存储 (STORED AS orc) 和 JSON 作为 SerDe (ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe') 混合使用,覆盖 ORC 的默认 OrcSerde SerDe,但不是输入 (OrcInputFormat) 和输出 (OrcOutputFormat ) 格式。

    您需要使用 ORC 存储而不覆盖其默认 SerDe。在这种情况下,请确保您的 Spark 应用程序写入 ORC 表,而不是 JSON。

    或者,如果您希望以 JSON 格式存储数据,请使用 JsonSerDe 和纯文本文件作为存储 (STORED AS TEXTFILE)。


    Hive 开发者指南解释了 SerDe 和 Storage 的工作原理 -https://cwiki.apache.org/confluence/display/Hive/DeveloperGuide#DeveloperGuide-HiveSerDe

    【讨论】:

    • 感谢您的回答。我试图使用df.rdd.saveAsTextFile("Path") 将我的数据框保存为文本文件,但我得到了他的错误`org.apache.hadoop.mapred.FileAlreadyExistsException:输出目录已经存在`我不知道为什么它试图为每个人创建一个新目录数据框而不是在给定路径中创建新文件。有没有更好的方法将数据框保存为文本文件?或者有没有办法可以将数据框保存为 csv 并给出适当的表定义来读取 csv 文件并使用 json serde? @Sergey Khudyakov
    • @HemanthAnnavarapu 转而查看df.write,尤其是df.write.mode(SaveMode)。我不知道你为什么现在提到 CSV 文件,但我强烈建议你先阅读 Hive 开发人员指南(答案中的链接)和 Spark DataFrame API 文档。 “更好的方法”真的取决于你想实现什么,你想在 Hive 中拥有什么样的表等等。
    • 我现在正在尝试使用 csv,因为我已经搜索了将数据框保存为文本的方法,并且在大多数示例中,他们指的是使用 DF.write.format("org.databricks.spark.csv").save("path") 。由于Df.saveAsTextFile 不起作用,我正在尝试使用 csv。有没有办法我仍然可以在csv 文件上使用serde?或者我是否可以使用orc 格式覆盖input format? @Sergey Khudyakov
    • 我可以通过将 dataframe 保存为 json 来使其正常工作。表定义中没有提到STORED AS
    • @HemanthAnnavarapu 很好,你解决了它。 Hive 默认使用 TEXTFILE 存储。
    猜你喜欢
    • 2017-12-27
    • 1970-01-01
    • 1970-01-01
    • 2023-03-09
    • 1970-01-01
    • 2017-07-07
    • 2016-12-05
    • 1970-01-01
    • 2019-10-04
    相关资源
    最近更新 更多