天天看點

成為頂尖機器學習算法專家需要知道哪些算法?

介紹

大家好,我是螞蟻金服的魯直,是螞蟻金服微服務團隊的 TL,同時也負責 SOFA 對外開源的相關事宜。

非常感謝中生代社群王友強,螞蟻金服右軍的組織,讓我今天能夠有機會給大家做一個分享。我今天給大家帶來的分享是「SOFA 分布式架構的演進」。

在開始之前,可能很多人不太清楚 SOFA 是什麼東西,這裡先做下簡單地介紹。SOFA 是螞蟻金服自研的一套金融級分布式中間件,從寫下第一行代碼到今天已經有将近 10 年的時間,包含了應用容器,RPC,消息,資料中間件,分布式事務,限流,熔斷,分布式鍊路追中等等架構,算是一個分布式中間件全家桶。随着螞蟻金服這 10 年業務的飛速發展,SOFA 也在這個過程中得到了大量地錘煉,快速地成長,支撐了每年雙十一,雙十二,新春紅包等大型活動。大家可以從下面這種圖中看到 SOFA 涵蓋的範圍。在今年 4 月份,SOFA 開始了開源之路,目前已經有部分元件開源在了 Github 上面,歡迎大家圍觀 star:https://github.com/alipay 。

成為頂尖機器學習算法專家需要知道哪些算法?

早期子產品化

要講 SOFA 的發展過程,要從支付寶的早期開始,在支付寶的早期,支付寶的全站的架構非常簡單,就是一個簡單的分層架構,類似于下面這張圖:

成為頂尖機器學習算法專家需要知道哪些算法?

最前面是一個負載均衡器,負載均衡器的流量直接打到當時支付寶唯一的系統錢包系統裡面來,然後錢包系統後面連着一個資料庫。這種系統的分層設計在剛開始系統流量不高,團隊不大的時候,沒有太大的問題,但是當團隊規模擴大,團隊内部以及團隊之間的協作成本就會越來越高,是以在 SOFA 最開始的版本中,我們引入了子產品化的方案,來為系統解決系統内部的協作的問題,也為服務化做準備。

SOFA 的子產品化不同于一般的子產品化的方案,在一個一般的子產品化的方案裡面,隻是在代碼的組織結構上進行了子產品化的拆分,負責同一個功能的代碼内聚到到一個 Maven 子產品下面,最終打包成一個 JAR 包。這種子產品化的方案有一個缺陷,就是沒有考慮運作時的問題,在這種子產品化的方案裡面,一般上都隻有一個 Spring 的上下文,意味着一個子產品裡面的 Bean 可以任意地通路另一個子產品裡面的 Bean 而沒有任何控制,長期來看,這種情況會導緻子產品和子產品之間在運作時的高度耦合。

為了解決這個問題,SOFA 的子產品化方案給每一個子產品都加上了一個獨立的 Spring 上下文,預設的情況下,一個子產品不能直接引用另一個子產品的 Bean。當需要引用另一個子產品的 Bean 的時候,需要在代碼中通過類似于 RPC 的服務釋出和引用來解決,比如當子產品 A 需要調用子產品 B 的 SampleService 這個 Bean 的時候,子產品 B 可以通過以下的代碼來提供服務:

<sofa:service ref="sampleService"

interface="com.alipay.sofa.sample.SampleService"/>

另一個子產品 B 就可以通過以下的代碼來引用服務:

<sofa:reference id="sampleService"

interface="com.alipay.sofa.sample.SampleService"/>

通過 SOFA 的子產品化方案改造之後,一個系統的子產品可以如下圖所示,圖中的紅線就是 JVM 的服務釋出和引用:

成為頂尖機器學習算法專家需要知道哪些算法?

從單應用到服務化

通過 SOFA 引入子產品化的方案之後,在一定程度上幫助業務解決了研發效率的問題。但是随着業務的不斷地發展,團隊規模的不斷擴大,單純靠一個系統内的子產品化已經難以滿足業務的訴求,是以,在這個時期,我們開始了服務化的改造,這個時候,SOFA 之前的子產品化的方案的另一個優勢就能夠展現出來了,當我們将一個系統的多個子產品通過服務化拆成多個系統的時候,隻需要在原來的 <sofa:service/> 以及 <sofa:reference/> 裡面加上一個協定,就可以将本地的子產品間的調用變成 RPC 的調用:

<sofa:service ref="sampleService"

interface="com.alipay.sofa.sample.SampleService">

<sofa:binding.bolt/>

<sofa:service/>

<sofa:reference id="sampleService"

interface="com.alipay.sofa.sample.SampleService">

<sofa:binding.bolt/>

<sofa:reference/>

在服務化的早期,我們引入了 F5 作為服務間調用的負載均衡裝置,也通過 F5 來做服務發現,如下面的架構圖所示:

