當時,章魚保羅作的預測,如今有企業專門在作了

2010 年南非世界盃,「預言帝」章魚保羅搶走了本來屬於球星的風頭,它精準的預測了德國國家隊的比賽結果;現實中,咱們每一個人也會對比賽結果進行娛樂性的預測,關注本身喜歡的球隊,而有這麼一家專業的公司,卻利用着大數據、人工智能、神經算法來給體育比賽結果預測,對體育進行服務 —— 智慧摩羯數據科技有限公司。前端

智慧摩羯數據科技有限公司,是一家專一於體育運動大數據分析服務的創新型科技公司,以賽事數據爲基礎,以大數據分析爲引擎,運用機器學習、深度學習等人工智能算法來實現全球體育比賽結果預測、體育運動指導、電子競技遊戲支持等服務。算法

智慧摩羯數據科技有限公司聯合創始人陳健,分享瞭如何解決隨着業務發展,系統愈來愈臃腫、應用變得愈來愈不易維護、不易擴展等問題,並分享智慧摩羯在搭建企業微服務中的相關經驗。如下爲演講正文:數據庫

大數據分析技術是企業的核心競爭力。主要的技術分爲兩部分:緩存

  • 第一部分是大數據技術;
  • 第二部分是應用的技術,即大數據服務和應用服務。

img

大數據服務跟絕大多數公司差很少,首先是數據採集,咱們有不少爬蟲,能夠直接在公網爬取全網數據,爬取到全網的體育數據後,咱們對數據進行分析,而後就是數據處理和建模。早期咱們經過大數據分析技術把這些數據跑出來,進行建模,進行結果預測。如今咱們開始進行一些更深刻地研究,像機器學習、深度學習,還有神經網絡等相關算法都已經引進並運用。但願經過這些人工智能算法更智能、更科學地預測一場比賽,或者對體育進行服務。網絡

img

正是基於核心技術,智慧摩羯佈局了三條產品線:架構

一是體育比賽預測,就是剛跟你們分享的,經過去全網扒數據,運用人工智能算法分析進而預測體育比賽結果。負載均衡

二是體育運動指導,經過收集全部運動員及體育愛好者的運動數據,對其進行專業地指導。框架

三是電競遊戲支持,咱們發現電競其實也能夠進行各類各樣的數據收集、分析和預測,智慧摩羯能夠爲電子競技類遊戲提供專業的數據支持,讓遊戲更加專業、真實和有趣。運維

技術架構機器學習

第一部分是技術的演化過程,主要講種子期和成長期。

img

早期是把代碼放在 GitHub 上,爲了把業務拆得足夠細,因此建立了不少代碼庫,但智慧摩羯當時只有一兩個後臺工程師,很快就拆出超過 10 個庫。這樣維護起來成本過高,代碼重複,且沒有精力合到公共的代碼庫裏,咱們發現這條路走不通。

img

這就是智慧摩羯早期的架構,特色是代碼庫特別多,咱們有前端負載均衡,有 API 服務,有消息隊列服務,定時任務服務,這時候 Redis 是單節點的,MySQL 也是單節點的,是很簡單的架構。實際上代碼庫多對咱們來說是比較重的事情,而後咱們就把多個代碼庫合成一個,解決公共庫的問題,代碼的冗餘度下降了。雖然單個數據庫根據業務劃分多個 schema,可是仍是在一個數據庫裏面,而後單個 Redis 節點,存放全部的緩存數據,這樣也能夠下降成本。

img

問題就是單體工程愈來愈龐大,一年咱們就作了幾十萬行代碼的量級,仍是一個工程代碼庫。還有一個特色就是文檔少,重複代碼多。因爲開發人員增長了,從兩三我的變成了十幾我的,致使重複代碼愈來愈多,由於不是每一個人都對代碼理解,文檔少,必然就會理解少,重複的代碼多。數據庫沒法根據業務分攤壓力,單失效節點多,事故也頻繁出現。

