【问题标题】:Permission denied when using SPARK dataframes' method "saveAsTable"使用 SPARK 数据帧的方法“saveAsTable”时权限被拒绝
【发布时间】:2016-04-27 11:05:31
【问题描述】:

我正在使用 Spark 1.3,我正在尝试从一个 RDD 生成一个表。这是伪代码:

val sc = new org.apache.spark.SparkContext(conf)
val sqlContext = new org.apache.spark.sql.hive.HiveContext(sc)
import sqlContext.implicits._

val rdd1=sc.textFile(path_1).map(........) // RDD[(string,Double)]
val rdd2=sc.textFile(path_2).map(........) // RDD[(string,Double)]
val rdd_join=rdd1.fullOuterJoin(rdd2)      // RDD[String,(Option(Double),Option(Double))) 
val rdd_get = rdd_join.map(....}           // RDD[(String,Double,Double)]
rdd_get.toDF().saveAsTable("database.tablename")

运行此代码时出现权限错误:

org.apache.hadoop.security.AccessControlException: 权限被拒绝: user=XXXXXXXX, access=WRITE, inode="/user/hive/warehouse":hive:hive:drwxrwx--x:user:hive:rwx, group::---,group:hive:rwx

如果我将表创建为:

  rdd_get.toDF().registerTempTable("rdd_get_temp")
  sqlContext.sql("CREATE TABLE database.tablename AS SELECT * FROM rdd_get_temp")

然后它工作并创建表。看起来 saveAsTable() 正在尝试使用我的用户写入“/user/hive/warehouse”(这是 Kerberization 禁止的),而 sqlContext.sql 使用正确的用户“hive”来执行此操作。

我说的对吗?这是bug吗??它适用于较新的 spark 版本吗?

谢谢大家。

【问题讨论】:

  • 不是错误。如果您想要“干净”的授权设置,您可以将 HiveServer2 设置为使用您的实际用户帐户,而不是 hive 服务帐户。但是随后您必须管理 Hive 表使用的每个 HDFS 目录上的 ACL——就像您对网络驱动器所做的一样(每个用户、每个组等)。这个通用的hive 帐户是一个非常蹩脚的东西——而 Sentry / Ranger 只是荒谬的创可贴,可以给企业吸盘提供安全的错觉。
  • 无论如何,如果您可以获得管理员权限(例如,以hdfs 获得 Kerberos 票证),那么您可以在您希望 Spark 创建文件的目录上创建 ACL,以便 您的 用户获得写入权限。比如hdfs dfs -setfacl -m user:johndoe:r-x /user/hive/warehouse/ 然后hdfs dfs -setfacl -m user:johndoe:rwx /user/hive/warehouse/sometable/
  • ...如果您需要创建分区(即子目录),请加上“默认”ACL。

标签: hadoop apache-spark kerberos spark-dataframe


【解决方案1】:

SaveAsTable 创建一个物理表,而 registerTempTable 在内存中创建一个(临时)表。 你是对的,用户需要适当的权限才能创建物理表。

【讨论】:

    猜你喜欢
    • 2011-08-04
    • 2010-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-25
    相关资源
    最近更新 更多