AWS Glue数据目录作为EMR上的Spark SQL的元存储问题

时间:2019-01-09 21:19:15

标签: apache-spark amazon-emr aws-glue hive-metastore aws-glue-data-catalog

我有一个带有Spark(v2.2.1)的AWS EMR集群(v5.11.1),并尝试使用AWS Glue数据目录作为其元存储。根据AWS官方文档中提供的指南(下面的参考链接),我已经按照步骤进行操作,但是在访问Glue Catalog数据库/表方面面临一些差异。 EMR群集和AWS Glue都在同一帐户中,并且提供了适当的IAM权限。

AWS文档https://docs.aws.amazon.com/emr/latest/ReleaseGuide/emr-spark-glue.html


  

观察

:      

-使用spark-shell(来自EMR主节点):

     
      
  • 工程。可以使用以下命令访问Glue数据库/表:      
    spark.catalog.setCurrentDatabase("test_db")
    spark.catalog.listTables
    
      
  •   
     

-使用火花提交(从EMR步骤开始):

     
      
  • 不起作用。不断收到错误消息“数据库'test_db'不存在”
  •   

错误跟踪如下:

  

INFO HiveClientImpl:Hive客户端(1.2.1版)的仓库位置为hdfs:/// user / spark / warehouse
  INFO HiveMetaStore:0:get_database:默认
  INFO审核:ugi = hadoop ip = unknown-ip-addr cmd = get_database:默认
  信息HiveMetaStore:0:get_database:global_temp
  信息审核:ugi = hadoop ip = unknown-ip-addr cmd = get_database:global_temp
  WARN ObjectStore:无法获取数据库global_temp,返回NoSuchObjectException
  INFO SessionState:创建的本地目录:/ mnt3 / yarn / usercache / hadoop / appcache / application_1547055968446_0005 / container_1547055968446_0005_01_000001 / tmp / 6d0f6b2c-cccd-4e90-a524-93dcc5301e20_resources
  INFO SessionState:创建的HDFS目录:/ tmp / hive / hadoop / 6d0f6b2c-cccd-4e90-a524-93dcc5301e20
  INFO SessionState:创建的本地目录:/ mnt3 / yarn / usercache / hadoop / appcache / application_1547055968446_0005 / container_1547055968446_0005_01_000001 / tmp / yarn / 6d0f6b2c-cccd-4e90-a524-93dcc5301e20
  INFO SessionState:创建的HDFS目录:/tmp/hive/hadoop/6d0f6b2c-cccd-4e90-a524-93dcc5301e20/_tmp_space.db
  INFO HiveClientImpl:Hive客户端(1.2.1版)的仓库位置为hdfs:/// user / spark / warehouse
  INFO StateStoreCoordinatorRef:已注册的StateStoreCoordinator端点
  INFO CodeGenerator:在> 191.063411 ms中生成的代码
  INFO CodeGenerator:代码在10.27313毫秒中生成
  信息HiveMetaStore:0:get_database:test_db
  信息审核:ugi = hadoop ip = unknown-ip-addr cmd = get_database:test_db
  WARN ObjectStore:无法获取数据库test_db,返回NoSuchObjectException
  org.apache.spark.sql.AnalysisException:数据库'test_db'不存在。     在org.apache.spark.sql.internal.CatalogImpl.requireDatabaseExists(CatalogImpl.scala:44)     在org.apache.spark.sql.internal.CatalogImpl.setCurrentDatabase(CatalogImpl.scala:64)     在org.griffin_test.GriffinTest.ingestGriffinRecords(GriffinTest.java:97)     在org.griffin_test.GriffinTest.main(GriffinTest.java:65)     在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)处     在sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)     在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)     在java.lang.reflect.Method.invoke(Method.java:498)     在org.apache.spark.deploy.yarn.ApplicationMaster $$ anon $ 2.run(ApplicationMaster.scala:635)


经过大量研究并在博客中提出了许多建议,我尝试了以下修复方法,但无济于事,我们仍然面临着差异。

参考博客:

  

修复尝试:

     

-在spark-defaults.conf和SparkSession(代码)中启用Hive支持:

     
      
  • 配置单元类位于CLASSPATH上,并将spark.sql.catalogImplementation内部配置属性设置为配置单元:

         
    spark.sql.catalogImplementation  hive
    
      
  •   
  • 添加Hive Metastore配置:

         
    .config("hive.metastore.connect.retries", 15)
    .config("hive.metastore.client.factory.class", "com.amazonaws.glue.catalog.metastore.AWSGlueDataCatalogHiveClientFactory")
    
      
  •   

代码段:

SparkSession spark = SparkSession.builder().appName("Test_Glue_Catalog")
                        .config("spark.sql.catalogImplementation", "hive")
                        .config("hive.metastore.connect.retries", 15) 
                        .config("hive.metastore.client.factory.class","com.amazonaws.glue.catalog.metastore.AWSGlueDataCatalogHiveClientFactory")
                        .enableHiveSupport()
                        .getOrCreate();

找出这种差异的根本原因的任何建议都会很有帮助。

感谢您的帮助!谢谢!

1 个答案:

答案 0 :(得分:1)

在整整一天的苦苦挣扎之后,我会告诉您什么对我有用。

我的目标:从EMR集群外部的EC2实例运行spark-submit命令。集群使用S3进行存储(配置单元表),并使用Glue Data Catalog进行元存储:

  • 启动您的EMR集群(当然,请打开Glue metastore配置)
  • 从您的主节点创建AMI图像
  • 从映像启动EC2实例
    • 确保您的网络配置允许群集VM与您将启动作业的实例(子网和安全组)之间的通信
  • 在您刚刚启动的实例上:

    • 使用以下命令更新/etc/hadoop/conf/yarn-site.xml:
    <property>    
       <name>yarn.timeline-service.enabled</name>
       <value>false</value>
    </property>
    

现在,您应该可以以集群模式提交作业了。为了在客户端模式中执行此操作,您需要在创建的该实例上设置AWS CREDENTIALS。

真正缺少的是什么

  • Spark需要为AWSGlueDataCatalogHiveClientFactory加载jar(在/etc/spark/conf/spark-defaults.conf中检查spark.driver.extraClassPath和spark.executor.extraClassPath)

  • 还要检查/etc/spark/hive-site.xml:

    <property>    
       <name>yarn.timeline-service.enabled</name>
       <value>com.amazonaws.glue.catalog.metastore.AWSGlueDataCatalogHiveClientFactory</value>
    </property>
    
         
        
    • 此配置告诉蜂巢将Glue数据目录用于元存储,无需再将其放在代码中!
    •   

使其工作后,我还清理了一些配置:

  • 您可以摆脱配置单元中的内容(/ etc / hive)。

  • 在/etc/spark/conf/spark-env.sh中,我只离开了导出HADOOP_CONF_DIR的行

  • 在/etc/spark/conf/spark-defaults.conf文件中,仅保留了以下配置:

    • spark.driver.extraClassPath
    • spark.driver.extraLibraryPath
    • spark.executor.extraClassPath
    • spark.executor.extraLibraryPath

我真的刚刚完成了这项工作,所以我将放一些配置。现在重要的是要确定我要放置什么以及为什么要添加这些配置。