img

這是智慧摩羯這時簡單的架構圖,GitHub 是單一的節點庫,增長了不少運維腳本,當時 VM 在 QingCloud 上就有幾十臺。

微服務解決方案

img

沒有問題就沒有動力去改變這個事情,因此咱們先來看下有哪些問題。

第一個特色是單個節點的數據庫承受全部的應用層壓力,沒有進行拆分。這時候數據庫實際上是最大的瓶頸,一旦它發生阻塞,整個服務就癱瘓了。由於全部的鏈接一直在那兒阻塞,沒辦法接新的鏈接,整個服務就是徹底阻塞的狀態。

第二個特色,單個 Redis 承受全部的緩存的數據,服務癱瘓,恢復時間慢。單體工程代碼量很是龐大,新人頭疼,無從下手。開發人員變多,出現的事故機率增大,系統升級的風險變高。

代碼的衝突也頻繁發生,這時因爲每一個人不太瞭解,合併的時候頻繁出現代碼被覆蓋的狀況,咱們的開發分支跟線上穩定分支總會出現各類各樣的問題,升級的風險很是高。應用層都部署在 VM 上,上百節點的 VM 沒有分開,這是咱們的問題。

img

針對以上問題,兩個核心的解決方案:第一個是隔離,第二個是解耦。一部分是靜態的部分,就是代碼的部分。而後動態的部分就是運維,若是不談運維、不談代碼就有點空。首先是隔離,工程代碼要隔離,而後代碼跟代碼之間不要互相干擾。第二個是運維事故要隔離。而後是解耦,代碼要解耦,系統升級要解耦。

img

一個目標就是要放權,我對微服務的理解就是產生不少的子服務之後,首先你的代碼庫拆掉,以前代碼庫的管理權限是給到整個研發部,不少事情須要統一的受權。可是代碼庫拆掉後你就能夠把權力下放到各個業務小組,由他們來決定代碼的合併和代碼的系統升級,這樣的話就等於把這個權力下發下去了。整個微服務實施的步驟是數據庫的 schema 拆分,接口流量拆分,微服務的註冊發現,管理服務的生命週期。

img

首先是代碼庫,咱們先把 GitHub 的代碼庫由一個工程 fork 出來不少子工程,其實都是同樣的,由於短期內若是想以最快的速度把工程拆掉,這是最簡單的辦法。

img

這是第一點,而後把一些公共的合起來,剩下的所有拆掉。拆掉的過程當中確定會有一些跟這個業務不相關的代碼,可是至少保證了每個工程能夠獨立的進行分支合併。

img

第二點是咱們的數據庫進行了比較大的改動,原來多是單個數據庫,就只有多 schema 的架構,如今咱們把原來的數據庫拆成八個,這些都是作事務的數據庫,而後用 MariaDB,由於 MariaDB 支持多元複製,把這些子數據庫,這些不一樣的 schema 合到一個數據庫裏面,這樣能夠把數據庫分開。

另外就是分表的問題,咱們經過阿里開源的 Otter 來解決,其實是假裝成了一個 MySQL 的 Slave,不停地從 Master 裏面同步數據。而後能夠創建多張表跟一張表的映射關係,創建完畢之後把多張表合成一張,這樣咱們有分有合,用戶查的是分表數據,可是咱們後臺統計的是合表數據,合表數據能夠提供給管理後臺的人員用,給作運營、作分析的人用,這樣也能把數據庫壓力分散掉,線上就是線上,咱們本身後臺的分析就是後臺的分析,把 OLTP 和 OLAP 分離。

img

咱們規範了合併流程,原來只有兩個分支,一個是 Master 分支,一個是 Develop 分支。相信你們比較瞭解,Develop 分支就是開發分支,主要開發新的 features,好比說咱們要開發新版本,全部的 features 開發完畢之後,就會進入集成測試的分支。可是開發人員在測試階段還能夠改代碼,這個事情若是沒有規範好,會致使測試人員作不少無用功。最後咱們以爲須要給測試人員足夠的權限,他們來管理一個單獨的分支。

