今天很榮幸給大家介紹 58 速運(yùn)從艱苦創(chuàng)業(yè)到成為同城貨運(yùn)行業(yè)領(lǐng)頭人的整個系統(tǒng)演進(jìn)過程,。 簡單來說我們的業(yè)務(wù)是做同城貨運(yùn),比如您去買一個大型家具,,自己的家用車肯定是裝不下的,,這時你可能需要找路邊的小型面包車或者金杯車來幫你搬運(yùn)。 一般來講,,很容易遇到黑車,,而且價格不標(biāo)準(zhǔn),我們做的這個行業(yè)就是將這種傳統(tǒng)的黑車行業(yè)進(jìn)行線上化,,在產(chǎn)品形態(tài)上可理解為滴滴打車的出租車版,。 本次分享內(nèi)容主要分為4個部分:
創(chuàng)業(yè)之初:快速迭代試錯 58 速運(yùn)在 2014 年是作為 58 集團(tuán)下 20 多個孵化業(yè)務(wù)中的其中一個,,那個時期基本上是平均三個星期一個業(yè)務(wù)孵化上線,當(dāng)時有 20 多個業(yè)務(wù)孵化同時進(jìn)行,。這個時間我們不斷的試錯,,不斷去尋找 58 同城新的增長點(diǎn)。 從上圖中,,大家可以看到,,我們所有的服務(wù)都是基于一個數(shù)據(jù)庫來運(yùn)行的,這個系統(tǒng)之間只需要通過一些簡單的 tag 標(biāo)記就可以區(qū)分開業(yè)務(wù),,系統(tǒng)迭代非??臁?/span> 對于新孵化的業(yè)務(wù),,我們增加了一些簡單的業(yè)務(wù)邏輯就能實(shí)現(xiàn)這個產(chǎn)品的快速上線,,我們在兩周內(nèi)實(shí)現(xiàn)了速運(yùn)用戶、商家的 APP 以及后端的產(chǎn)品上線,。 派單-石器時代 這時的系統(tǒng)架構(gòu)是非常簡單的,,我們稱之為“石器時代”,當(dāng)時所有的訂單調(diào)度的邏輯放在一個 Jar 包,,然后通過 MQTT 服務(wù)將訂單推送到司機(jī)的 APP 上,。 當(dāng)時的訂單調(diào)度(也是我們最初級的訂單調(diào)度方案)是一個訂單搜索附近的司機(jī),然后由近到遠(yuǎn)的距離將訂單推送出去,,司機(jī)搶單后即中單,。因?yàn)樵趧?chuàng)業(yè)階段,我們需要吸引客戶,、司機(jī),,對于每單都會有補(bǔ)貼。 這個階段面臨的痛點(diǎn)如下:
針對以上痛點(diǎn),,我們做了第一次的技術(shù)引進(jìn)——遷庫,、集群拆分。 第一次技術(shù)演進(jìn):遷庫,、集群解耦 為什么要遷庫,?誰痛誰知道!不想受到其他業(yè)務(wù)小伙伴的影響,,就要做到解耦,。 一個最簡單的方案就是停服,,把所有的服務(wù)停掉,然后把數(shù)據(jù)庫抽離出來,,相對來講這是成本最簡單的,。 但是停服會產(chǎn)生的影響:
我們采用的方案:將訂單表單獨(dú)地拆離出來,,放在單獨(dú)的數(shù)據(jù)庫里,,兩個數(shù)據(jù)庫之間使用雙向同步。 雙向同步需要解決的問題:
經(jīng)過多次的遷移,,將原有的數(shù)據(jù)庫按照業(yè)務(wù)劃分成了訂單庫、結(jié)算庫,、配置庫和軌跡庫等,,每個數(shù)據(jù)庫會根據(jù)業(yè)務(wù)量容量的大小來配置數(shù)據(jù)庫物理機(jī)的內(nèi)核、內(nèi)存,,減少成本,。 高速發(fā)展:穩(wěn)定、高效 2015 年我們進(jìn)入了高速發(fā)展的階段,,市場上出現(xiàn)了藍(lán)犀牛,、1 號貨的、云鳥的等多個強(qiáng)勁的競爭對手,。各方都是爭分奪秒,,一個系統(tǒng)、功能,,我需要抓緊把它給迭代上來,,誰也不能比誰落后。 這個階段我們存在的問題:
這時我們進(jìn)行了第二次技術(shù)演進(jìn),,我們稱之為“進(jìn)行了奔跑中的火車換輪子”,,我們進(jìn)行了服務(wù)化解耦;緩存,、分庫分表,,提升系統(tǒng)性能;接入大數(shù)據(jù)平臺,,進(jìn)行復(fù)雜需求的分析,。 第二次技術(shù)演進(jìn):奔跑中的火車換輪子 派單-鐵器時代 我們將所有的系統(tǒng)都按服務(wù)模塊進(jìn)行了拆分,比如說結(jié)算,、充值,、推送、司機(jī)任務(wù)等,,現(xiàn)在大概已有 20+ 個服務(wù),,每個服務(wù)都有獨(dú)立的數(shù)據(jù)庫,,有獨(dú)立的負(fù)責(zé)人。 這樣就可以做到我自己的代碼我自己來寫,,別人都不允許去插手,。 此外我們進(jìn)行了推送的多通道化,從上圖可以看到,,我們針對每個司機(jī)選取了兩種推送通道,,同時我們也建議大家在做推送消息時采取這種方案。 拿小米的手機(jī)來說,,“小米”推送通道的到達(dá)率是最高的,,但小米的通道在華為的手機(jī)上,到達(dá)率不如“個推”的推送到達(dá)率高,。 我們就會根據(jù)司機(jī)的機(jī)型來選取一個到達(dá)率最高的三方通道,。同時在設(shè)計上不能有單點(diǎn),假如說小米的通道出現(xiàn)了問題,,那我們的服務(wù)就不可用了,司機(jī)接收不到訂單,,用戶的需求就沒法得到滿足,。 所以我們還有一個自研渠道 TCP 通道,這個 TCP 通道除了和我們?nèi)酵ǖ雷鲆粋€雙通道?;钔猓€可以做一些數(shù)據(jù)的上傳,。 這時的訂單調(diào)度,被稱為探索階段,,初期的距離推送效果有限,,誰搶到誰就中單,司機(jī)的服務(wù)質(zhì)量我們沒有辦法去評判,,補(bǔ)貼也是大眾化的。 所以我們自己研究了一個按象限推送的方法:
分庫分表 前面提到數(shù)據(jù)庫性能已經(jīng)成為瓶頸了,,所以這里以一個用戶服務(wù)給大家講一下我們的分庫分表是怎么做的:
在這里水平拆分要重點(diǎn)提一下,,就是如果資源允許,,水平拆分還是建議分庫,。 數(shù)據(jù)庫的性能瓶頸也是會受到硬件設(shè)備和網(wǎng)絡(luò) IO 的影響,如果訪問量持續(xù)增加,,數(shù)據(jù)庫還是會成為瓶頸,。 我們的水平拆分有兩種方法:
拆分后的問題:
問題分析,,“任何脫離業(yè)務(wù)架構(gòu)的設(shè)計都在耍流氓”:
前端解決方案:
運(yùn)營側(cè)需求解決方案:
到了 2016 年,,競爭對手基本上已經(jīng)被消滅了,,58 速運(yùn)已經(jīng)成為行業(yè)的領(lǐng)頭者了,如何使用更少的補(bǔ)貼獲取最大化的收益,? 我們有如下幾點(diǎn)反思:
第三次技術(shù)演進(jìn):戰(zhàn)斧項(xiàng)目 我們進(jìn)行了第三次的技術(shù)引進(jìn),,我們稱之為戰(zhàn)斧項(xiàng)目,項(xiàng)目的定義:精準(zhǔn),、高效,。 我們做了以下優(yōu)化:
智能時代:效率、精準(zhǔn) 智能模型訓(xùn)練 上圖為智能模型訓(xùn)練圖,,首先我們會將訂單信息,、用戶信息、司機(jī)信息,、客司關(guān)系信息,、訂單總體推送,、司機(jī)接單等場景信息統(tǒng)一上傳到大數(shù)據(jù)平臺。 通過這種歸一化&分桶,、XGBoost,、特征組合、獨(dú)熱編碼等將這些數(shù)據(jù)分析為特征數(shù)據(jù),。 針對分析出來的特征數(shù)據(jù),,我們需要對它進(jìn)行訓(xùn)練,如:訂單價格,、訂單距離等特征在整個訂單派單中起到的權(quán)重,。 因?yàn)樘卣骱芏啵嬎愠鰜淼臋?quán)重可能并不是一個完美的解,,只能說是近優(yōu),、最優(yōu)的一個解法,通過不斷地迭代優(yōu)化,,最終訓(xùn)練出來最終的模型,。 訂單-模型運(yùn)用 訂單模型的運(yùn)用:
派單-智能時代 上圖是智能派單時代的系統(tǒng)架構(gòu)圖。用戶在下完單以后,,訂單會進(jìn)入到我們整體的策略系統(tǒng),,它包含推送系統(tǒng)、補(bǔ)貼系統(tǒng),、價格系統(tǒng),、任務(wù)系統(tǒng)等。 然后通過特征匹配系統(tǒng),,計算出一個最優(yōu)的訂單調(diào)度解,,將這個訂單推送到司機(jī)的單隊(duì)列引擎和訂單的排序策略引擎,最終通過我們的推送服務(wù)將訂單推送給司機(jī),。 策略分流+監(jiān)測 智能系統(tǒng)需要有不同的算法在線上實(shí)驗(yàn),,當(dāng)我們一些新算法研發(fā)完成以后,肯定不能用 100% 的流量在線上進(jìn)行驗(yàn)證算法的可行性,,如果有問題,,會對線上業(yè)務(wù)產(chǎn)生影響。 我們一般取 5% 或 10% 的流量在線上驗(yàn)證,,根據(jù)用戶手機(jī)號,、設(shè)備碼、用戶屬性等,,以及取模,、集合等方式。對線上算法驗(yàn)證時,,如何實(shí)時的監(jiān)測算法的效果,,避免錯誤算法對線上業(yè)務(wù)造成的影響? 如上圖所示,,用戶在 APP 中的每個步驟,、運(yùn)用了哪個算法,我們都會將用戶的 ID,、采用的算法 ID 通過日志上報到統(tǒng)計平臺,。業(yè)務(wù)監(jiān)控平臺會實(shí)時進(jìn)行監(jiān)控,對于出現(xiàn)異常的算法就自動關(guān)閉分流,。 特征計算 特征數(shù)據(jù)中有 40 多萬個特征,,每個訂單需要推送給很多個司機(jī),,需要進(jìn)行上萬次的運(yùn)算,需要在幾十毫秒內(nèi)給出計算結(jié)果,,如何保證計算的高性能呢,? 我們采用的是這種階段性事件驅(qū)動的計算方式來最大化提高并行計算的能力。 如圖所示,,這是我們的計算鏈,,里面包含多個 Stage,包含準(zhǔn)備階段,、轉(zhuǎn)化階段,、取數(shù)階段和計算階段。 每一個階段都有自己獨(dú)立的線程池,,根據(jù)每個階段的特征設(shè)置核心線程數(shù),,同時整個計算鏈做到了可插拔的形式,方便業(yè)務(wù)調(diào)整,。 利器-監(jiān)控平臺 監(jiān)控可以說是整個架構(gòu)演進(jìn)過程中非常重要的部分:
立體化監(jiān)控 目前已經(jīng)做到的監(jiān)控包含:關(guān)鍵字,、接口、流量,、端口,,JVM、CPU,、線程,、緩存、DB 所有的監(jiān)控等等,,同時還有服務(wù)治理,,當(dāng)服務(wù)節(jié)點(diǎn)發(fā)生異常,實(shí)時切換,。 業(yè)務(wù)化的指標(biāo)監(jiān)控,,渠道轉(zhuǎn)化率、渠道取消率,、渠道推送數(shù)量,、異常訂單數(shù)量等等,如果出現(xiàn)異常,第一時間預(yù)警,。 調(diào)用跟蹤系統(tǒng) 很多互聯(lián)網(wǎng)公司都已經(jīng)在使用調(diào)用跟蹤系統(tǒng),,目的是需要看到 APP 發(fā)起的每個請求在整個 Service 后端走過的所有過程,效果如下圖所示,,可以監(jiān)控到每一步所調(diào)用的服務(wù)和耗時,。 總結(jié) 最后給大家總結(jié)了 5 點(diǎn)經(jīng)驗(yàn):
作者:胡顯波 |
|