成為頂尖機器學習算法專家需要知道哪些算法?

但是,運作了一段時候之後,我們發現 F5 成了一個瓶頸,所有的流量都要 F5,對 F5 本身會造成比較大的壓力,另外,這種負載均衡裝置在處理長連接配接的時候會有一些問題,服務端擴容操作可能會導緻最終流量不均衡,是以,在後面,我們引入了自研的服務注冊中心,變成了下面的這種結構:

成為頂尖機器學習算法專家需要知道哪些算法?

這裡面之是以不選擇 ZK 的原因是因為考慮到 ZK 是一個 CP 的系統,在發生網絡故障的時候,會發生嚴重地不可用。是以 SOFA 自己的服務注冊中心 SOFARegistry 設計成了一個 AP 的系統,最大程度的保證可用性,放棄一定程度的一緻性。

目前 SOFARegistry 正在進行開源的準備工作,在準備完成之後,會公布出來。

到了這個階段,支付寶的系統已經完成了基本的服務拆分。

SOFA資料拆分

在通過服務化解決了應用的水準擴容的問題之後,後面,我們遇到了資料庫的容量的問題,原來,支付寶的所有的資料都在一個大的資料庫裡面,首先想到的就是進行垂直的拆分,将不同的業務的資料放到不同的資料庫裡面去。如下圖所示:

成為頂尖機器學習算法專家需要知道哪些算法?

但是随着交易量的上升,類似交易庫這種,會首先面臨大量的交易的資料,單庫都放不下這麼多的事情,這個時候,就需要考慮做水準拆分, 比如向交易庫這種,我們就可以根據使用者的 ID 進行拆分,變成類似于下面的這種結構:

成為頂尖機器學習算法專家需要知道哪些算法?

資料庫的分庫分表我相信很多人都已經聽說過,這裡也分享一下如何确定需要有多少的庫, 需要有多少的表。首先是最小的庫的數量,可以通過業務峰值 TPS 除以單庫容量上限 TPS 來計算。然後是最小的表的數量,可以通過機關時間業務量乘以存儲時長再除以單表的容量上限來進行計算。

SOFA分布式事務

在經過資料庫的拆分之後,在金融場景下很自然地,就面臨了一個新的問題,就是分布式事務的問題,原來所有的資料都在一個庫裡面,那麼隻需要資料庫支援事務就可以了。在資料庫經過了拆分之後,就需要通過引入分布式事務來協調多個資料庫之間的事務問題了。

在 SOFA 裡面,通過自研了一個 TCC 的架構來解決了分布式事務的問題,也就是現在的 SOFA DT X ,在 TCC 模型下,會有一個事務的發起方,這個一般上是一個業務系統,它會現在業務系統中去啟動一個本地事務,然後調用所有的事務參與方的 Try 接口,如果 Try 通過之後,再調用所有的事務的參與方的 Commit 接口進行事務送出。如果 Try 失敗,則調用所有的事務參與方的 Cancel 接口進行事務復原。在 TCC 中,一旦一階段 Try 通過之後,二階段就 Commit 就必須成功,但是現實情況中,總會因為各種各樣的問題,會有 Commit 失敗的情況發生。是以,在 SOFA 的 DTX 中,還有一個單獨的服務,專門用于重試二階段,讓這些事務最終能夠成功。

成為頂尖機器學習算法專家需要知道哪些算法?

當然,在 SOFA 裡面,除了對分布式事務做同步的服務的事務支援之外,針對異步的消息,也提供了事務消息的支援,SOFA 裡面的事務消息的支援可以看如下這張圖:

成為頂尖機器學習算法專家需要知道哪些算法?

在事務消息裡面,發起方會在一個本地事務中去發送一個消息,SOFA 的消息中心接收到這個消息之後,會落到消息中心的存儲裡面,但是這個時候,消息中心并不會向訂閱方投遞消息;等到發起方的本地事務結束,會自動給消息中心一個通知,告訴消息中心本地事務已經送出或者復原,如果消息中心從發起方得到的通知是事務已經送出,就會将消息發送給消息的訂閱方,如果消息中心從發起方得到的通知是事務已經復原,那麼消息中心就會從存儲中将消息删除掉。當然,發起方給消息中心的通知在中間也可能會因為各種各樣的問題到丢失,是以,一般上事務的發起方還需要實作一個消息回查的接口,當消息中心在一段時間内沒有收到事務的發起方的通知的時候,消息中心會主動回查發起方,主動咨詢發起方對應的事務的狀态,根據主動拿到的狀态來決定消息是要發送還是删除。

在螞蟻内部,分布式事務和事務型消息作為 SOFA 在事務上的解決方案都在被廣泛地使用,其中分布式事務一般上用在強同步的場景,比如轉賬的場景,而事務型的消息一般上被用在異步的場景,比如消息記錄的生成等等。

合并部署

