0
本文作者: 老王 | 2017-02-13 12:23 | 專題:雷峰網(wǎng)公開課 |
雷鋒網(wǎng)按:技術(shù)圈流傳這樣一句話“人工智能背后的架構(gòu)和工程問題是武當(dāng)少林,屬于內(nèi)功。而算法則是招式,講究一時之快?!?br/>
再強的算法均需強大的架構(gòu)和工程作支撐,兩者缺一不可。
那么 AI 公司該如何設(shè)計承載產(chǎn)品背后龐大復(fù)雜的算法、工程核心架構(gòu)?本期雷鋒網(wǎng) AI 科技評論特邀極限元 CTO 康利強為大家講述《AI 公司該如何設(shè)計基于微服務(wù)的 AI SaaS 架構(gòu)》。
康利強,極限元 CTO,親自主導(dǎo)搭建了支撐極限元現(xiàn)有語音識別、計算機視覺、人機交互解決方案的構(gòu)架;20 年軟件研發(fā)、架構(gòu)設(shè)計以及項目管理經(jīng)驗,前億贊普集團核心架構(gòu)設(shè)計專家;美國 Borland 軟件公司中國機構(gòu)分布式存儲架構(gòu)師及項目負責(zé)人。
本期公開課視頻(共 44 分鐘)
如想獲取本期公開課的 PPT 資源,關(guān)注雷鋒網(wǎng)人工智能垂直微信公眾號“ AI 科技評論”,在后臺回復(fù)關(guān)鍵詞“架構(gòu)”,即可收到本期公開課 32 頁的 PPT 下載鏈接。
以下為分享正文:
今天我給大家分享的內(nèi)容是,基于微服務(wù)的 AI Saas 架構(gòu)設(shè)計。
既然要設(shè)計 SaaS 架構(gòu),先要了解何為 Saas?SaaS 是云計算的一種服務(wù)形式,關(guān)于云計算,我先簡要做個介紹:
什么是云計算?
云計算的分類(分層)
云計算新的服務(wù)方式
云計算是一種計算資源,按量付費,也就是你用多少就支付多少費用,可以便捷的訪問,通過網(wǎng)絡(luò)進入可配置的資源池,(資源包括網(wǎng)絡(luò),服務(wù)器,存儲,應(yīng)用軟件,服務(wù)),這些資源能夠被快速提供,我們只需投入很少的管理工作,或與服務(wù)供應(yīng)商進行很少的交互。
2006 年 8 月 ,Google 提出云計算的概念,到今天經(jīng)過了 10 年的發(fā)展,云計算越來越為大家所接受,很多人也在使用云計算提供的服務(wù),比如云主機、云存儲、網(wǎng)盤、云分發(fā)、云筆記等等;今天的直播也會用到其中的幾項服務(wù),比如云存儲、云分發(fā),由于用到云分發(fā),所以大家在看直播的時候會有一個比較低的延時。
接下來介紹 SaaS,除了SaaS 外,云計算也包含其他幾種類型:
主要有以下幾種類型:
IaaS(Infrastructure-as-a- Service):基礎(chǔ)設(shè)施即服務(wù)。消費者通過 Internet 可以從完善的計算機基礎(chǔ)設(shè)施獲得服務(wù)。也就是云主機,比如亞馬遜云,微軟云,阿里云等。
PaaS(Platform-as-a-Service):平臺即服務(wù)。PaaS 實際上是指將軟件研發(fā)的平臺作為一種服務(wù),以 SaaS 的模式提交給用戶。因此,PaaS 也是 SaaS 模式的一種應(yīng)用。PaaS 的出現(xiàn)可以加快 SaaS 的發(fā)展,尤其是加快 SaaS 應(yīng)用的開發(fā)速度。需要用戶有一定的開發(fā)能力,比如谷歌的 GAE。
SaaS(Software-as-a-Service):軟件即服務(wù)。它是一種通過 Internet 提供軟件的模式,用戶無需購買軟件。例如:各種云存儲,網(wǎng)盤、云筆記。
近些年隨著 Docker 的發(fā)展,出現(xiàn)了一種新的服務(wù)形式:CaaS。
CaaS (Containers-as-a-Service): 容器即服務(wù)這是隨著近幾年docker的火熱而出現(xiàn)的一種新的服務(wù)形式,使應(yīng)用的打包與部署自動化,創(chuàng)建輕量、私有的 PAAS 環(huán)境,使持續(xù)集成/部署、測試自動化,部署可伸縮的 web app、數(shù)據(jù)庫和后臺服務(wù)。
因為 docker 基于 Linux Container(Namespace,cgroup,chroot等),抽象出 Libcontainer 的接口,docker 運行于 Libcontainer 接口之上而不關(guān)心底層實現(xiàn),所以這種服務(wù)就叫做 CaaS。
這是一個簡化版的云計算分類,通過這個圖可以一目了然看到它們之間的關(guān)系。
既然講架構(gòu)設(shè)計,所以要了解一下架構(gòu)模式,題目是基于微服務(wù)的架構(gòu)設(shè)計有微服務(wù),那么是不是有宏大的服務(wù)呢,答案是肯定的。
一般來說,有以下兩種架構(gòu)模式:
單體式架構(gòu)(Monolithic Architecture)
微服務(wù)架構(gòu)(Microservices Architecture)
下面我們來看一下單體式架構(gòu):
單體式架構(gòu)就是所有功能打包運行在一個進程,比如一個war包,從這個架構(gòu)圖我們也可以看到,這是一個叫車應(yīng)用,中間部分是一個整體,包含很多功能,有乘客管理,通知,支付,司機管理 ,路線規(guī)劃等功能。
優(yōu)點是開發(fā),部署,測試,水平擴展比較容易,可以放到一個工程,打一個包,擴展的時候只把這一個包復(fù)制到新的位置即可。缺點就是隨著功能增多,代碼變多, 維護成本高,交付周期長。
與此同時,不同模塊發(fā)生資源沖突時,擴展將會非常困難。造成資源的浪費,有的要大內(nèi)存,有的高帶寬,有的要大的存儲空間等。為了同時滿足這些條件,這樣就造成了資源的浪費。
還有一個問題是,技術(shù)選項成本高,必須謹慎選擇,因為一旦選定很難更改,如果要更改的話,肯能要全部推到重來。另外可靠性也存在問題,一個模塊故障會影響整個服務(wù)。
在了解微服務(wù)之前,首先了解什么是微服務(wù),其次需要了解微服務(wù)架構(gòu)的設(shè)計要點,最后需知道微服務(wù)的優(yōu)缺點。先看一下什么是微服務(wù)?
微服務(wù)沒有一個公認的確切定義,但是有一些共性,微服務(wù)是是面向服務(wù)架構(gòu)的一種特例,有以下特性:
容易替換(升級)。
服務(wù)輕量級,可獨立部署,構(gòu)建發(fā)布自動化。
與其他服務(wù)通過網(wǎng)絡(luò)協(xié)作完成任務(wù)。
根據(jù)功能來劃分服務(wù),比如用戶前端,推薦,物流,賬單等。
可以用不同的語言、數(shù)據(jù)庫、軟硬件實現(xiàn)。
所以微服務(wù)本身天然就具有模塊化特性,適合于持續(xù)交付的開發(fā)部署,業(yè)務(wù)改變只需要重新發(fā)布部署少量的服務(wù)。了解微服務(wù)以后,進入今天的主題:為微服務(wù)架構(gòu)設(shè)計。
我們知道,人工智能的核心是機器學(xué)習(xí),因為機器不會自己學(xué)習(xí),所以要明確指明一些特征來讓機器知道符合這個條件的是什么,符合那個條件的是什么,這就需要編寫復(fù)雜的程序來讓機器來學(xué)習(xí),在某些場合,隨著需要的特征約來越多,編寫程序越來越困難,我們無法用足夠?qū)嵱貌⑶铱煽康姆绞矫鞔_指定所要優(yōu)化的特征。
以讓機器識別一只貓為例,假設(shè)這只貓是白色的,先不考慮其他特征,只說顏色特征。其它特征+白色這兩個特征讓計算機知道這是一只貓,那么來一只黑色貓就不認識了,或者來一只加菲貓計算機就有可能就會把它識別成色情圖片了。
這就導(dǎo)致所需的特征越來越多,這時候發(fā)現(xiàn)程序沒法寫了。于是深度學(xué)習(xí)順勢而生,大量數(shù)據(jù)通過深度神經(jīng)網(wǎng)絡(luò)的訓(xùn)練,讓計算機學(xué)習(xí),機器會自己提取特征并跟測試集來比較,然后自己調(diào)整進行下一輪的訓(xùn)練,直到訓(xùn)練出合適的結(jié)果。所以說目前的 AI 更多是數(shù)據(jù)的比拼。
首先我們要了解 AI 能做什么,AI 可以做一些色情檢測、廣告檢測、涉爆涉恐言論以及電信詐騙檢測,這些都是 AI 可以做的事情。用 AI 來做的話可以節(jié)省大量的人力,但是,不是所有公司都有能量構(gòu)建 AI 系統(tǒng),從上圖中可以看出,構(gòu)建 AI 系統(tǒng)需要大量數(shù)據(jù),需要大量計算資源,需要專業(yè)技術(shù)人員。
所以隨著社會分工越來越細,專注于自己的業(yè)務(wù),專業(yè)的事情交給專業(yè)的公司來做就好,避免自己精力過于分散。以直播平臺為例,其需要檢測上面所述的一些違規(guī)內(nèi)容,也可以用 AI 來檢測。但是不一定要自己做 AI 系統(tǒng),你可以把更多的精力放在直播的流暢度、延時、互動性等提升上。
由于 AI SaaS 需要提供多種服務(wù),不同的服務(wù)需要不同的計算資源,AI 算法需要 GPU 資源,所以微服務(wù)的架構(gòu)更適合 AI SaaS。
傳統(tǒng)的架構(gòu)設(shè)計一般從這 5 個方面來設(shè)計,所謂的五視圖:邏輯架構(gòu),開發(fā)架構(gòu),運行架構(gòu),部署架構(gòu),數(shù)據(jù)架構(gòu)。
邏輯架構(gòu)主要是考慮需求,并根據(jù)職責(zé)劃分邏輯層,子系統(tǒng)、子模塊兒,同時考慮模塊兒的接口。
開發(fā)架構(gòu):源文件管理,工程組織方式,依賴的庫、框架,以及構(gòu)建系統(tǒng)。
運行架構(gòu):子系統(tǒng)需要幾個進程,進程之間怎么通信,以及怎么啟停。
部署架構(gòu):系統(tǒng)的物理架構(gòu),需要那些服務(wù)器,服務(wù)器之間的網(wǎng)絡(luò)拓撲結(jié)構(gòu),以及系統(tǒng)運行到那些服務(wù)器上。同時還需要考慮冗余,因為系統(tǒng)出問題是必然的。
邏輯架構(gòu)是根據(jù)需求劃分的幾個邏輯層,主要分為接入層,業(yè)務(wù)層,存儲層,管理層,這幾層分別有不同的服務(wù)。
整體架構(gòu)
上面講到邏輯架構(gòu)要根據(jù)需求劃分子系統(tǒng),子模塊,以及定義模塊的接口。對應(yīng)的微服務(wù)架構(gòu)的話就是怎么根據(jù)需求分解成微服務(wù),以及怎么定義服務(wù)間的通訊接口。與單體應(yīng)用不同的是還需要確定服務(wù)的位置,所以需要服務(wù)定位。此外,由于微服務(wù)通過網(wǎng)絡(luò)來訪問,所以需要有對應(yīng)的故障處理機制。
服務(wù)的劃分
所以下面就從服務(wù)的劃分,接口設(shè)計,服務(wù)定位(注冊與發(fā)現(xiàn)),故障處理來講解一下邏輯架構(gòu)。
第一,服務(wù)的劃分,服務(wù)劃分的原則跟面向?qū)ο笤O(shè)計原則基本一致,單一職責(zé),高內(nèi)聚,低耦合。我們知道對于需求來說分為功能性需求跟非功能性需求,那么微服務(wù)也按這種方式來劃分。
首先來看功能性需求:
API Server api 的接入,認證,負載均衡。
Service Registry服務(wù)注冊與發(fā)現(xiàn)。
AI 網(wǎng)關(guān):AI 服務(wù)的流量控制與負載均衡。
AI 服務(wù):提供 AI 服務(wù),比如圖像識別,語音識別等。
計費服務(wù) 計費的管理
文件服務(wù) 存儲文件
非功能性需求
緩存服務(wù):提高性能
監(jiān)控服務(wù):監(jiān)控系統(tǒng)及應(yīng)用的情況
日志服務(wù):應(yīng)用日志收集分析
接口設(shè)計
接口設(shè)計分為:對外接口,內(nèi)部接口。為了方便多語言的開發(fā),所以對外提供 http 協(xié)議接口,不一定完全按照 REST ful 去設(shè)計,根據(jù)業(yè)務(wù)確定。每個請求需要確定訪問者的身份,而 http 無狀態(tài),故可以用 JSON Web Token(JWT) 來做認證。
內(nèi)部調(diào)用分為兩種:同步調(diào)用,異步調(diào)用。
同步調(diào)用可以這幾種方式去做:REST API ,RPC框架,比如 thrift,gRPC 等,或者可以基于 PB 自定義通訊,當(dāng)然也可以完全用完全自定義的協(xié)議,根據(jù)公司開發(fā)資源靈活選擇。
異步調(diào)用主要是通過消息隊列去做 (RabbitMQ,RocketMQ,kafka,NSQ)等。
服務(wù)定位(注冊與發(fā)現(xiàn))
既然有這么多服務(wù),這些服務(wù)有會同時存在好多實例,那么怎么去定位這些服務(wù)也是一個要解決的問題。
這就是服務(wù)定位,也就是服務(wù)注冊與發(fā)現(xiàn)。
為什么需要定位呢,一是服務(wù)位置的變化,另一個就是數(shù)量的變化。服務(wù)位置可能會變化由于某些原因要遷移到不同的 ip 地址,數(shù)量會變化,比如增加一臺服務(wù)器,需要對外提供服務(wù),就要告訴網(wǎng)關(guān),如果用固定配置文件方式就會比較麻煩,所以需要動態(tài)的去獲取服務(wù)的位置。
現(xiàn)在常用的幾個開源服務(wù)包括 ZooKeeper、Etcd、Consul 等,服務(wù)啟動注冊到注冊表服務(wù),當(dāng)一個請求到來時,網(wǎng)關(guān)去注冊表查詢。服務(wù)位置,然后把請求轉(zhuǎn)發(fā)到其中某一個服務(wù),服務(wù)與注冊表服務(wù)之間會定時檢測,如果一個服務(wù)掛了,那么就會從注冊表刪除,同時通知網(wǎng)關(guān),這樣就可以避免訪問到失敗的服務(wù)。而如果有新加入的服務(wù),它會注冊到注冊表,網(wǎng)關(guān)也會收到通知,這樣請求就可以轉(zhuǎn)發(fā)到新服務(wù),不需要手工做任何的配置。
故障處理
剛才提到服務(wù)掛了注冊表會檢測到,但是并不是實時的,所以這個時候的調(diào)用就會失敗,那怎么處理這些調(diào)用失敗呢?通過故障處理這節(jié)我們有以下這些處理方式。我們可以看到有超時機制、限流、熔斷機制、負載均衡、降級(本地緩存)。在解釋這些處理機制之前我,我們先通過這個圖看一下如果出現(xiàn)故障,不管是服務(wù)掛了也好,網(wǎng)絡(luò)斷了也好,還是訪問量太大處理不過來,會發(fā)生什么情況,會造成服務(wù)不可用,沒法處理新的請求。
這種情況的第一個處理方式就是超時機制,就是每個調(diào)用都要有個超時時間,防止資源被無限制的占用,這樣避免影響后面的調(diào)用。如果流量太大處理不過來,就可以通過限流來處理,比如用請求隊列大小來限制訪問量,避免訪問量過大造成服務(wù)不可用,就像早期的 12306,想必刷過票的都有體會。
斷路器模式:就是先跟蹤成功、失敗調(diào)用的次數(shù),當(dāng)比率達到設(shè)定的閾值,打開斷路器,后續(xù)的調(diào)用就會立即失敗,這時候斷路器會啟動一個定時器,來給服務(wù)器恢復(fù)服務(wù),計時器時間到了就會去允許一定數(shù)量的請求操作,而不是立即返回失敗,如果全部調(diào)用成功就關(guān)閉斷路器開始正常服務(wù),否則繼續(xù)啟動定時器,進入下一個循環(huán)。
負載均衡方式:后面對應(yīng)多個服務(wù)實例,一個服務(wù)失敗會自動切換到另一個,這也是一種故障處理方案。某些業(yè)務(wù)情況直接返回錯誤可能不太友好,所以可以返回緩存的數(shù)據(jù),或者返回默認的數(shù)據(jù),比如別人發(fā)了朋友圈,你刷新的時候還給你返回舊的數(shù)據(jù),也不會影響你的體驗,過一會兒再一刷,他就出來了。邏輯架構(gòu)這部分就結(jié)束了,上面所說的這些功能都是需要開發(fā)來實現(xiàn)的,所以下面我們看一下開發(fā)架構(gòu)。
開發(fā)架構(gòu)主要是一些軟件資源以及人員的問題。隨著開源軟件的發(fā)展,它們可以減少我們大量的工作,我們有許多服務(wù),這些服務(wù)之間需要通訊,所以可以選擇一些通訊框架,比如 netty,libevent 等,這樣可以減少很多工作量,提高效率。還有一些開源應(yīng)用可以直接使用,如 nginx,redis,mysql,prometheus,grafana 等。
nginx 可以用作反向代理,redis 用于緩存,mysql 作為數(shù)據(jù)庫,Prometheus,Grafana 用于監(jiān)控。
源碼版本控制可以直接用 gitlab 社區(qū)版,當(dāng)然也可以用 GitLab 收費版。如果完全開源,那么也可以直接用 GitLab 的免費服務(wù)。
Bug 管理選擇 redmine,當(dāng)然也可以用 jira,那就需要不少的費用。
人員方面根據(jù)團隊擅長的語言,比如 Java,可以做網(wǎng)關(guān),計費系統(tǒng)等,而 AI Server 通常用 C++ 去做,當(dāng)然有些應(yīng)用也可以用 Go 語言做,如 prometheus 就是用 Go 寫的。
主要有一下幾個進程,如圖所示,請求的流程如圖所示。
確定了運行的服務(wù),那么接下來我們來看看怎么部署這些服務(wù),也就是服務(wù)的部署架構(gòu)。
首先看下怎么部署:
每個主機一個 Service 實例,這些主機可以是真實主機、虛擬機、容器、Docker。部署的時候要考慮災(zāi)備,可以同一個服務(wù)部署多個實例。對于微服務(wù)來說,由于服務(wù)數(shù)量比較多,手工部署比較繁瑣,也容易出錯,所以需要一些自動化的部署工具。比如 puppet,saltstack,chef,ansible,k8s(kubernetes) 是 Docker 的編排工具。CoreOS 提供 docker 的運行環(huán)境,精簡版的 Linux,很快的可以部署出一個系統(tǒng)出來,包括一些 Marathon/Mesos。
部署原則
API Gateway 對外提供服務(wù),所以需要高帶寬,AI 服務(wù)部署到 GPU 計算資源的主機。文件服務(wù)部署存儲空間大的主機,緩存服務(wù)需要內(nèi)存大的主機。所有應(yīng)用都部署在云上,方便擴容。
部署架構(gòu)圖
雷峰網(wǎng)原創(chuàng)文章,未經(jīng)授權(quán)禁止轉(zhuǎn)載。詳情見轉(zhuǎn)載須知。