2023年8月12日 星期六

用Databricks Container Services加速Cluster啟動速度

前言

最近有同事在Databricks的Cluster,每次啟動都很慢,之後他找了一些資料,發現可以執行自訂的Docker container來加快啟動速度,就跑來問我這個東西如何。Blog主從來不知道可以這樣做,看了一下微軟的官方文件,感覺方法也沒特別難,就照著說明試了一下,最後也成功裝上了自訂的Docker image。

先說結論,Blog主試的時候,在沒快取的狀態下,Cluster啟動時間從10分鐘降到5分鐘,大約省了一半時間,還蠻驚人的。在有快取的狀態下,啟動時間甚至來到2分鐘,不過除非很頻繁的啟動Cluster,而且都用同一個Docker image,基本上我們只看沒快取的時間就好。

為什麼我同事的Cluster啟動會特別慢?

我同事有一個Cluster專門跑自然語言處理(NLP),裡面裝了各式各樣的Python以及R的Library,數量很多,這就是最直接的原因。每次Cluster啟動的時候,Databricks都要從網路下載以及安裝,因此拖慢了啟動速度。上述說的啟動時間10分鐘只是狀況好的情況,有時甚至會拖到15~20分鐘。

Databricks的Cluster灌Library的方式有幾種?什麼情況用什麼方式?

  1. 在Cluster的設定頁面指定Library的名稱與版本
  2. 在Notebook內用%pip或%sh指令安裝
  3. 如果使用Azure Data Factory的話,可以在pipeline裡面的Databricks專用activity裡指定Library
  4. 自己建Docker image,並在Cluster設定啟動時使用(本文的主題,後述)

上面簡單整理目前Blog主所知的安裝方法,我們先暫時忽略方法4。取決於你的use case,如果是有不同功能的處理,共用同一個Cluster的情況(通常大公司,或多人開發環境,應該都屬於這個Case),Blog主推薦使用方法2或3,而這裡面又屬方法2最佳。

方法2跟3都不會全域性的安裝Library,當你開發一個新的處理的時候,也不會被既存的Library影響,能維持執行環境的乾淨。特別是Python在不同Library都使用同個函式名稱的情況下,會直接隨意選其中一個來執行。而使用方法2的優點是,更可以在同一個地方就知道這個處理使用什麼自訂Library,確認跟管理都快速。

至於如果你的use case規模比較小,只有一個處理,或著相似的處理共用Cluster,那其實方法1~3不會差非常多,甚至方法1還能省去每個處理都要特別指定Library的麻煩。但也許未來有天規模會變大,所以Blog主還是建議,一開始就用方法3會比較好。

什麼時候你需要自己建Docker image,什麼時候不用?

前文的方法4,也就是這次的主題,Blog主建議只建議在自訂Library的數量很多,安裝時間長的時候使用。因為基本上方法4跟方法1一樣,都是全域性安裝,只是手法不一樣而已。

Azure的官方文件說,方法4的優點還可以維持執行環境(Golden container environment),不過老實說,Databricks在更新Runtime的時候,也不太會強制升級你的Cluster,他只會標記你的Runtime過時了,Cluster仍可以正常啟用(不安全就是啦),然後PIP只要有指定Library的版本,基本上執行環境都會是一樣的。所以個人是覺得這說法有點弱啦,但也許只是Blog主沒想到use case就是。

  • 避免複數Library的衝突(方法2&3)
  • 避免多安裝目前的處理不需要的Library(方法2&3)
  • 集中管理(方法3)
  • 減少大量Library造成冗長的下載及安裝時間(方法4)
  • 維持完全固定的執行環境(方法4)

以上簡單整理各種方法的優點。

建Databricks的Docker image的方法

建立能在Databricks使用的image,基本上就是自己建一個客製化的Databricks runtime。Databricks runtime的基底是Ubuntu,你可以用Ubuntu的image為基底建立,也可以直接用官方Docker Hub的Image為基礎再加調味料,Blog主用的是後者。

可以參考官方的GitHub,裡面有很多範例Dockerfile,像是Blog主幫同事建立的Image,裡面需要DBFS(為了連上Azure Storage Account的Blob),還需要R,Python本體,以及所有R跟Python的額外Library,還有一些依存的Linux套件。所以參考的是官方GitHub上的standard+python+R,三個Dockerfile的內容合起來,最後再加上額外Library,還有一些Linux的套件安裝指令,跑Build,就大功告成啦!

建Docker image時的注意點

RUN的數量越少越好

微軟的官方範例

Docker官方建議RUN的數量越少越好,這跟微軟每個Install就一個RUN的範例有點相違(不過Databricks的GitHub上,實際的Dockerfile裡,是一個RUN安裝全部的python library沒錯)。在Docker的運作方式裡,每多一個RUN,COPY或ADD都會多一層layer,也會增加Image容量。假設我們的目的是降低Databricks的Cluster啟動時間,那最終Docker的Image容量越小越好。當然,適當的分隔RUN也是有好處的,Blog主也沒做到非常嚴謹,有時為了未來Dockerfile好修改,會刻意把明明可以合再一起的指令隔開。

當需要修正內容,然後重新Build時,
前面的指令都沒變的情況,Docker會吃快取,然後處理得飛快

另外,Docker在Build時,每個RUN都會有快取,所以Blog主在寫Dockerfile時,會把自訂內容寫在最下面,跟上面必需的基礎功能分開,這樣當我發現自訂內容需要修正時,我重跑Build就可以直接吃到所有的快取,上面的基礎功能都能在幾秒鐘結束,Docker只要重跑最下面我修改的自訂部分而已。

用Azure Container Registry要開admin user

如果你選擇不用Docker Hub,用Azure Container Registry的話,Azure Container Registry裡面可以開啟admin user功能,會自動生成兩個key。原本Blog主沒很喜歡用admin user,所以在上傳Docker image的時候是用我自己的微軟帳號登入的,不過後來發現Databricks的cluster設定並不支援微軟帳號登入(明明都在Azure裡面),就是只能用帳號名稱跟key,只好回去啟用admin user。

需要新建Cluster

在Databircks的workspace admin settings裡啟用Docker功能後,並不會讓所有既有的Cluster都自動開放Docker功能,你需要去重新建立新的Cluster,並在一開始就設定好Docker的功能。

Databricks的Notebook用的是虛擬環境

Notebook執行時是用/databricks/python3裡的虛擬環境,而不是使用系統的python環境,所以在用pip install時,記得指定/databricks/python3/bin裡的pip(datatabricksruntime/standard:9.x以上的情況)。

DBFS不需要額外設定

DBFS(Databricks File System)方面,跟一般的Cluster一樣,只要在其中一個Cluster mount過了之後,用上Docker Container的Cluster也會自動mount,不需要額外設定。

其他小細節

使用Docker image的Cluster似乎就無法使用web terminal了,還有ML(Machine Learning)版本的Runtime無法使用Docker image。

總結

本次的文章就到這邊,當你的處理需要安裝非常多的Library時,使用本次介紹的Databricks Container Services能夠讓Cluster的啟動速度大幅提升,Blog主實測是10分減到5分。不過如果安裝的Library不多,或著有多個處理共用Cluster的情況,就比較不建議使用本次的方法了。未來Blog主如果還在Databricks有新發現,應該會上來再跟大家分享。


其他Blog主寫的Databricks文:
Azure Databricks的543
Azure Databricks 新功能 Files in Repos:自訂Python library有新做法

沒有留言:

張貼留言