Spark:同一个程序使用多个hive元数据

一个SparkSession对象只能使用一个hive元数据,且中间不可变更,若想spark程序能访问多个hive元数据,有以下两种方法:

方法一:

采用jdbc方式建立多个hive连接。

方法二:

程序前后创建两个SparkSession对象(不能共存),分别用 hive.metastore.uris 选项指定不同的hive服务地址:

val spark = SparkSession
    .builder()
    .appName("Test")
    .config("spark.sql.parquet.writeLegacyFormat", true)
    .config("hive.metastore.uris", "thrift://10.18.2.3:9083")
    .enableHiveSupport()
    .getOrCreate()
val df = spark.table("...")
df.createOrReplaceGlobalTempView("tempView")

val spark1 = spark.newSession //此新的SparkSession对象能够看到表tempView

spark.stop()

val spark2 = SparkSession
    .builder()
    .appName("Test")
    .config("spark.sql.parquet.writeLegacyFormat", true)
    .config("hive.metastore.uris", "thrift://10.18.2.4:9083")
    .enableHiveSupport()
    .getOrCreate()
//spark2对象看不到表tempView

用这种方法可以在一个程序中先后分别使用两个hive的数据,但是却不能同时使用两个hive的数据,也不能在两个hive之间共享数据。因为——

createOrReplaceGlobalTempView方法注册的全局表只能在上下文相同的SparkSession对象间可见:
假设spark是注册全局表时用的SparkSession对象,则此全局表对spark.newSession返回的新对象可见;而对于用SparkSession.builder().getOrCreate()返回的新对象不可见。

spark.newSessionspark共享相同的SparkContext,newSession方法的文档是这样说的:

使用隔离的SQL配置启动新会话。临时表,已注册的函数被隔离,但共享底层的SparkContext和缓存数据。

所以方法二不能跨hive共享数据。

猜你喜欢

转载自blog.csdn.net/xuejianbest/article/details/85993275