這樣的話全部的開發人員往這個分支合併代碼的時候必須通過測試人員的贊成,測試再去測這個獨立分支的時候,若是測完沒有問題,再往 Master 合併,能保證測的代碼就是要升級的代碼。同時爲了保證流程,若是線上發現了一個 bug,應該以 M 打頭,經過它 fork 出來一個子分支,而後往三個分支同時進行合併,依次合併。這個代碼的分支合併的規範流程,其實對咱們來說仍是很重要的。這裏面解決了不少開發人員不規範,亂提交代碼的問題。這個頗有用,能保證代碼的質量。

接着咱們對線上全部的服務進行拆分,拆分以前咱們就是一個單體服務,很麻煩。如圖:

img

最前面是負載均衡器,這個就不用說了,用的是青雲的負載均衡器。在負載均衡器後面,咱們本身加了一層是 API gateway,咱們把接口、定時任務、消息隊列等這些模塊按照功能爲單位,依次進行劃分,劃分紅幾百個服務。

這幾百個服務不必每一個服務一臺機器。對哪些服務須要訪問哪些資源鏈接進行整理歸類,好比有的是訪問用戶的數據庫,有的是訪問訂單數據庫,可是他們訪問的時候也會分讀寫,究竟是讀數據仍是寫數據。

而後咱們再把全部的這些幾百個服務、接口,每個都仔細過了一遍,而後把哪一個該走讀,哪一個該走寫,所有歸好類,把全部的配置配好,而後由 API gateway 轉到不一樣的機型,可能配的是讀庫或者寫庫,把線上的幾百個接口拆成幾百個服務,每個服務能作到對其餘的服務最小力度地干擾。

原來數據庫阻塞了,而後應用層組塞,整個用戶就阻塞了。如今變成了咱們能夠逐步降級服務,給用戶提供更穩定可靠的服務,不至於出問題。

img

這是咱們用青雲的 AppCenter 2.0 作的這個事情。在去年青雲的 AppCenter 2.0 發佈會上,我以爲可以幫助智慧摩羯實現業務。

我對它的理解就是,它在定義角色,定義生命週期。裏面包含了存儲的角色,計算的角色,包含 RDB、包含 Redis、包含 Zookeeper,能夠包含不少的角色。而後這一個角色能夠定義不少參數,由於這些參數就是配置參數,原來的配置參數可能不統一,好比說 Redis有 Redis 的配置參數、Zookeeper 有 Zookeeper 的配置參數。

總體的把全部的配置參數都抽象出來,而後生命週期裏好比說服務的建立、服務的銷燬、服務的啓動、服務的關閉、服務的 Scale In&Scale Out,還有監控,健康檢查,每個過程定義好之後,這些過程都可以觸發咱們提早定義好的腳本,這個腳本可以在生命週期裏作它該作的工做。

而後咱們把咱們的服務註冊在青雲的 AppCenter 2.0 裏面,當服務啓動之後咱們的服務之間怎麼訪問呢,這是依賴於咱們用的 consul 的框架,每個節點啓動之後會有一個 consul 的 Agent,Agent 用來獲取其它服務的地址,完成微服務之間的訪問。

同時服務的註冊和發現,還有健康檢查,也依賴於 consul 的 sever,例如,我要註冊一個服務,個人 IP 是什麼,個人信息是什麼,放到哪裏,其餘的服務就能同步下來,而且找到這個服務。

img

下一步,原來傳統的部署是程序對接資源,資源是指的是什麼?好比說 VM,計算資源、存儲資源都算資源,我理解的是,物理設備這些東西都叫資源。

而後程序直接對接資源,這會致使咱們有不少的配置文件,因爲存在不一樣的環境,可能不一樣的環境只是配置文件不一樣,那麼這個配置文件不一樣就致使了多一個環境就多一套配置文件,因此須要對配置文件進行管理,配置文件發生變化之後須要對相應的服務進行更新和同步。好比說常常出現配置文件和實際部署的服務發生不一致,若是是不一致的話就會出問題。

