apache-spark - 如何通过 Spark 2.3 (pyspark) 在 Hive 3.1 中创建镶木地板表
问题描述
从 Spark 创建/加载 parquet 表时面临的问题
环境细节:
Horotonworks HDP3.0
火花 2.3.1
蜂巢 3.1
1#。当尝试在 Hive 3.1 到 Spark 2.3 中创建 parquet 表时,Spark 会抛出以下错误。
df.write.format("parquet").mode("overwrite").saveAsTable("database_name.test1")
pyspark.sql.utils.AnalysisException: u'org.apache.hadoop.hive.ql.metadata.HiveException: MetaException(message:Table datamart.test1 failed strict managed table checks due to the following reason: Table is marked as a managed table but is not transactional.);'
2#。成功地将数据插入现有 parquet 表并通过 Spark 检索。
df.write.format("parquet").mode("overwrite").insertInto("database_name.test2")
spark.sql("select * from database_name.test2").show()
spark.read.parquet("/path-to-table-dir/part-00000.snappy.parquet").show()
但是当我尝试通过 Hive 读取同一张表时,Hive 会话断开连接并抛出错误。
SELECT * FROM database_name.test2
org.apache.thrift.transport.TTransportException
at org.apache.thrift.transport.TIOStreamTransport.read(TIOStreamTransport.java:132)
at org.apache.thrift.transport.TTransport.readAll(TTransport.java:86)
at org.apache.thrift.transport.TSaslTransport.readLength(TSaslTransport.java:376)
at org.apache.thrift.transport.TSaslTransport.readFrame(TSaslTransport.java:453)
at org.apache.thrift.transport.TSaslTransport.read(TSaslTransport.java:435)
at org.apache.thrift.transport.TSaslClientTransport.read(TSaslClientTransport.java:37)
at org.apache.thrift.transport.TTransport.readAll(TTransport.java:86)
at org.apache.thrift.protocol.TBinaryProtocol.readAll(TBinaryProtocol.java:429)
at org.apache.thrift.protocol.TBinaryProtocol.readI32(TBinaryProtocol.java:318)
at org.apache.thrift.protocol.TBinaryProtocol.readMessageBegin(TBinaryProtocol.java:219)
at org.apache.thrift.TServiceClient.receiveBase(TServiceClient.java:77)
at org.apache.hive.service.rpc.thrift.TCLIService$Client.recv_FetchResults(TCLIService.java:567)
at org.apache.hive.service.rpc.thrift.TCLIService$Client.FetchResults(TCLIService.java:554)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.hive.jdbc.HiveConnection$SynchronizedHandler.invoke(HiveConnection.java:1572)
at com.sun.proxy.$Proxy22.FetchResults(Unknown Source)
at org.apache.hive.jdbc.HiveQueryResultSet.next(HiveQueryResultSet.java:373)
at org.apache.hive.beeline.BufferedRows.<init>(BufferedRows.java:56)
at org.apache.hive.beeline.IncrementalRowsWithNormalization.<init>(IncrementalRowsWithNormalization.java:50)
at org.apache.hive.beeline.BeeLine.print(BeeLine.java:2250)
at org.apache.hive.beeline.Commands.executeInternal(Commands.java:1026)
at org.apache.hive.beeline.Commands.execute(Commands.java:1201)
at org.apache.hive.beeline.Commands.sql(Commands.java:1130)
at org.apache.hive.beeline.BeeLine.dispatch(BeeLine.java:1425)
at org.apache.hive.beeline.BeeLine.execute(BeeLine.java:1287)
at org.apache.hive.beeline.BeeLine.begin(BeeLine.java:1071)
at org.apache.hive.beeline.BeeLine.mainWithInputRedirection(BeeLine.java:538)
at org.apache.hive.beeline.BeeLine.main(BeeLine.java:520)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.hadoop.util.RunJar.run(RunJar.java:318)
at org.apache.hadoop.util.RunJar.main(RunJar.java:232)
Unknown HS2 problem when communicating with Thrift server.
Error: org.apache.thrift.transport.TTransportException: java.net.SocketException: Broken pipe (Write failed) (state=08S01,code=0)
在此错误之后,Hive 会话断开连接,我必须重新连接。所有其他查询都工作正常,只有此查询显示上述错误并断开连接。
解决方案
出现此问题是因为在没有 Hive 仓库连接器的情况下访问 Hive 表。
默认情况下,spark 使用 spark 目录,下面的文章解释了如何通过 Spark 访问 Apache Hive 表。
将 Apache Hive 与 Apache Spark 集成 - Hive 仓库连接器
从 HDP 3.0 开始,Apache Hive 和 Apache Spark 的目录是分开的,它们使用自己的目录;即它们是互斥的——Apache Hive 目录只能被 Apache Hive 或这个库访问,而 Apache Spark 目录只能被 Apache Spark 中现有的 API 访问。换句话说,一些特性,如 ACID 表或带有 Apache Hive 表的 Apache Ranger 只能通过 Apache Spark 中的这个库获得。Hive 中的这些表不应在 Apache Spark API 本身中直接访问。
推荐阅读
- windows-services - 在 CI 服务器上运行时,testcafe E2E 测试在 Internet Explorer 11 上挂起(由 Windows 服务运行)
- python - 导出 svg 文件时,Plotly 无法访问 orca 服务器
- octobercms - 关系经理如何使用转发器字段?
- php - PHP在页面之间丢失会话
- c++ - 为什么 gcc 编译这个而 msvc 不编译
- c++ - 链表的通用函数 remove() 与成员函数 remove()
- java - 生成正则表达式以匹配字符串
- php - 用包含+符号的长字符串(超过1000个字符)在php中解码json字符串
- if-statement - Freemarker 如果条件为 NULL
- python - 熊猫数据框中每一列的唯一值及其计数