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.newSession
和spark
共享相同的SparkContext,newSession
方法的文档是这样说的:
使用隔离的SQL配置启动新会话。临时表,已注册的函数被隔离,但共享底层的SparkContext和缓存数据。
所以方法二不能跨hive共享数据。