Spark 程序在内部调用 HDFS:/apps/hive/warehouse

Posted

技术标签:

【中文标题】Spark 程序在内部调用 HDFS:/apps/hive/warehouse【英文标题】:Spark program is internally calling HDFS: /apps/hive/warehouse 【发布时间】:2018-12-06 12:42:21 【问题描述】:

场景/代码详情


我正在创建一个 spark session 对象来将数据存储到 hive 表中,如下所示:

_sparkSession = SparkSession.builder().
                    config(_sparkConf).
                    config("spark.sql.warehouse.dir", "/user/platform").
                    enableHiveSupport().
                    getOrCreate();

将我的 JAR 部署到服务器后,出现以下异常:

Caused by: org.apache.spark.sql.AnalysisException:
org.apache.hadoop.hive.ql.metadata.HiveException:
MetaException(message:org.apache.hadoop.security.AccessControlException:
Permission denied: user=diplatform, access=EXECUTE,
inode="/apps/hive/warehouse":hdfs:hdfs:d---------
        at org.apache.hadoop.hdfs.server.namenode.FSPermissionChecker.check(FSPermissionChecker.java:353)

在我的 hive-site.xml 中,我给出了以下配置。我们正在将此 xml 添加到我们的 spark 代码中,以便可以覆盖 /etc/hive/conf 中的默认 xml:

<property>
  <name>hive.security.metastore.authenticator.manager</name>
  <value>org.apache.hadoop.hive.ql.security.HadoopDefaultMetastoreAuthenticator</value>
</property>

<property>
  <name>hive.security.metastore.authorization.auth.reads</name>
  <value>false</value>
</property>

<property>
  <name>hive.security.metastore.authorization.manager</name>
  <value>org.apache.hadoop.hive.ql.security.authorization.DefaultHiveMetastoreAuthorizationProvider</value>
</property>

<property>
  <name>hive.metastore.authorization.storage.checks</name>
  <value>false</value>
</property>

 <property>
  <name>hive.metastore.cache.pinobjtypes</name>
  <value>Table,Database,Type,FieldSchema,Order</value>
</property>

    <property>
  <name>hive.metastore.client.connect.retry.delay</name>
  <value>5s</value>
</property>

<property>
  <name>hive.metastore.client.socket.timeout</name>
  <value>1800s</value>
</property>

<property>
  <name>hive.metastore.connect.retries</name>
  <value>24</value>
</property>

 <property>
  <name>hive.metastore.execute.setugi</name>
  <value>true</value>
</property>

 <property>
  <name>hive.metastore.failure.retries</name>
  <value>24</value>
</property>

<property>
  <name>hive.metastore.kerberos.keytab.file</name>
  <value>/etc/security/keytabs/hive.service.keytab</value>
</property>

<property>
  <name>hive.metastore.kerberos.principal</name>
  <value>hive/_HOST@EXAMPLE.COM</value>
</property>

<property>
  <name>hive.metastore.pre.event.listeners</name>
  <value>org.apache.hadoop.hive.ql.security.authorization.AuthorizationPreEventListener</value>
</property>

<property>
  <name>hive.metastore.sasl.enabled</name>
  <value>true</value>
</property>

<property>
  <name>hive.metastore.server.max.threads</name>
  <value>100000</value>
</property>

<property>
  <name>hive.metastore.uris</name>
  <value>thrift://masternode1.com:9083</value>
</property>

<property>
  <name>hive.metastore.warehouse.dir</name>
  <value>/user/platform</value>
</property>

问题:


    现在整个开发团队都不确定为什么以及从哪里获取这条路径:/apps/hive/warehouse,即使在覆盖了我们的自定义 hive-site.xml 之后也是如此?

    是不是内部HDFS框架调用这个位置来存储中间结果,需要这个路径的执行权限?

根据政策,我们无法在 /apps/hive/warehouse 向用户提供 777 级访问权限,原因有两个:

将来可能会有其他不同的用户集。 在仓库向用户提供 777 是不安全的。

    以上两个原因是否正确或有一些解决方法?

【问题讨论】:

【参考方案1】:

Hive 元存储有自己的 XML 文件,用于确定 Hive 表在 HDFS 上的位置。该属性由 HiveServer 决定,而不是 Spark

例如,在 Hortonworks 集群上,请注意仓库的权限为 777,并归 hive 用户和 hdfs 超级用户组所有。

$ hdfs dfs -ls /apps/hive
Found 2 items
drwxrwxrwx   - hive hadoop          0 2018-02-27 20:20 /apps/hive/auxlib
drwxrwxrwx   - hive hdfs            0 2018-06-27 10:27 /apps/hive/warehouse

根据您的错误,该目录存在,但没有用户可以读取、写入或列出该仓库目录的内容。

理想情况下,我建议不要将仓库放在 HDFS 用户目录中。

【讨论】:

我们可以将仓库位置更改为任何其他目录,但错误仍然存​​在。如何更改HDFS正在挑选的dafult位置(/apps/hive/warehouse)?? 想强调有 kerberos 身份验证,并且在服务器上启用了 Ranger 授权。这是强制 diplatform 用户不能访问 /apps/hive 和 /apps/hive/* HDFS 没有选择任何东西。 Hive Metastore 进程是。您需要更改该服务器上的配置单元站点并重新启动配置单元进程。我没有使用 Kerberos 或 Ranger 的经验 以下链接帮助您更改 Metastore ***.com/questions/30518130/…【参考方案2】:

似乎是用户“diplatform”在 HDFS 上的权限问题。

以admin用户登录,进行如下操作

hadoop fs -mkdir -p /apps/hive/warehouse
hadoop fs -mkdir /tmp
hadoop fs -chmod -R 777 /user/hive
hadoop fs -chmod 777 /tmp

然后在从“diplatform”创建数据库语句之后。

【讨论】:

你是对的。它在组织级别的权限问题。根据授权政策,它不允许授予对 /apps/hive/warehouse 的完全访问权限。我们不能将此位置设置为其他位置吗?我尝试将其设置在 hive-site.xml 并将此 xml 包含在我的代码中,但所有这些都不起作用。我仍然看到异常。 我们可以模拟并解决这个问题吗?我尝试将 doAS 属性设置为 false,但没有成功。此外,当我运行: $ hdfs dfs -ls /apps/hive from diplatform user 时,它给出了相同的异常: ls: Permission denied: user=diplatform, access=EXECUTE, inode="/apps/hive":hdfs:hdfs:d -

以上是关于Spark 程序在内部调用 HDFS:/apps/hive/warehouse的主要内容,如果未能解决你的问题,请参考以下文章

调用 malloc 函数并不总是在内部调用 sbrk 函数?

我的 C# win 表单应用程序在内部调用批处理脚本,如何在 Visual Studio 中导出时对最终用户隐藏它?

Spring Hystrix 未在内部方法上触发

将数据作为文本文件从 spark 保存到 hdfs

如何在内部调用快速导出方法?

snprintf() 是不是在内部调用 memset() 或类似的?