寫一篇好技術(shù)文章的經(jīng)驗(yàn)秘籍,全在這兒了
679
2025-03-31
作為一名AI云平臺(tái)研發(fā)工程師,之前更多地,都是以“服務(wù)化”的角度去看云平臺(tái),就是怎么把應(yīng)用改造成http等服務(wù),然后部署到云上。較少?gòu)摹鞍姹竟芾怼薄ⅰ胺€(wěn)定性”這樣一個(gè)視角去看云平臺(tái)。直到最近對(duì)SageMaker平臺(tái)進(jìn)行了一番深度體驗(yàn)和分析,加上本身的承擔(dān)的集成解耦工作,有點(diǎn)陰差陽(yáng)錯(cuò)地,把這個(gè)視角開(kāi)啟了。
一、軟件設(shè)計(jì)中的變與不變
首先得從一句老話說(shuō)起,“唯一不變的就是變化”。
第一次聽(tīng)到這句話,是在大學(xué)的JAVA課上,充滿哲學(xué)智慧的一句話,若是配上網(wǎng)上產(chǎn)品經(jīng)理與碼農(nóng)間因“改需求”引發(fā)的段子或動(dòng)圖,又多了幾分碼農(nóng)自黑的味道。當(dāng)然也正是因?yàn)檫@句話,才會(huì)出現(xiàn)“軟件架構(gòu)設(shè)計(jì)”、“軟件可擴(kuò)展性”等概念,才有了架構(gòu)師這樣一個(gè)面向“變化”編程的工種。在我的理解中,面向“變化”編程,無(wú)非就是“業(yè)務(wù)抽象”、“組件重用”、“分層解耦”三板斧。下面我們來(lái)聊聊“分層解耦”。
在軟件建模的世界里,沒(méi)有什么是加一層解決不了的,如果有,那就加兩層。MVC三層架構(gòu)、DDD的四層模型、OSI網(wǎng)絡(luò)七層協(xié)議,莫不如是。
繞了一大圈,總算從“變化”引出“分層”這個(gè)主角了。一般地,“分層”主要有兩大功能,一個(gè)是分邊界劃?rùn)?quán)責(zé),使層次更清晰。另一個(gè)是隔離變化,解耦合。復(fù)雜軟件最擔(dān)心的是“蝴蝶效應(yīng)”,牽一發(fā)動(dòng)全身。
假如我問(wèn)你,在上圖的分層架構(gòu)中,最怕出現(xiàn)變化的是哪一層?相信很多人會(huì)不假思索地回答是“領(lǐng)域模型”層,做為分層結(jié)構(gòu)中的最底層,這里的變化是最有可能形成“蝴蝶效應(yīng)”的。我也是這樣認(rèn)為的,所以在此之前,我最關(guān)心的是“領(lǐng)域模型”層,一個(gè)好的軟件,對(duì)業(yè)務(wù)領(lǐng)域的理解和抽象建模應(yīng)該是有一定的超前、預(yù)見(jiàn)性的,這是顯而易見(jiàn)的。
直到近來(lái)搞解耦,一邊被下游服務(wù)追著懟,一邊追著上游服務(wù)懟,前些天和主管討論一個(gè)問(wèn)題的時(shí)候,才意識(shí)到,當(dāng)從系統(tǒng)的外面看進(jìn)來(lái),好像“接口層”的穩(wěn)定性要比“領(lǐng)域模型層”的穩(wěn)定性要重要。剛意識(shí)到這點(diǎn)時(shí),有點(diǎn)懵圈,仿佛三觀被刷新了一樣,在軟件中,不應(yīng)該是越底層,功能便越基礎(chǔ)越簡(jiǎn)單,越上層,功能便越是豐富和復(fù)雜么?不應(yīng)該是越簡(jiǎn)單的東西,便越可能穩(wěn)定么?
既要上面的“接口層”穩(wěn)定(簡(jiǎn)單),又要底層的“模型層”穩(wěn)定(簡(jiǎn)單),夾逼原理,量中間層再?gòu)?fù)雜也復(fù)雜不到哪里去了。所以,復(fù)雜都是自找的?所以加班都是自作的?答案顯然是否定的,好的架構(gòu)設(shè)計(jì)能減少不必要的工作量,卻不能消滅必要的工作量,一如“變化”不能被消滅,“唯一不變的就是變化”。
二、軟件設(shè)計(jì)中的繁與簡(jiǎn)
在上節(jié)中,我們從“變化”,引出“分層”,從分層引出“接口層”和“模型層”都要簡(jiǎn)單這樣一個(gè)近乎“五彩斑斕的黑”這樣的訴求。誠(chéng)然,“五彩斑斕的黑”是不可能的了,這輩子都不可能的,但“接口層”和“模型層”都要穩(wěn)定這樣的訴求,還是可以盡力試下的。
在我看來(lái),解決系統(tǒng)復(fù)雜度的方法主要可以分為以下三大類:
【化繁為簡(jiǎn)】:也即“抽象”大法,就像小學(xué)數(shù)學(xué)中的合并同類項(xiàng)等等,在這類系統(tǒng)本身就是簡(jiǎn)單的,呈現(xiàn)出來(lái)的復(fù)雜性都是人為引入的,比如說(shuō),不熟悉系統(tǒng)的業(yè)務(wù)場(chǎng)景,對(duì)系統(tǒng)建模的切入角度錯(cuò)了,抓不到系統(tǒng)的常變點(diǎn)和穩(wěn)定點(diǎn)等等。
【刪繁就簡(jiǎn)】:也即“砍需求”大法,此策略常用于擁有較多的平行應(yīng)用場(chǎng)景的軟件系統(tǒng)中,這時(shí)候就可以通過(guò)在文檔中標(biāo)明該系統(tǒng)支持和不支持的場(chǎng)景范圍來(lái)降低系統(tǒng)復(fù)雜度,這種“砍”法比較粗暴,還有一種比較優(yōu)雅的“砍”法,即通過(guò)增加系統(tǒng)的可擴(kuò)展性來(lái)砍掉需求,所謂“這個(gè)需求不是我不支持,是需要你通過(guò)自己開(kāi)發(fā)插件的方式來(lái)支持”。
【分而治之】:也即“拆分”大法,此策略常用于應(yīng)用場(chǎng)景的垂直棧特別深的系統(tǒng),由于每部分間不是平行關(guān)系,且缺少任意一個(gè),整個(gè)系統(tǒng)的功能就不是完備的,導(dǎo)致了這種系統(tǒng)根本無(wú)法通過(guò)“砍需求”大法來(lái)簡(jiǎn)化,只能通過(guò)劃分邊界來(lái)使其局部簡(jiǎn)單化。
現(xiàn)實(shí)中,系統(tǒng)復(fù)雜度的分類與解決方法并不如上述分類中那么涇渭分明,更多的是你中有我我中有你,舉個(gè)栗子,像大名鼎鼎的領(lǐng)域驅(qū)動(dòng)建模(DDD),試圖通過(guò)整合領(lǐng)域?qū)<液统绦騿T的經(jīng)驗(yàn)知識(shí)來(lái)捕捉系統(tǒng)中最本質(zhì)的元素,減少因?yàn)檎J(rèn)知偏差人為引入的復(fù)雜度,很明顯針對(duì)的是上述的【化繁為簡(jiǎn)】;像在“微服務(wù)”這種架構(gòu),很明顯對(duì)的是上述的【分而治之】,但在現(xiàn)實(shí)中,我們可以看到“領(lǐng)域驅(qū)動(dòng)建模”和“微服務(wù)架構(gòu)設(shè)計(jì)”的概念經(jīng)常會(huì)一起出現(xiàn),DDD被很多的人用來(lái)指導(dǎo)微服務(wù)的拆分。
鋪墊了這么多,此時(shí)我們回到本文一開(kāi)始關(guān)注的問(wèn)題。
如上圖,從上到下,為從前臺(tái)到后臺(tái),往往,前臺(tái)的功能比后臺(tái)更豐富。比如基于JAVA開(kāi)發(fā)的應(yīng)用的數(shù)目和功能是要比Java的JDK接口的功能豐富得多的。從廣義上說(shuō),某門語(yǔ)言的應(yīng)用可以看做該語(yǔ)言的前臺(tái),把樸素的語(yǔ)言功能包裝成一個(gè)個(gè)場(chǎng)景的解決方案。但是,根據(jù)我們上面的分析,要求接口層盡可能穩(wěn)定(簡(jiǎn)單),由【刪繁就簡(jiǎn)】大法,那就刪掉一些接口和功能吧,又因?yàn)檫@個(gè)垂直的應(yīng)用棧,去除的功能會(huì)影響整個(gè)應(yīng)用場(chǎng)景的功能,不能刪,故這部分“待刪除”的功能往往會(huì)被整合成另一個(gè)相對(duì)獨(dú)立的組件(胖前端)。【刪繁就簡(jiǎn)】大法最終演變成了【分而治之】。
如果你是一個(gè)傳統(tǒng)應(yīng)用軟件(非服務(wù)化發(fā)布)的工程師,對(duì)上述的這個(gè)演變描述也許會(huì)持反對(duì)意見(jiàn),以tensorflow為例,對(duì)外暴露的接口確實(shí)很重要,我在改動(dòng)的接口的時(shí)候同時(shí)更新下版本號(hào)不就好了么,比如從1.12改到1.13,完全沒(méi)有必要為了保持接口的穩(wěn)定,限制新功能的加入,甚至要把新功能拆成另一個(gè)組件來(lái)引入,這個(gè)有必要么?
對(duì)于傳統(tǒng)應(yīng)用軟件來(lái)說(shuō),確實(shí)沒(méi)有上述如此拆分的必要,這主要是因?yàn)楸疚挠懻摰膱?chǎng)景的前提是“接口層”的穩(wěn)定性很重要,甚至比“模型層”的穩(wěn)定性還要重要。這一般會(huì)出現(xiàn)在資源共用的場(chǎng)景中,比如云服務(wù),比如硬件驅(qū)動(dòng)等。最主要的區(qū)別在于,不出現(xiàn)資源共用的場(chǎng)景中,選擇權(quán)在客戶手上,比如tensorflow從1.X升級(jí)到2.X,連“模型層”都有調(diào)整,但是他沒(méi)有強(qiáng)迫用戶一定要去用2.X,1.X也依然可以下載可以安裝使用。這個(gè)在云服務(wù)的場(chǎng)景中就不一樣了,云服務(wù)的接口更新有些是非此即彼的更新(可以做到同時(shí)支持新舊版,維護(hù)成本比非云服務(wù)軟件大),選擇權(quán)不在客戶,比如某某網(wǎng)站換新版了,此時(shí)客戶的選擇是被動(dòng)的。
從版本管理的角度來(lái)看,傳統(tǒng)軟件以軟件安裝包的形式發(fā)布,其版本發(fā)布沒(méi)有試圖去修改歷史,即發(fā)布了1.0.0版本,如果1.0.0版本有BUG,他是通過(guò)發(fā)布1.0.1版本來(lái)修復(fù)這個(gè)BUG的,此時(shí)就算有人依賴于1.0.0的BUG實(shí)現(xiàn)了自己的業(yè)務(wù)邏輯也是不要緊的,只要不切1.0.1就好。而云服務(wù)以服務(wù)的形式發(fā)布,其版本發(fā)布更傾向于去刪除歷史,即便在云服務(wù)版本更新的時(shí)候會(huì)有支持新舊兩個(gè)版本的的策略,但這些都只是緩兵之計(jì),最終的目的都是在某天把前面犯下錯(cuò)(BUG)抹掉。
所以,在云平臺(tái)、云服務(wù)這類軟件中“接口層”的穩(wěn)定性往往要重于“模型層”的穩(wěn)定性,導(dǎo)致了它可能出現(xiàn)本文上述的“胖客戶”端演進(jìn)方式,把易變的功能抽到“客戶端”,客戶端以軟件安裝包的形式發(fā)布,減少因“接口”變更要維護(hù)多套接口的成本。同時(shí)服務(wù)端的接口也越來(lái)越簡(jiǎn)單,最后變成特別穩(wěn)定的基礎(chǔ)服務(wù)。從服務(wù)端的角度看,這也是一個(gè)“職責(zé)單一化”的演進(jìn)思路,服務(wù)端只要管好基本功能就好了,不要因?yàn)楣艿锰嘁氩环€(wěn)定因素。
三、從SageMaker的鏡像管理來(lái)看云服務(wù)的“胖前端”設(shè)計(jì)
啰嗦了一大堆,下面通過(guò)sageMaker來(lái)串一遍上述的分析。軟件系統(tǒng)的設(shè)計(jì)受眾多因素的影響,本節(jié)只是從“接口和版本”的角度來(lái)給出一些解讀,僅供參考。
下圖為sageMaker的模型導(dǎo)入界面,簡(jiǎn)單到有點(diǎn)簡(jiǎn)陋,作為一個(gè)AI Devops平臺(tái),竟然連常見(jiàn)的AI框架的鏡像都不提供,只是簡(jiǎn)單地提供了一個(gè)鏡像地址的輸入框。
仔細(xì)分析發(fā)現(xiàn),AWS是有提供AI引擎的預(yù)置鏡像的,只是這個(gè)東西不是SageMaker,是一個(gè)比較獨(dú)立的服務(wù)“Deep Learning Containers”(https://docs.aws.amazon.com/deep-learning-containers/latest/devguide/what-is-dlc.html)
從產(chǎn)品文檔的組織結(jié)構(gòu)上看,“Deep Learning Containers”歸屬于“Machine Learning”模塊下,與AI平臺(tái)“SageMaker”平級(jí),如下圖所示:
“Deep Learning Containers”對(duì)外開(kāi)源了其鏡像構(gòu)建項(xiàng)目:https://github.com/aws/deep-learning-containers
在開(kāi)源項(xiàng)目里面用文件同步了目前已發(fā)布的鏡像的信息:https://github.com/aws/deep-learning-containers/blob/master/available_images.md
SageMaker和“Deep Learning Containers”出現(xiàn)交集的地方有兩個(gè),一個(gè)是在SageMaker的studio界面中,提供了相關(guān)鏡像的下拉列表框供選擇(沒(méi)有明確說(shuō)明是training鏡像還是inference鏡像,估計(jì)是training鏡像):
另一個(gè)是在SageMaker自己官方的SDK中,可以通過(guò)“框架名”、“python版本”等信息檢索鏡像地址:https://github.com/aws/sagemaker-python-sdk/blob/99c56b273789ea0ed3a2d530c0ac1b66ce43bbb0/src/sagemaker/image_uris.py#L30
各個(gè)region提供的鏡像的信息也記錄在SageMaker SDK的代碼庫(kù)配置文件中(不是在SageMaker的數(shù)據(jù)庫(kù)):https://github.com/aws/sagemaker-python-sdk/tree/99c56b273789ea0ed3a2d530c0ac1b66ce43bbb0/src/sagemaker/image_uri_config
從上面可以看到盡管預(yù)置鏡像和“sageMaker”很相關(guān),AWS還是把它拆解出來(lái)了作為一個(gè)獨(dú)立的服務(wù)“Deep Learning Containers”,這個(gè)點(diǎn)在于保證各個(gè)服務(wù)都是最基本的,“職責(zé)單一”的,避免因?yàn)榉?wù)組合出現(xiàn)復(fù)雜的接口引入不穩(wěn)定因素。在兩個(gè)服務(wù)的交互上,SageMaker也頗有用心,堅(jiān)決保持原生網(wǎng)頁(yè)接口的“簡(jiǎn)陋”,把雙方的交互放到了studio和SDK中。與直接放原生網(wǎng)頁(yè)相比,studio和SDK更像前文中描述的以軟件安裝包交付的傳統(tǒng)軟件,其在版本變動(dòng)的時(shí)候,是在創(chuàng)造歷史,而不是試圖修改歷史。客戶無(wú)法自己選擇云服務(wù)的版本,但是可以自主選擇SDK的版本,盡管SDK的版本和云服務(wù)的版本有一定的配套關(guān)系,但相比于把SDK的功能放到云服務(wù)內(nèi)帶來(lái)的云服務(wù)版本頻繁變更風(fēng)險(xiǎn),已經(jīng)好很多了。
這個(gè)“厚重”的SDK和studio,也是上文中一直在說(shuō)的“胖客戶端”,這里要注意studio和網(wǎng)頁(yè)UI不是等價(jià)的,區(qū)別在于studio可以通過(guò)容器化來(lái)做到用戶自主選擇版本,比如A客戶在使用1.0.0版本的studio,同時(shí)B用戶可以使用1.2.2版本的studio,而AWS的那個(gè)網(wǎng)頁(yè)卻不是那么容易做到“千人千面”的(不要抬杠,這里意會(huì)就好)。
如果你有仔細(xì)分析過(guò)SageMaker,會(huì)發(fā)現(xiàn)從整個(gè)產(chǎn)品的演進(jìn)上,SageMaker的新功能越來(lái)越傾向于集成與studio和sdk中,如他的AI project和flow功能等,那個(gè)簡(jiǎn)陋到令人發(fā)指的網(wǎng)頁(yè)界面,會(huì)演變成像數(shù)據(jù)庫(kù)那樣的基礎(chǔ)服務(wù),提供SageMaker基本元素的CRUD功能。
其實(shí),最能體現(xiàn)SageMaker的“胖前端”設(shè)計(jì)思路的,是SageMaker的SDK,鑒于分析的“SDK”所需篇幅太大,本文最后臨時(shí)選了“Deep Learning Containers”來(lái)串一下,后續(xù)有機(jī)會(huì),可以好好扒扒SageMaker的SDK設(shè)計(jì)。
以安裝包形式發(fā)布的軟件,羨慕云服務(wù)可以集中刷新版本,修BUG于無(wú)形的優(yōu)勢(shì);以服務(wù)發(fā)布的軟件,卻羨慕以安裝包形式發(fā)布時(shí),接口的調(diào)整負(fù)擔(dān)不那么大的優(yōu)勢(shì)。不過(guò)羨慕歸羨慕,API作為一個(gè)產(chǎn)品的門面,即便在以安裝包形式發(fā)布的軟件中,也是要保持版本間接口的穩(wěn)定的。至于如何設(shè)計(jì)一個(gè)穩(wěn)定的API接口,給大家推薦一本這方面的好書《API Design for C++》,雖然是以C++為例,設(shè)計(jì)思維是通用的,電子版自行網(wǎng)上搜索就好。
云設(shè)計(jì) 架構(gòu)設(shè)計(jì)
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。