內容來源:2017年6月24日,噹噹架構部總監在「雙態運維·烏鎮峯會-數人云專題研討會」進行《噹噹彈性化中間件及雲化之路》演講分享。本文轉自數人云公衆號(dmesos)。
6月24日,雙態運維·烏鎮峯會-數人云專題研討會上,張亮老師從業務、中間件、雲化的方向出發,分享了當當網實踐落地容器的經驗。小編掐指一算,稀缺好文,宜收藏和分享!前端
今天主分享的內容分爲三部分——算法
第一部分:噹噹業務體系簡介。受限於時間,只作簡單概述。數據庫
第二部分:介紹噹噹的彈性化中間件。現階段,無狀態容器已趨於成熟,須要進一步開發和優化的是運行在容器裏面的部分,即中間件。編程
第三部分:噹噹的雲化之路。後端
嘉賓演講視頻地址:t.cn/R96OZby緩存
首先,介紹下噹噹的業務特徵,這也是互聯網行業的共有特徵:安全
海量用戶 噹噹面向的是徹底開放的、整個互聯網的億級用戶量。服務器
品類繁多 噹噹是賣書起家的,書的品類是不少的。除了書,噹噹還有百貨、服裝等。與垂直電商不一樣,水平電商因爲品類繁多,所以數據架構也會有很大區別。架構
7*24 互聯網公司基本都是如此要求,儘可能縮短宕機時間。併發
流量突增 如「雙11」或「書香節」,其流量是平時的幾倍到幾十倍不等。
業務複雜 下圖是業務框架圖,分爲三部分,中間部分是噹噹主業務流程,從用戶查看選擇商品的賣場模塊,到購物車、結算的交易模塊,最後發至訂單工做流系統;而後經過倉儲系統生產訂單,並交由物流系統配送貨品。上面部分是用戶相關的系統,如搜索、推薦、促銷、會員等。下面部分是爲噹噹運營人員與合做夥伴提供的系統,如商品、價格、庫存等。
這僅是縮略版的系統架構圖,噹噹實際系統要複雜的多、用到的語言也各異,大部分如:前端PHP、後端Java、搜索系統用C++,推薦系統用Go和Python。所以它是一個由異構語言組成的複雜系統集合。
互聯網核心問題和企業級開發不同的地方在於規模。互聯網公司的規模由如下幾點組成的——
海量數據:包括但不限於用戶數據、商品數據、交易數據、訂單數據、用戶行爲數據等。因爲數據量巨大,所以不能僅使用單一的數據存儲結構,也不能以單數據節點的方式存儲全部數據。
響應遲緩:大量的用戶訪問,使得系統承載了更多流量,處理過多的請求會致使系統響應變的遲緩。
系統繁多:經過上一張圖能夠得知,系統是由很是多的子系統組成的,每一個子系統各司其職。合理的系統拆分能夠靈活的分離冷熱數據、擴容重點系統等。
開發困難:各個系統都是由異構語言的不一樣技術棧構成,開發成本較高。
穩定性差:因爲系統間交互增多,系統之間會造成一個複雜的交互網。任一系統出現問題,均可能致使部分不可用,進而增長總體不可控的風險。系統拆分的越多,出問題的可能性就越大,系統穩定性就會越差。
伸縮性差:電商公司不可能常備「雙11」的機器體量。所以遇到大促等須要承載突發流量的場景,系統須要能夠彈性伸縮。在流量增長的時候擴張容量,用於承接更多的購買需求;在流量降低的時候收縮容量,節省成本。
解決方案是中間件+雲平臺。
中間件解決的主要問題是服務化、彈性化和異步化。
服務化:衆多系統間應該提供一致的交互和治理方式。
彈性化:讓系統具有根據實際須要靈活的擴縮容的能力。
異步化:將同步調用鏈梳理爲同步落盤 + 異步處理的方式以提高吞吐量。
雲平臺解決的主要問題是部署自動化和監控一體化。
中間件缺少對運行環境搭建,App部署分發等能力,也難以提供統一的監控一體化系統,所以雲平臺在這方面是對中間件的有益補充。
這裏介紹最主要的三個中間件:服務中間件、做業中間件和數據中間件。中間件遠遠不止這三種,限於時間,沒法涵蓋所有的中間件:如消息中間件、緩存中間件、NoSQL以及離線大數據等因時間關係不在分享範圍以內。
服務中間件有不少優秀的開源產品,從早期的Finagle, Dubbo,到近期出現的Motan,Spring Cloud都是個中翹楚。服務中間件的核心功能主要包括:
遠程調用:分爲長鏈接調用和短鏈接調用兩種方式。長連接採用Socket + 二進制序列化的方式居多,短鏈接以HTTP RESTFul + JSON的方式爲主。不管採用何種調用方式,都應在服務中間件中封裝爲統一接口。
服務發現:自動感知上線和下線的應用,並分配和截斷相應的請求。標準實現方案是經過一個註冊中心管理和協調分佈式應用,常見的註冊中心有Zookeeper,etcd和Eureka。
負載均衡:合理的將流量分配給權重不盡相同的分佈式節點。
服務治理:包括服務調動鏈梳理、服務降級、服務版本控制等功能。
限流:將過載的流量擋在後端系統以外,讓部分不過載的請求能夠繼續提供服務。保證系統不會由於突增的流量而被徹底沖垮,而是任何狀況下都能提供對核心用戶的平穩服務能力。
監控報警:提供將內部指標經過API對接到外部系統的能力,內部指標通常有SLA、服務狀態、節點承載量等。
上圖是噹噹採用的服務框架——DubboX。
該項目Fork了阿里開源的Dubbo,並內置了Web服務器且增長REST協議,用於支持異構語言間的調用。每一個基於DubboX的應用都可經過內置的Web服務器提供服務,每一個Web服務器經過Nginx實現負載均衡。而且在Nginx經過OpenResty實現了基於漏桶和令牌桶兩種算法的限流插件。請求調用信息經過Agent的本地彙總以後,按期發送至一個Kafka的消息隊列,並經過Storm的二次彙總計算出SLA,存儲至數據庫中。最終由監控系統按期抓取報警數據。
使用DubboX部署的程序,在邏輯上分爲兩部分。上面部分是服務的提供者;下面部分是服務的消費者。服務消費者在REST協議的場景,是直接經過Nginx代理訪問服務提供者的。若是採用Java同構應用,可使用Dubbo原生的長連接+Dubbo協議,並經過註冊中心服務發現,以及客戶端負載均衡。
下圖是噹噹的SLA監控系統以及限流系統的Dashboard。
噹噹系統中不少業務是由做業實現的,如拉單做業、價格同步做業等。由於公司系統較多,很難經過惟一的方案實現,所以也有部分系統經過消息中間件完成。做業中間件的核心功能主要包括:
定時調度:根據cron表達式的時間調度應用。
任務分片:將一個大任務拆分紅爲多個任務片斷,分佈運行。此功能後文會重點介紹。
彈性擴容:與任務分片息息相關,一併在後文中介紹。
做業治理:管控做業生命週期,如:執行、禁用、啓用以及更復雜的行爲,如:失效轉移、錯過任務重觸發等。
監控報警:提供將做業運行狀態、歷史統計和查詢對接至外部系統的能力。
噹噹採用的做業中間件是自研的Elastic-Job,它能夠將一個完整的做業拆分爲多個相互獨立的任務。一個完整的做業運行時間可能較長,但很難經過增長機器實例提高運行效率。經過Elastic-Job將做業拆分爲多個任務,能夠並行的在分佈式的環境中運行,提高其處理速度。用戶能夠實現本身的分片策略,將任務分配至合適的節點運行。
經過上圖舉例,做業分爲4片,由兩臺服務器執行,每臺執行兩片。當增長一臺服務器時,以下圖所示,分片項被稀釋爲服務器1和3各執行一片,服務器2執行兩片,那麼服務器1和3因爲執行的分片項減小,從而提高性能。
而一旦有服務器宕機,以下圖所示,僅剩餘一臺服務器能夠提供服務,那麼全部的分片都將指向該服務器。集羣的總體處理能力會降低,但做業的完整性不會受到影響,從而提供高可用的能力。
所以,隨着運行實例的增長和減小,Elastic-Job能夠動態的調整分片來提高性能和保證可用性。
這是Elastic-Job的部署架構圖。
接下來介紹的是數據庫中間件。關係型數據庫在大數據量的狀況下,單庫單表難以支撐。解決方案是將單一的數據庫拆分爲分佈式數據庫,而讓開發和運維人員像訪問一個數據庫同樣訪問分佈式數據庫,屏蔽其複雜度,是數據庫中間件的基本功能。數據庫中間件的核心功能主要包括:
分庫分表:經過打散數據的方式有效的減小每一個表的數據量,減小索引的深度以提高查詢性能。而且拆分數據庫來有效的疏導請求流量。
讀寫分離:進一步提高數據庫的性能能夠採用讀寫分離。讀庫僅負責響應查詢,寫庫相應更新,經過異步數據同步的方式保持讀寫庫的數據一致性。這種方式能夠有效的減低行鎖,進一步提高效率。
內聯事務:數據庫一旦打散,就必須使用分佈式事務而致使性能急劇降低。所以如何合理的分庫分表,儘可能將操做保證落在同一個庫,而使用內聯事務,是更好的選擇。
柔性事務:在內聯事務不適用的跨庫場景,犧牲強一致性來換取性能的提高,而後採用異步補償的機制來達到最終一致性,是柔性事務的核心理念。
SQL審覈:先期過濾出不符合OLTP的非法SQL。如:DELETE語句沒有WHERE等。
噹噹採用自研的Sharding-JDBC做爲數據庫中間層。它直接修改JDBC協議,所以能夠兼容各類數據庫以及ORM框架,應用工程師幾乎沒有學習成本,和使用原生JDBC沒有區別。應用工程師僅須要配置分片規則,用於告訴Sharding-JDBC哪個分片鍵的數據應該路由至哪一個庫的哪一個表,便可。
Sharding-JDBC的內部結構包括:JDBC規範重寫、SQL解析、 SQL改寫、SQL路由、SQL執行以及結果集歸併。
上面兩個圖是Sharding-JDBC的性能測試報告,在單庫時,因爲SQL解析帶來的損耗,Sharding-JDBC比原生JDBC慢了0.02%。而將數據拆分至雙庫,Sharding-JDBC比原生JDBC的性能提高了94%,所以,拆分的數據庫實例越多,其對性能的提高也越顯著。
Sharding-JDBC定位是面向在線業務的框架。所以OLTP涉及到的SQL基本都兼容。
分佈式的事務處理方案有三種:XA,弱XA和柔性事務。
XA即分佈式事務,他對業務代碼徹底沒有侵入性,並且也能夠保證分佈式場景下事務的強一致性,但其性能低下,在互聯網的場景下很是不適用。
弱XA是分庫分表數據庫的中間層所提出來的概念,簡單說就是單片事務。它僅能控制單節點事務的一致性,對於分佈式的事務徹底沒有控制能力。他不會對性能帶來任何影響,但沒有一致性的能力,在分佈式的場景下極易形成數據不一致。
柔性事務是對弱XA的補充。它使用異步補償的方式,將短時間內不一致的數據修復,達到最終一致性。它用犧牲強一致性的方式提高了性能,所以內聯事務 + 柔性事務成爲了最受青睞的互聯網事務處理方案。
柔性事務有兩種比較成熟實現方案,最大努力送達型和TCC(Try Confirm Cancel)。
最大努力送達型能夠保證事務最終成功,業務入侵較小,僅須要業務方實現冪等性便可。它要求事務最終必定會成功,沒法回滾,所以會反覆嘗試,直至最終成功。
TCC相似原生事務,事務能夠提交,也能夠回滾。但事務的提交和回滾操做均須要業務工程師去實現,所以對業務入侵極大,TCC一樣須要業務代碼實現冪等性。
上圖是最大努力送達型的流程圖。它在SQL執行前記錄事務日誌,在SQL執行成功後清理相應事務日誌。一旦SQL執行失敗,事務管理器就會經過同步和異步執行的方式從日誌庫中獲取當前的SQL反覆嘗試,直至到達最大重試次數爲止。超過最大重試次數的數據須要人工介入處理。
首先,應用運行時環境是經過容器來實現的,不一樣編程語言編寫的應用須要不一樣的運行時環境,將環境、應用及相關依賴一塊兒打包發佈是容器的主要做用,在噹噹採用的容器解決方案是Docker。另外,容器還能夠用於隔離運行環境,讓運行在同一宿主機的不一樣鏡像能夠安全和獨立的使用既有資源。
其次,僅經過容器沒法作到應用治理。中間件是應用彈性化的關鍵,它分別針對服務、做業以及數據庫訪問進行有效的加強。服務和做業中間件是兩種大相徑庭的應用類型,而數據中間件則是它們的有力支撐。無狀態的服務更易彈性擴展;而有狀態的做業則經過分片項隔離與數據的依賴;數據庫中間件則用於簡化分佈式數據庫的訪問以及事務處理。
最後,一個可快速運行且高度彈性化方案的最後一塊拼圖,便是須要一個平臺去合理分配資源以及自動分發應用。目前比較流行的是Kubernetes和Mesos兩種方案。在使用的複雜度上Kubernetes要更加簡潔和一站式,但Mesos所採用兩級調度概念,經過其Framework定製化很是簡單,所以噹噹選擇Mesos做爲資源調度系統。
分佈式調度系統當前有三種架構:單體式,兩階段以及狀態共享。
單體式調度較爲簡單,調度邏輯能夠在沒有任何併發的狀況下使用所有資源。但因爲互聯網業務需求多、變化快,所以這種架構雖然性能高,但不利於業務的快速變化。Hadoop V1即採用此種架構。
兩階段調度將資源經過Offer的形式分發給註冊在調度系統中的各個Framework,由Framework負責處理接收到的Offer,調度底層系統僅用於資源的收集和治理。所以此種架構更易於經過Framework定製化擴展業務需求。Mesos便是兩階段調度的典型表明。
狀態共享調度功能看似最爲強大,但實現起來卻更加複雜。它的每個Framework均可以看到資源邏輯視圖的全集,採用樂觀鎖的方式使用資源,每次資源使用時,須要根據資源的佔用狀態進行相似於事務方式的提交和回滾。它的優勢是能夠更加有效的利用資源,缺點是實現難度高。除了Google閉源的Omega系統論文,開源產品中目前不多見成熟的實現方案。
上圖是噹噹雲平臺的架構圖。中間件API與業務應用一塊兒打包至Docker鏡像或tar文件,並放入應用倉庫。服務型應用噹噹採用Marathon管理,由DubboX治理服務,並與應用一同放入Docker鏡像;做業型應用噹噹使用自研的Mesos Framework Elastic-Job-Cloud代替Marathon進行瞬時和常駐做業的治理。
在Elastic-Job-Cloud中採用了自定義Executor和Mesos原生容器,它可以追加資源。利用此功能,能夠有效的聚合做業,進一步簡化開發並節省資源。Elastic-Job-Cloud調度的應用使用tar包存入應用倉庫。雖然Marathon與Elastic-Job-Cloud所管理的容器不一樣,但Mesos都會採用一樣的接口將其分發至相應Mesos Agent執行。
上圖是更加全面的總體雲化架構圖。能夠從運維、構建、日誌和監控4個方面說明。
運維經過自研的控制檯,向Mesos Framework發送信令和讀取數據來達到控制業務應用上下線、暫停執行等功能,並可查看運行時狀態。
構建是經過當當自研的盤古系統,控制灰度發佈,一鍵回滾等功能,並由盤古系統將待部署上線的應用鏡像推送至Nexus或Docker倉庫。由Mesos Agent自動從Nexus獲取tar文件、或由Docker倉庫獲取應用鏡像並執行。
日誌採用的標準的ELK的方式,不過獲取日誌並未使用Logstash,而是採用性能更佳的Filebeat代替。
監控是由多個維度組成。首先使用Mesos Exporter暴露Mesos的狀態數據,而後由時序數據庫Prometheus按期抓取,並由Grafana展示結果。Prometheus也經過Alertmanager向當當自研的雷達系統發送報警數據,由雷達系統負責最終的報警。其次,雷達系統還負責抓取elasticsearch的報警日誌以及運行歷史記錄、SLA等信息一併報警。
剛纔介紹的DubboX、Elastic-Job以及Sharding-JDBC都已開源。
Elastic-Job經不徹底統計,有30家以上的公司在使用。Elastic-Job目前是Mesosphere官方承認的Framework,在Apache Mesos的官方文檔中能夠查到,目前已經進行到對接DC/OS的最終階段。
Sharding-JDBC僅僅開源1年多,即獲取了2016年最受歡迎的國產開源第17名。
三個開源項目均採用Apache協議,有興趣的同窗請自由使用,歡迎提供寶貴意見。