[英]How to use in-memory Derby database for testing with Hive (Scala)
我正在使用帶有Scala 2.11的spark-hive 2.3.0並設置單元測試框架。 spark-hive附帶了TestHiveContext
和TestHiveSparkSession
,它可以方便地從單元測試中調用Hive,而無需運行Hadoop,Spark或集群,這對於自動化測試非常TestHiveSparkSession
。
Hive需要一個用於其Metastore的數據庫,當以這種方式運行時,它使用Derby作為使用javax.jdo.option.ConnectionURL
配置的嵌入式數據庫,默認情況下為jdbc:derby:;databaseName=<file-path>;create=true
。 <file-path>
是本地文件系統中的一個位置,是運行Derby的一個選項。
另一種選擇是在內存中運行Derby,這通常就像將URL更改為類似jdbc:derby:memory:databaseName;create=true
。 Hoewever,這對於Hive是不可能的,因為配置是在內部HiveUtils
類中進行的,並且不能被覆蓋。 我試着在我的星火會話生成器改變它,但后來我改變得到由吹走HiveUtils
當我創建我的TestHiveContext
。
在我的情況下,內存數據庫是首選,因為我們的開發人員在Windows上運行(絕對不是我/我們的選擇),並且當創建這些文件時,通常會出現文件名中的權限或無效字符等問題(因為Hadoop從未真正打算過在Windows上工作),這些文件經常被遺忘,因為它們無法清理(由於這些問題)。 我們希望測試完全獨立,因此它們可以在沒有副作用的情況下運行和完成,因此它們可以在多個環境(開發人員,CI,Jenkins,AWS等)中運行。
有趣的是我在TestHive.scala
看到了這個:
{ // set the metastore temporary configuration
val metastoreTempConf = HiveUtils.newTemporaryConfiguration(useInMemoryDerby = false) ++ Map(
因此,有一個使用內存數據庫的標志,但這是不可配置的,並且沒有代碼路徑將其設置為true
。
有沒有辦法配置或寫這個,以便TestHive
的Derby可以在內存中? 試圖通過hive-site.xml或hdfs-site.xml設置javax.jdo.option.ConnectionURL
的值不起作用,我認為這是因為TestHive
, TestHiveContext
和TestHiveSparkSession
如何初始化,它們有自己的代碼路徑與非測試路徑分開。 它們提供的功能對於測試框架非常有用,但顯然沒有提供覆蓋此值和其他一些設置的方法。
到目前為止,我能看到的最好的選擇是覆蓋或編寫我自己的TestHiveContext
類,該類從該類借用了一堆功能並覆蓋了我需要的部分,但這對於我認為可以用簡單的方法完成的工作來說是一項相對較大的任務。配置改變。
我終於想出了如何做到這一點,並希望分享答案,以防其他人試圖做同樣的事情。
我的測試類使用SharedSparkContext
性狀,它提供了一個SparkContext
經由變種通過引用sc
。
在SparkContext初始化之后(我使用了scalatest
測試框架中提供的beforeAll
鈎子),我創建了一個這樣的TestHiveContext
:
hc = new TestHiveContext(sc, false)
然后立即,我可以設置javax.jdo.option.ConnectionURL
並可能設置其他一些Hadoop和Hive配置,如下所示:
sc.hadoopConfiguration.set("javax.jdo.option.ConnectionURL",
"jdbc:derby:memory:db;create=true")
此配置參數由Hive使用,但顯然必須添加到Hadoop配置中,該配置用於構建Hive測試上下文。
訣竅是時間,這必須在Hadoop和Hive自己初始化后(使用配置文件和諸如此類)完成,並且最初的框架也被初始化,最后在TestHive框架初始化之后,但在運行任何測試之前。 嘗試在這些其他初始化之前設置此參數意味着您的設置將在測試運行之前被覆蓋。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.