在經過了幾年的服務化之後,因為螞蟻的業務的特點,出現了一些比較長的業務鍊路,比如從淘寶過來的支付鍊路,可能中間涉及到十幾個系統,這些系統之間在一次請求中的互相調用非常頻繁,導緻中間 RPC 消耗地時間比較高,并且像支付鍊路這樣,其實上下遊關系非常密切,在運維操作上,因為大促而導緻的容量評估,擴容縮容也都必須一起操作,是以,在 SOFA 中,我們引入了合并部署的概念,來解決這種長的業務鍊路中的 RPC 調用耗時的問題,也期望通過合并部署能夠讓關鍵系統更好地去做容量評估。合并部署整體的示意圖如下圖所示:

成為頂尖機器學習算法專家需要知道哪些算法?

所謂的合并部署,從上圖中可以看出,就是将相關聯的一些系統部署到一個 SOFA 運作時下面,每個系統之間通過單獨的 ClassLoader 加載,防止出現類沖突,和服務化的過程剛好相反,在合并部署裡面,SOFA 會自動地将這些系統之間的 RPC 調用轉換成 JVM 調用,進而節省了類的成本。

在合并部署裡面,有門面系統和非門面系統的概念,隻有門面系統會對外暴露服務,外部的系統隻能看到門面系統釋出的服務,非門面的系統全部為門面系統服務。

雖然這些系統部署最終是部署在一起的,但是開發還是有獨立的團隊進行開發,是以在研發上,并沒有太大的差比,合并部署更多的是一種運維以及部署上的優化。

單元化

剛才在資料拆分的那張圖裡面知道,一個應用對應的資料庫進行了拆分之後,對于一個應用的執行個體來說,它必須連到分庫後的所有的資料庫,才能夠確定任何請求進入的時候都可以找到資料,這種方式在應用的執行個體數量增加之後,就會出現資料庫連接配接的瓶頸,如下圖所示:

成為頂尖機器學習算法專家需要知道哪些算法?

為了解決資料庫連接配接的瓶頸的問題,我們開始引入了單元化的概念,在螞蟻叫 LDC(邏輯資料中心),單元化的概念如下圖所示:

成為頂尖機器學習算法專家需要知道哪些算法?

在單元化中,一個邏輯資料中心隻處理一個資料分片的請求,如果說資料是按照使用者來進行分片的話,涉及到一個使用者的請求隻會在一個邏輯資料中心裡面來處理,通過這樣的設計,一個應用連的資料庫隻要和對應的邏輯資料中心的資料分片一緻就可以,這樣,就可以大量地減少資料庫上的連接配接數的壓力。而且利用這種邏輯資料中心的概念,理論上,如果資料庫的連接配接數不足,隻需要增加邏輯資料中心就可以。

ServiceMesh

前面講到的 SOFA 從演進過程中發展出來的能力,都是在螞蟻線上運作地非常成熟的一些東西,這幾年,雖然 Kubernetes 的普及,ServiceMesh 也變得越來越火,是以,SOFA 現在也在往 ServiceMesh 這個方向上演進,在螞蟻内部,有将近 2000 多個 SOFA 的系統,每次版本的更新都非常痛苦;另外,随着人工智能等領域的興起,Python 等語言越來越火,原來 SOFA 裡面所有的内容都是通過 Java 來做的,已經不能夠滿足目前業務的系統,我們需要也尋找一個方案去解決多語言的問題。剛好,通過 ServiceMesh,我們可以将 SOFA 裡面原有的一些能力下沉,比如服務發現,限流,熔斷等等,這樣,這些能力的更新一方面可以擺脫業務系統去自主更新,另一方面,也可以讓 SOFA 的體系更加友善地為其他的語言所服務。

目前 SOFAMesh 的 0.1.0 的版本也已經在 Github 上面開源,包括 Istio 的 Control Plane 的部分:

https://github.com/alipay/sofa-mesh ,

以及我們自研的 Data Plane 的部分:

https://github.com/alipay/sofa-mosn

總結

SOFA 的發展離不開螞蟻金服自身業務的發展,正是由于螞蟻金服自身業務的飛速發展,需要 SOFA 不斷地去解決各種各樣的問題,才有了 SOFA 的今天,當然,我們也深感螞蟻金服本身的業務的廣度和整個業界比起來真的是九牛一毛,是以在今年 4 月份,我們開始了 SOFA 的開源的程序,逐漸将 SOFA 裡面的各個元件開放出來,希望 SOFA 在整個社群中能夠得到更大的鍛煉,得到更多的回報,幫助 SOFA 進一步發展。對 SOFA 開源感興趣的,可以到我們的 Github 的位址上給一個 star:https://github.com/alipay

原文釋出時間為:2018-10-17

本文作者:魯直

本文來自雲栖社群合作夥伴“

中生代技術

”,了解相關資訊可以關注“

”。