而如今還有一個特色,當你管理幾百個節點的時候會很痛苦,它們究竟是屬於哪個服務的,你不清楚,由於對你而言它就是一大堆幾百個節點的資源,都在青雲的管理後臺裏,只能經過標籤分類。但這並不許確,若是有人粗心把標籤打錯了,你就會誤判,並且可能只有運維人員最瞭解,其餘人都不懂。

中間通過 AppCenter 2.0 之後,咱們作的微服務,至關於隔一層,程序直接不去對接資源,而是對接 AppCenter 2.0 裏面的一個微服務。

這個微服務裏面定義了須要的參數,這些參數不是配置文件,而是在服務啓動的時候纔會真正有這麼一個東西,這是在微服務啓動的時候,好比說我須要一個 MySQL,它是哪個 IP 地址,主從是什麼樣的結構,我須要一個集羣,它是什麼樣的配置參數,你在建立的時候再填寫,這樣的話由 AppCenter 2.0 去建立資源、建立服務,把這些資源提起來,而且管理服務的生命週期。

經過這些咱們把幾百個節點,徹底按照以服務爲角度進行歸攏和聚類,方便咱們的管理。

img

接下來談談還有哪些工做咱們沒有作,其實咱們剛纔說的這些工做都是比較初級的,是能幫助咱們的最快的手段。開發人員沒有投入太多的代碼的改動,咱們就把整個服務拆掉,拆成十幾個微服務。我認爲智慧摩羯接下來要作的事情,或者說智慧摩羯尚未完成的工做。

第一個就是認證受權,智慧摩羯的微服務之間如今雖說是內部系統,可是互相之間也應該有一個受權操做,如今是由於公司的業務沒有到必定的程度,到必定的程度的話是否容許互相認證訪問是應該有受權的。

還有性能監控,拆掉以後每個服務的性能,延遲尚未加監控。再就是流量控制,假如說某一個服務知道它大概能承受多少許級的壓力,若是這個壓力過線,咱們就能自動進行熔斷,而這個尚未作。

總結和反思

img

經過以上這些操做,咱們消滅了單失效節點。MySQL 的每個服務都有主從,能夠把壓力分擔。應用層都解決了。解耦單體工程,每一個微服務的代碼庫由每一個小組進行維護,原來每一次升級都是一次大動做,全部的研發工程師都比較緊張,須要一塊兒溝通交流,而後盯着升級,擔憂其是否會出現問題。

如今經過這種方式避免了各個模塊之間的代碼干擾,解決了以前有可能你改了這個代碼卻引發了另一個你根本不知道的地方出現問題。各個代碼庫的合併受權下發給相關的組長,這樣就解決了放權的問題,咱們能夠把研發部拆成不少的小組,他們能夠獨立進行本身的工做,再也不受整個研發部統一的受權。

規範了代碼的合併流程,這實際上解決了開發階段的代碼污染問題,包括開發階段的代碼污染、測試階段的代碼污染、以及線上的代碼污染。

對上百個資源節點以微服務爲單位進行分組管理,減小了各個模塊之間的運維干擾,運維也能夠以微服務爲單位進行拆分放權,包括進行升級。

部署就能夠以接口爲單位,用接口隨意切流量,雖然作不到智能的流量控制,可是若是線上某一個接口形成特別大的壓力,可讓接口先返回一些友好的報送信息,從而解決線上某一個接口壓力過大的問題。

img

第一,系統在不斷地進步,每個公司的系統都有不一樣的階段,要針對現階段找到最佳的解決方案。

第二,全部的道理你們都懂,每一個人心中也都有解決方案,當你遇到問題的時候確定有本身的想法,可是最核心的、最重要的事情就是幹!

相關文章
相關標籤/搜索