原文出處: 楊步濤的博客
一、 設(shè)計(jì)理念
1. 空間換時(shí)間
1) 多級(jí)緩存嘱兼,靜態(tài)化
客戶端頁面緩存(http header中包含Expires/Cache of Control国葬,last modified(304,server不返回body芹壕,客戶端可以繼續(xù)用cache汇四,減少流量),ETag)
反向代理緩存
應(yīng)用端的緩存(memcache)
內(nèi)存數(shù)據(jù)庫
Buffer哪雕、cache機(jī)制(數(shù)據(jù)庫船殉,中間件等)
2) 索引
哈希、B樹斯嚎、倒排利虫、bitmap
哈希索引適合綜合數(shù)組的尋址和鏈表的插入特性挨厚,可以實(shí)現(xiàn)數(shù)據(jù)的快速存取。
B樹索引適合于查詢?yōu)橹鲗?dǎo)的場(chǎng)景糠惫,避免多次的IO疫剃,提高查詢的效率。
倒排索引實(shí)現(xiàn)單詞到文檔映射關(guān)系的最佳實(shí)現(xiàn)方式和最有效的索引結(jié)構(gòu)硼讽,廣泛用在搜索領(lǐng)域巢价。
Bitmap是一種非常簡(jiǎn)潔快速的數(shù)據(jù)結(jié)構(gòu),他能同時(shí)使存儲(chǔ)空間和速度最優(yōu)化(而不必空間換時(shí)間)固阁,適合于海量數(shù)據(jù)的的計(jì)算場(chǎng)景壤躲。
**2. 并行與分布式計(jì)算 **
1) 任務(wù)切分、分而治之(MR)
在大規(guī)模的數(shù)據(jù)中备燃,數(shù)據(jù)存在一定的局部性的特征碉克,利用局部性的原理將海量數(shù)據(jù)計(jì)算的問題分而治之。
MR模型是無共享的架構(gòu)并齐,數(shù)據(jù)集分布至各個(gè)節(jié)點(diǎn)漏麦。處理時(shí),每個(gè)節(jié)點(diǎn)就近讀取本地存儲(chǔ)的數(shù)據(jù)處理(map)况褪,將處理后的數(shù)據(jù)進(jìn)行合并(combine)撕贞、排序(shuffle and sort)后再分發(fā)(至reduce節(jié)點(diǎn)),避免了大量數(shù)據(jù)的傳輸测垛,提高了處理效率捏膨。
2) 多進(jìn)程、多線程并行執(zhí)行(MPP)
并行計(jì)算(Parallel Computing)是指同時(shí)使用多種計(jì)算資源解決計(jì)算問題的過程赐纱,是提高計(jì)算機(jī)系統(tǒng)計(jì)算速度和處理能力的一種有效手段脊奋。它的基本思想是用多個(gè)處理器/進(jìn)程/線程來協(xié)同求解同一問題,即將被求解的問題分解成若干個(gè)部分疙描,各部分均由一個(gè)獨(dú)立的處理機(jī)來并行計(jì)算诚隙。
和MR的區(qū)別在于,它是基于問題分解的起胰,而不是基于數(shù)據(jù)分解久又。
3. 多維度的可用
1) 負(fù)載均衡、容災(zāi)效五、備份
隨著平臺(tái)并發(fā)量的增大地消,需要擴(kuò)容節(jié)點(diǎn)進(jìn)行集群,利用負(fù)載均衡設(shè)備進(jìn)行請(qǐng)求的分發(fā)畏妖;負(fù)載均衡設(shè)備通常在提供負(fù)載均衡的同時(shí)脉执,也提供失效檢測(cè)功能;同時(shí)為了提高可用性戒劫,需要有容災(zāi)備份半夷,以防止節(jié)點(diǎn)宕機(jī)失效帶來的不可用問題婆廊;備份有在線的和離線備份,可以根據(jù)失效性要求的不同巫橄,進(jìn)行選擇不同的備份策略淘邻。
2) 讀寫分離
讀寫分離是對(duì)數(shù)據(jù)庫來講的,隨著系統(tǒng)并發(fā)量的增大湘换,提高數(shù)據(jù)訪問可用性的一個(gè)重要手段就是寫數(shù)據(jù)和讀數(shù)據(jù)進(jìn)行分離宾舅;當(dāng)然在讀寫分離的同時(shí),需要關(guān)注數(shù)據(jù)的一致性問題彩倚;對(duì)于一致性的問題筹我,在分布式的系統(tǒng)CAP定量中,更多的關(guān)注于可用性署恍。
3) 依賴關(guān)系
平臺(tái)中各個(gè)模塊之間的關(guān)系盡量是低耦合的崎溃,可以通過相關(guān)的消息組件進(jìn)行交互,能異步則異步盯质,分清楚數(shù)據(jù)流轉(zhuǎn)的主流程和副流程,主副是異步的概而,比如記錄日志可以是異步操作的呼巷,增加整個(gè)系統(tǒng)的可用性。
當(dāng)然在異步處理中赎瑰,為了確保數(shù)據(jù)得到接收或者處理王悍,往往需要確認(rèn)機(jī)制(confirm、ack)餐曼。
但是有些場(chǎng)景中压储,雖然請(qǐng)求已經(jīng)得到處理,但是因其他原因(比如網(wǎng)絡(luò)不穩(wěn)定)源譬,確認(rèn)消息沒有返回集惋,那么這種情況下需要進(jìn)行請(qǐng)求的重發(fā),對(duì)請(qǐng)求的處理設(shè)計(jì)因重發(fā)因素需要考慮冪等性踩娘。
4) 監(jiān)控
監(jiān)控也是提高整個(gè)平臺(tái)可用性的一個(gè)重要手段刮刑,多平臺(tái)進(jìn)行多個(gè)維度的監(jiān)控;模塊在運(yùn)行時(shí)候是透明的养渴,以達(dá)到運(yùn)行期白盒化雷绢。
4. 伸縮
1) 拆分
拆分包括對(duì)業(yè)務(wù)的拆分和對(duì)數(shù)據(jù)庫的拆分。
系統(tǒng)的資源總是有限的理卑,一段比較長(zhǎng)的業(yè)務(wù)執(zhí)行如果是一竿子執(zhí)行的方式翘紊,在大量并發(fā)的操作下,這種阻塞的方式藐唠,無法有效的及時(shí)釋放資源給其他進(jìn)程執(zhí)行帆疟,這樣系統(tǒng)的吞吐量不高孵滞。
需要把業(yè)務(wù)進(jìn)行邏輯的分段,采用異步非阻塞的方式鸯匹,提高系統(tǒng)的吞吐量坊饶。
隨著數(shù)據(jù)量和并發(fā)量的增加,讀寫分離不能滿足系統(tǒng)并發(fā)性能的要求殴蓬,需要對(duì)數(shù)據(jù)進(jìn)行切分匿级,包括對(duì)數(shù)據(jù)進(jìn)行分庫和分表。這種分庫分表的方式染厅,需要增加對(duì)數(shù)據(jù)的路由邏輯支持痘绎。
2) 無狀態(tài)
對(duì)于系統(tǒng)的伸縮性而言,模塊最好是無狀態(tài)的肖粮,通過增加節(jié)點(diǎn)就可以提高整個(gè)的吞吐量孤页。
5. 優(yōu)化資源利用
1) 系統(tǒng)容量有限
系統(tǒng)的容量是有限的,承受的并發(fā)量也是有限的涩馆,在架構(gòu)設(shè)計(jì)時(shí)行施,一定需要考慮流量的控制,防止因意外攻擊或者瞬時(shí)并發(fā)量的沖擊導(dǎo)致系統(tǒng)崩潰魂那。在設(shè)計(jì)時(shí)增加流控的措施蛾号,可考慮對(duì)請(qǐng)求進(jìn)行排隊(duì),超出預(yù)期的范圍涯雅,可以進(jìn)行告警或者丟棄鲜结。
2) 原子操作與并發(fā)控制
對(duì)于共享資源的訪問,為了防止沖突活逆,需要進(jìn)行并發(fā)的控制精刷,同時(shí)有些交易需要有事務(wù)性來保證交易的一致性,所以在交易系統(tǒng)的設(shè)計(jì)時(shí)蔗候,需考慮原子操作和并發(fā)控制怒允。
保證并發(fā)控制一些常用高性能手段有,樂觀鎖琴庵、Latch误算、mutex、寫時(shí)復(fù)制迷殿、CAS等儿礼;多版本的并發(fā)控制MVCC通常是保證一致性的重要手段,這個(gè)在數(shù)據(jù)庫的設(shè)計(jì)中經(jīng)常會(huì)用到庆寺。
3) 基于邏輯的不同蚊夫,采取不一樣的策略
平臺(tái)中業(yè)務(wù)邏輯存在不同的類型,有計(jì)算復(fù)雜型的懦尝,有消耗IO型的知纷,同時(shí)就同一種類型而言壤圃,不同的業(yè)務(wù)邏輯消耗的資源數(shù)量也是不一樣的,這就需要針對(duì)不同的邏輯采取不同的策略琅轧。
針對(duì)IO型的伍绳,可以采取基于事件驅(qū)動(dòng)的異步非阻塞的方式,單線程方式可以減少線程的切換引起的開銷乍桂,或者在多線程的情況下采取自旋spin的方式冲杀,減少對(duì)線程的切換(比如oracle latch設(shè)計(jì));對(duì)于計(jì)算型的睹酌,充分利用多線程進(jìn)行操作权谁。
同一類型的調(diào)用方式,不同的業(yè)務(wù)進(jìn)行合適的資源分配憋沿,設(shè)置不同的計(jì)算節(jié)點(diǎn)數(shù)量或者線程數(shù)量旺芽,對(duì)業(yè)務(wù)進(jìn)行分流,優(yōu)先執(zhí)行優(yōu)先級(jí)別高的業(yè)務(wù)辐啄。
4) 容錯(cuò)隔離
系統(tǒng)的有些業(yè)務(wù)模塊在出現(xiàn)錯(cuò)誤時(shí)采章,為了減少并發(fā)下對(duì)正常請(qǐng)求的處理的影響,有時(shí)候需要考慮對(duì)這些異常狀態(tài)的請(qǐng)求進(jìn)行單獨(dú)渠道的處理则披,甚至?xí)簳r(shí)自動(dòng)禁止這些異常的業(yè)務(wù)模塊共缕。
有些請(qǐng)求的失敗可能是偶然的暫時(shí)的失敗(比如網(wǎng)絡(luò)不穩(wěn)定),需要進(jìn)行請(qǐng)求重試的考慮士复。
5) 資源釋放
系統(tǒng)的資源是有限的,在使用資源時(shí)翩活,一定要在最后釋放資源阱洪,無論是請(qǐng)求走的是正常路徑還是異常的路徑,以便于資源的及時(shí)回收菠镇,供其他請(qǐng)求使用冗荸。
在設(shè)計(jì)通信的架構(gòu)時(shí),往往需要考慮超時(shí)的控制利耍。
二蚌本、 靜態(tài)架構(gòu)藍(lán)圖
整個(gè)架構(gòu)是分層的分布式的架構(gòu),縱向包括CDN隘梨,負(fù)載均衡/反向代理程癌,web應(yīng)用,業(yè)務(wù)層轴猎,基礎(chǔ)服務(wù)層嵌莉,數(shù)據(jù)存儲(chǔ)層。水平方向包括對(duì)整個(gè)平臺(tái)的配置管理部署和監(jiān)控捻脖。
三锐峭、 剖析架構(gòu)
1. CDN
CDN系統(tǒng)能夠?qū)崟r(shí)地根據(jù)網(wǎng)絡(luò)流量和各節(jié)點(diǎn)的連接中鼠、負(fù)載狀況以及到用戶的距離和響應(yīng)時(shí)間等綜合信息將用戶的請(qǐng)求重新導(dǎo)向離用戶最近的服務(wù)節(jié)點(diǎn)上。其目的是使用戶可就近取得所需內(nèi)容沿癞,解決 Internet網(wǎng)絡(luò)擁擠的狀況援雇,提高用戶訪問網(wǎng)站的響應(yīng)速度。
對(duì)于大規(guī)模電子商務(wù)平臺(tái)一般需要建CDN做網(wǎng)絡(luò)加速椎扬,大型平臺(tái)如淘寶惫搏、京東都采用自建CDN,中小型的企業(yè)可以采用第三方CDN廠商合作盗舰,如藍(lán)汛晶府、網(wǎng)宿、快網(wǎng)等钻趋。
當(dāng)然在選擇CDN廠商時(shí)川陆,需要考慮經(jīng)營(yíng)時(shí)間長(zhǎng)短,是否有可擴(kuò)充的帶寬資源蛮位、靈活的流量和帶寬選擇较沪、穩(wěn)定的節(jié)點(diǎn)、性價(jià)比失仁。
2. 負(fù)載均衡尸曼、反向代理
****一個(gè)大型的平臺(tái)包括很多個(gè)業(yè)務(wù)域,不同的業(yè)務(wù)域有不同的集群萄焦,可以用DNS做域名解析的分發(fā)或輪詢控轿,DNS方式實(shí)現(xiàn)簡(jiǎn)單,但是因存在cache而缺乏靈活性拂封;一般基于商用的硬件F5茬射、NetScaler或者開源的軟負(fù)載lvs在4層做分發(fā),當(dāng)然會(huì)采用做冗余(比如lvs+keepalived)的考慮冒签,采取主備方式在抛。
4層分發(fā)到業(yè)務(wù)集群上后,會(huì)經(jīng)過web服務(wù)器如nginx或者HAProxy在7層做負(fù)載均衡或者反向代理分發(fā)到集群中的應(yīng)用節(jié)點(diǎn)萧恕。
選擇哪種負(fù)載刚梭,需要綜合考慮各種因素(是否滿足高并發(fā)高性能,Session保持如何解決票唆,負(fù)載均衡的算法如何朴读,支持壓縮,緩存的內(nèi)存消耗)惰说;下面基于幾種常用的負(fù)載均衡軟件做個(gè)介紹磨德。
LVS,工作在4層,Linux實(shí)現(xiàn)的高性能高并發(fā)典挑、可伸縮性酥宴、可靠的的負(fù)載均衡器,支持多種轉(zhuǎn)發(fā)方式(NAT您觉、DR拙寡、IP Tunneling),其中DR模式支持通過廣域網(wǎng)進(jìn)行負(fù)載均衡琳水。支持雙機(jī)熱備(Keepalived或者Heartbeat)肆糕。對(duì)網(wǎng)絡(luò)環(huán)境的依賴性比較高。
Nginx工作在7層在孝,事件驅(qū)動(dòng)的诚啃、異步非阻塞的架構(gòu)、支持多進(jìn)程的高并發(fā)的負(fù)載均衡器/反向代理軟件私沮∈际辏可以針對(duì)域名、目錄結(jié)構(gòu)仔燕、正則規(guī)則針對(duì)http做一些分流造垛。通過端口檢測(cè)到服務(wù)器內(nèi)部的故障,比如根據(jù)服務(wù)器處理網(wǎng)頁返回的狀態(tài)碼晰搀、超時(shí)等等五辽,并且會(huì)把返回錯(cuò)誤的請(qǐng)求重新提交到另一個(gè)節(jié)點(diǎn),不過其中缺點(diǎn)就是不支持url來檢測(cè)外恕。對(duì)于session sticky杆逗,可以基于ip hash的算法來實(shí)現(xiàn),通過基于cookie的擴(kuò)展nginx-sticky-module支持session sticky鳞疲。
HAProxy支持4層和7層做負(fù)載均衡髓迎,支持session的會(huì)話保持,cookie的引導(dǎo)建丧;支持后端url方式的檢測(cè);負(fù)載均衡的算法比較豐富波势,有RR翎朱、權(quán)重等。
對(duì)于圖片尺铣,需要有單獨(dú)的域名拴曲,獨(dú)立或者分布式的圖片服務(wù)器或者如mogileFS,可以圖片服務(wù)器之上加varnish做圖片緩存凛忿。
3. App接入
****應(yīng)用層運(yùn)行在jboss或者tomcat容器中澈灼,代表獨(dú)立的系統(tǒng),比如前端購(gòu)物、用戶自主服務(wù)叁熔、后端系統(tǒng)等
協(xié)議接口委乌,HTTP、JSON
可以采用servlet3.0,異步化servlet,提高整個(gè)系統(tǒng)的吞吐量
http請(qǐng)求經(jīng)過Nginx荣回,通過負(fù)載均衡算法分到到App的某一節(jié)點(diǎn)遭贸,這一層層擴(kuò)容起來比較簡(jiǎn)單救鲤。
除了利用cookie保存少量用戶部分信息外(cookie一般不能超過4K的大小)盲链,對(duì)于App接入層,保存有用戶相關(guān)的session數(shù)據(jù)辉哥,但是有些反向代理或者負(fù)載均衡不支持對(duì)session sticky支持不是很好或者對(duì)接入的可用性要求比較高(app接入節(jié)點(diǎn)宕機(jī)删铃,session隨之丟失)耳贬,這就需要考慮session的集中式存儲(chǔ),使得App接入層無狀態(tài)化猎唁,同時(shí)系統(tǒng)用戶變多的時(shí)候咒劲,就可以通過增加更多的應(yīng)用節(jié)點(diǎn)來達(dá)到水平擴(kuò)展的目的。
Session的集中式存儲(chǔ)胖秒,需要滿足以下幾點(diǎn)要求:
a缎患、高效的通訊協(xié)議
b、session的分布式緩存阎肝,支持節(jié)點(diǎn)的伸縮挤渔,數(shù)據(jù)的冗余備份以及數(shù)據(jù)的遷移
c、session過期的管理
4. 業(yè)務(wù)服務(wù)
代表某一領(lǐng)域的業(yè)務(wù)提供的服務(wù)风题,對(duì)于電商而言判导,領(lǐng)域有用戶、商品沛硅、訂單眼刃、紅包、支付業(yè)務(wù)等等摇肌,不同的領(lǐng)域提供不同的服務(wù)擂红,
這些不同的領(lǐng)域構(gòu)成一個(gè)個(gè)模塊,良好的模塊劃分和接口設(shè)計(jì)非常重要围小,一般是參考高內(nèi)聚昵骤、接口收斂的原則,
這樣可以提高整個(gè)系統(tǒng)的可用性肯适。當(dāng)然可以根據(jù)應(yīng)用規(guī)模的大小变秦,模塊可以部署在一起,對(duì)于大規(guī)模的應(yīng)用框舔,一般是獨(dú)立部署的蹦玫。
高并發(fā):
業(yè)務(wù)層對(duì)外協(xié)議以NIO的RPC方式暴露赎婚,可以采用比較成熟的NIO通訊框架,如netty樱溉、mina
可用性:
為了提高模塊服務(wù)的可用性挣输,一個(gè)模塊部署在多個(gè)節(jié)點(diǎn)做冗余,并自動(dòng)進(jìn)行負(fù)載轉(zhuǎn)發(fā)和失效轉(zhuǎn)移;
最初可以利用VIP+heartbeat方式饺窿,目前系統(tǒng)有一個(gè)單獨(dú)的組件HA,利用zookeeper實(shí)現(xiàn)(比原來方案的優(yōu)點(diǎn))
一致性歧焦、事務(wù):
對(duì)于分布式系統(tǒng)的一致性,盡量滿足可用性肚医,一致性可以通過校對(duì)來達(dá)到最終一致的狀態(tài)绢馍。
5. 基礎(chǔ)服務(wù)中間件
1) 通信組件
通信組件用于業(yè)務(wù)系統(tǒng)內(nèi)部服務(wù)之間的調(diào)用,在大并發(fā)的電商平臺(tái)中肠套,需要滿足高并發(fā)高吞吐量的要求舰涌。
整個(gè)通信組件包括客戶端和服務(wù)端兩部分。
客戶端和服務(wù)器端維護(hù)的是長(zhǎng)連接你稚,可以減少每次請(qǐng)求建立連接的開銷瓷耙,在客戶端對(duì)于每個(gè)服務(wù)器定義一個(gè)連接池,初始化連接后刁赖,可以并發(fā)連接服務(wù)端進(jìn)行rpc操作搁痛,連接池中的長(zhǎng)連接需要心跳維護(hù),設(shè)置請(qǐng)求超時(shí)時(shí)間宇弛。
對(duì)于長(zhǎng)連接的維護(hù)過程可以分兩個(gè)階段鸡典,一個(gè)是發(fā)送請(qǐng)求過程,另外一個(gè)是接收響應(yīng)過程枪芒。在發(fā)送請(qǐng)求過程中彻况,若發(fā)生IOException,則把該連接標(biāo)記失效舅踪。接收響應(yīng)時(shí)纽甘,服務(wù)端返回SocketTimeoutException,如果設(shè)置了超時(shí)時(shí)間抽碌,那么就直接返回異常悍赢,清除當(dāng)前連接中那些超時(shí)的請(qǐng)求。否則繼續(xù)發(fā)送心跳包(因?yàn)榭赡苁莵G包货徙,超過pingInterval間隔時(shí)間就發(fā)送ping操作)泽裳,若ping不通(發(fā)送IOException),則說明當(dāng)前連接是有問題的破婆,那么就把當(dāng)前連接標(biāo)記成已經(jīng)失效;若ping通胸囱,則說明當(dāng)前連接是可靠的祷舀,繼續(xù)進(jìn)行讀操作。失效的連接會(huì)從連接池中清除掉。
每個(gè)連接對(duì)于接收響應(yīng)來說都以單獨(dú)的線程運(yùn)行裳扯,客戶端可以通過同步(wait,notify)方式或者異步進(jìn)行rpc調(diào)用抛丽,
序列化采用更高效的hession序列化方式。
服務(wù)端采用事件驅(qū)動(dòng)的NIO的MINA框架饰豺,支撐高并發(fā)高吞吐量的請(qǐng)求亿鲜。
2) 路由Router
在大多數(shù)的數(shù)據(jù)庫切分解決方案中,為了提高數(shù)據(jù)庫的吞吐量冤吨,首先是對(duì)不同的表進(jìn)行垂直切分到不同的數(shù)據(jù)庫中蒿柳,
然后當(dāng)數(shù)據(jù)庫中一個(gè)表超過一定大小時(shí),需要對(duì)該表進(jìn)行水平切分漩蟆,這里也是一樣垒探,這里以用戶表為例;
對(duì)于訪問數(shù)據(jù)庫客戶端來講怠李,需要根據(jù)用戶的ID圾叼,定位到需要訪問的數(shù)據(jù);
數(shù)據(jù)切分算法捺癞,
根據(jù)用戶的ID做hash操作夷蚊,一致性Hash,這種方式存在失效數(shù)據(jù)的遷移問題髓介,遷移時(shí)間內(nèi)服務(wù)不可用
維護(hù)路由表惕鼓,路由表中存儲(chǔ)用戶和sharding的映射關(guān)系,sharding分為leader和replica,分別負(fù)責(zé)寫和讀
這樣每個(gè)biz客戶端都需要保持所有sharding的連接池版保,這樣有個(gè)缺點(diǎn)是會(huì)產(chǎn)生全連接的問題呜笑;
一種解決方法是sharding的切分提到業(yè)務(wù)服務(wù)層進(jìn)行,每個(gè)業(yè)務(wù)節(jié)點(diǎn)只維護(hù)一個(gè)shard的連接即可彻犁。
見圖(router)
路由組件的實(shí)現(xiàn)是這樣的(可用性叫胁、高性能、高并發(fā))
基于性能方面的考慮汞幢,采用mongodb中維護(hù)用戶id和shard的關(guān)系驼鹅,為了保證可用性,搭建replicatset集群森篷。
biz的sharding和數(shù)據(jù)庫的sharding是一一對(duì)應(yīng)的输钩,只訪問一個(gè)數(shù)據(jù)庫sharding.
biz業(yè)務(wù)注冊(cè)節(jié)點(diǎn)到zookeeper上/bizs/shard/下。
router監(jiān)聽zookeeper上/bizs/下節(jié)點(diǎn)狀態(tài)仲智,緩存在線biz在router中买乃。
client請(qǐng)求router獲取biz時(shí),router首先從mongodb中獲取用戶對(duì)應(yīng)的shard,router根據(jù)緩存的內(nèi)容通過RR算法獲取biz節(jié)點(diǎn)钓辆。
為了解決router的可用性和并發(fā)吞吐量問題剪验,對(duì)router進(jìn)行冗余肴焊,同時(shí)client監(jiān)聽zookeeper的/routers節(jié)點(diǎn)并緩存在線router節(jié)點(diǎn)列表。
3) HA
傳統(tǒng)實(shí)現(xiàn)HA的做法一般是采用虛擬IP漂移功戚,結(jié)合Heartbeat娶眷、keepalived等實(shí)現(xiàn)HA,
Keepalived使用vrrp方式進(jìn)行數(shù)據(jù)包的轉(zhuǎn)發(fā)啸臀,提供4層的負(fù)載均衡届宠,通過檢測(cè)vrrp數(shù)據(jù)包來切換,做冗余熱備更加適合與LVS搭配乘粒。Linux Heartbeat是基于網(wǎng)絡(luò)或者主機(jī)的服務(wù)的高可用豌注,HAProxy或者Nginx可以基于7層進(jìn)行數(shù)據(jù)包的轉(zhuǎn)發(fā),因此Heatbeat更加適合做HAProxy谓厘、Nginx幌羞,包括業(yè)務(wù)的高可用。
在分布式的集群中竟稳,可以用zookeeper做分布式的協(xié)調(diào)属桦,實(shí)現(xiàn)集群的列表維護(hù)和失效通知,客戶端可以選擇hash算法或者roudrobin實(shí)現(xiàn)負(fù)載均衡他爸;對(duì)于master-master模式聂宾、master-slave模式,可以通過zookeeper分布式鎖的機(jī)制來支持诊笤。
4) 消息Message
對(duì)于平臺(tái)各個(gè)系統(tǒng)之間的異步交互系谐,是通過MQ組件進(jìn)行的。
在設(shè)計(jì)消息服務(wù)組件時(shí)讨跟,需要考慮消息一致性纪他、持久化、可用性晾匠、以及完善的監(jiān)控體系茶袒。
業(yè)界開源的消息中間件主要RabbitMQ、kafka有兩種凉馆,
RabbitMQ,遵循AMQP協(xié)議薪寓,由內(nèi)在高并發(fā)的erlanng語言開發(fā);kafka是Linkedin于2010年12月份開源的消息發(fā)布訂閱系統(tǒng),它主要用于處理活躍的流式數(shù)據(jù),大數(shù)據(jù)量的數(shù)據(jù)處理上澜共。
對(duì)消息一致性要求比較高的場(chǎng)合需要有應(yīng)答確認(rèn)機(jī)制向叉,包括生產(chǎn)消息和消費(fèi)消息的過程;不過因網(wǎng)絡(luò)等原理導(dǎo)致的應(yīng)答缺失嗦董,可能會(huì)導(dǎo)致消息的重復(fù)母谎,這個(gè)可以在業(yè)務(wù)層次根據(jù)冪等性進(jìn)行判斷過濾;RabbitMQ采用的是這種方式京革。還有一種機(jī)制是消費(fèi)端從broker拉取消息時(shí)帶上LSN號(hào)销睁,從broker中某個(gè)LSN點(diǎn)批量拉取消息供璧,這樣無須應(yīng)答機(jī)制,kafka分布式消息中間件就是這種方式冻记。
消息的在broker中的存儲(chǔ),根據(jù)消息的可靠性的要求以及性能方面的綜合衡量来惧,可以在內(nèi)存中冗栗,可以持久化到存儲(chǔ)上。
對(duì)于可用性和高吞吐量的要求供搀,集群和主備模式都可以在實(shí)際的場(chǎng)景應(yīng)用的到隅居。RabbitMQ解決方案中有普通的集群和可用性更高的mirror queue方式。 kafka采用zookeeper對(duì)集群中的broker葛虐、consumer進(jìn)行管理胎源,可以注冊(cè)topic到zookeeper上;通過zookeeper的協(xié)調(diào)機(jī)制屿脐,producer保存對(duì)應(yīng)topic的broker信息涕蚤,可以隨機(jī)或者輪詢發(fā)送到broker上;并且producer可以基于語義指定分片的诵,消息發(fā)送到broker的某分片上万栅。
總體來講,RabbitMQ用在實(shí)時(shí)的對(duì)可靠性要求比較高的消息傳遞上西疤。kafka主要用于處理活躍的流式數(shù)據(jù),大數(shù)據(jù)量的數(shù)據(jù)處理上烦粒。
5) Cache&Buffer
Cache系統(tǒng)
在一些高并發(fā)高性能的場(chǎng)景中,使用cache可以減少對(duì)后端系統(tǒng)的負(fù)載代赁,承擔(dān)可大部分讀的壓力扰她,可以大大提高系統(tǒng)的吞吐量,比如通常在數(shù)據(jù)庫存儲(chǔ)之前增加cache緩存芭碍。
但是引入cache架構(gòu)不可避免的帶來一些問題徒役,cache命中率的問題, cache失效引起的抖動(dòng),cache和存儲(chǔ)的一致性豁跑。
Cache中的數(shù)據(jù)相對(duì)于存儲(chǔ)來講廉涕,畢竟是有限的,比較理想的情況是存儲(chǔ)系統(tǒng)的熱點(diǎn)數(shù)據(jù)艇拍,這里可以用一些常見的算法LRU等等淘汰老的數(shù)據(jù)狐蜕;隨著系統(tǒng)規(guī)模的增加,單個(gè)節(jié)點(diǎn)cache不能滿足要求卸夕,就需要搭建分布式Cache层释;為了解決單個(gè)節(jié)點(diǎn)失效引起的抖動(dòng) ,分布式cache一般采用一致性hash的解決方案快集,大大減少因單個(gè)節(jié)點(diǎn)失效引起的抖動(dòng)范圍贡羔;而對(duì)于可用性要求比較高的場(chǎng)景廉白,每個(gè)節(jié)點(diǎn)都是需要有備份的。數(shù)據(jù)在cache和存儲(chǔ)上都存有同一份備份乖寒,必然有一致性的問題猴蹂,一致性比較強(qiáng)的,在更新數(shù)據(jù)庫的同時(shí)楣嘁,更新數(shù)據(jù)庫cache磅轻。對(duì)于一致性要求不高的,可以去設(shè)置緩存失效時(shí)間的策略逐虚。
Memcached作為高速的分布式緩存服務(wù)器聋溜,協(xié)議比較簡(jiǎn)單,基于libevent的事件處理機(jī)制叭爱。
Cache系統(tǒng)在平臺(tái)中用在router系統(tǒng)的客戶端中撮躁,熱點(diǎn)的數(shù)據(jù)會(huì)緩存在客戶端,當(dāng)數(shù)據(jù)訪問失效時(shí)买雾,才去訪問router系統(tǒng)把曼。
當(dāng)然目前更多的利用內(nèi)存型的數(shù)據(jù)庫做cache,比如redis凝果、mongodb祝迂;redis比memcache有豐富的數(shù)據(jù)操作的API;redis和mongodb都對(duì)數(shù)據(jù)進(jìn)行了持久化器净,而memcache沒有這個(gè)功能型雳,因此memcache更加適合在關(guān)系型數(shù)據(jù)庫之上的數(shù)據(jù)的緩存。
Buffer系統(tǒng)
用在高速的寫操作的場(chǎng)景中山害,平臺(tái)中有些數(shù)據(jù)需要寫入數(shù)據(jù)庫纠俭,并且數(shù)據(jù)是分庫分表的,但對(duì)數(shù)據(jù)的可靠性不是那么高浪慌,為了減少對(duì)數(shù)據(jù)庫的寫壓力冤荆,可以采取批量寫操作的方式。
開辟一個(gè)內(nèi)存區(qū)域权纤,當(dāng)數(shù)據(jù)到達(dá)區(qū)域的一定閥值時(shí)如80%時(shí)钓简,在內(nèi)存中做分庫梳理工作(內(nèi)存速度還是比較快的),后分庫批量flush汹想。
6) 搜索
在電子商務(wù)平臺(tái)中搜索是一個(gè)非常的重要功能外邓,主要有搜索詞類目導(dǎo)航、自動(dòng)提示和搜索排序功能古掏。
開源的企業(yè)級(jí)搜索引擎主要有l(wèi)ucene, sphinx损话,這里不去論述哪種搜索引擎更好一些,不過選擇搜索引擎除了基本的功能需要支持外,非功能方面需要考慮以下兩點(diǎn):
a丧枪、 搜索引擎是否支持分布式的索引和搜索光涂,來應(yīng)對(duì)海量的數(shù)據(jù),支持讀寫分離拧烦,提高可用性
b忘闻、 索引的實(shí)時(shí)性
c、 性能
Solr是基于lucene的高性能的全文搜索服務(wù)器恋博,提供了比lucene更為豐富的查詢語言服赎,可配置可擴(kuò)展,對(duì)外提供基于http協(xié)議的XML/JSON格式的接口交播。
從Solr4版本開始提供了SolrCloud方式來支持分布式的索引,自動(dòng)進(jìn)行sharding數(shù)據(jù)切分践付;通過每個(gè)sharding的master-slave(leader秦士、replica)模式提高搜索的性能;利用zookeeper對(duì)集群進(jìn)行管理永高,包括leader選舉等等隧土,保障集群的可用性。
Lucene索引的Reader是基于索引的snapshot的命爬,所以必須在索引commit的后曹傀,重新打開一個(gè)新的snapshot,才能搜索到新添加的內(nèi)容饲宛;而索引的commit是非常耗性能的皆愉,這樣達(dá)到實(shí)時(shí)索引搜索效率就比較低下。
對(duì)于索引搜索實(shí)時(shí)性艇抠,Solr4的之前解決方案是結(jié)合文件全量索引和內(nèi)存增量索引合并的方式幕庐,參見下圖。
Solr4提供了NRT softcommit的解決方案家淤,softcommit無需進(jìn)行提交索引操作异剥,就可以搜素到最新對(duì)索引的變更,不過對(duì)索引的變更并沒有sync commit到硬盤存儲(chǔ)上絮重,若發(fā)生意外導(dǎo)致程序非正常結(jié)束冤寿,未commit的數(shù)據(jù)會(huì)丟失,因此需要定時(shí)的進(jìn)行commit操作青伤。
平臺(tái)中對(duì)數(shù)據(jù)的索引和存儲(chǔ)操作是異步的督怜,可以大大提高可用性和吞吐量;只對(duì)某些屬性字段做索引操作潮模,存儲(chǔ)數(shù)據(jù)的標(biāo)識(shí)key亮蛔,減少索引的大小擎厢;數(shù)據(jù)是存儲(chǔ)在分布式存儲(chǔ)HBase 中的究流,HBase對(duì)二級(jí)索引搜索支持的不好辣吃,然而可以結(jié)合Solr搜索功能進(jìn)行多維度的檢索統(tǒng)計(jì)。
索引數(shù)據(jù)和HBase數(shù)據(jù)存儲(chǔ)的一致性芬探,也就是如何保障HBase存儲(chǔ)的數(shù)據(jù)都被索引過神得,可以采用confirm確認(rèn)機(jī)制,通過在索引前建立待索引數(shù)據(jù)隊(duì)列偷仿,在數(shù)據(jù)存儲(chǔ)并索引完成后哩簿,從待索引數(shù)據(jù)隊(duì)列中刪除數(shù)據(jù)。
7) 日志收集
在整個(gè)交易過程中酝静,會(huì)產(chǎn)生大量的日志节榜,這些日志需要收集到分布式存儲(chǔ)系統(tǒng)中存儲(chǔ)起來,以便于集中式的查詢和分析處理别智。
日志系統(tǒng)需具備三個(gè)基本組件宗苍,分別為agent(封裝數(shù)據(jù)源,將數(shù)據(jù)源中的數(shù)據(jù)發(fā)送給collector)薄榛,collector(接收多個(gè)agent的數(shù)據(jù)讳窟,并進(jìn)行匯總后導(dǎo)入后端的store中),store(中央存儲(chǔ)系統(tǒng)敞恋,應(yīng)該具有可擴(kuò)展性和可靠性丽啡,應(yīng)該支持當(dāng)前非常流行的HDFS)。
開源的日志收集系統(tǒng)業(yè)界使用的比較多的是cloudera的Flume和facebook的Scribe硬猫,其中Flume目前的版本FlumeNG對(duì)Flume從架構(gòu)上做了較大的改動(dòng)补箍。
在設(shè)計(jì)或者對(duì)日志收集系統(tǒng)做技術(shù)選型時(shí),通常需要具有以下特征:
a浦徊、 應(yīng)用系統(tǒng)和分析系統(tǒng)之間的橋梁馏予,將他們之間的關(guān)系解耦
b、 分布式可擴(kuò)展盔性,具有高的擴(kuò)展性霞丧,當(dāng)數(shù)據(jù)量增加時(shí),可以通過增加節(jié)點(diǎn)水平擴(kuò)展
日志收集系統(tǒng)是可以伸縮的冕香,在系統(tǒng)的各個(gè)層次都可伸縮蛹尝,對(duì)數(shù)據(jù)的處理不需要帶狀態(tài),伸縮性方面也比較容易實(shí)現(xiàn)悉尾。
c突那、 近實(shí)時(shí)性
在一些時(shí)效性要求比較高的場(chǎng)景中,需要可以及時(shí)的收集日志构眯,進(jìn)行數(shù)據(jù)分析愕难;
一般的日志文件都會(huì)定時(shí)或者定量的進(jìn)行rolling,所以實(shí)時(shí)檢測(cè)日志文件的生成,及時(shí)對(duì)日志文件進(jìn)行類似的tail操作猫缭,并支持批量發(fā)送提高傳輸效率葱弟;批量發(fā)送的時(shí)機(jī)需要滿足消息數(shù)量和時(shí)間間隔的要求。
d猜丹、 容錯(cuò)性
Scribe在容錯(cuò)方面的考慮是芝加,當(dāng)后端的存儲(chǔ)系統(tǒng)crash時(shí),scribe會(huì)將數(shù)據(jù)寫到本地磁盤上射窒,當(dāng)存儲(chǔ)系統(tǒng)恢復(fù)正常后藏杖,scribe將日志重新加載到存儲(chǔ)系統(tǒng)中。
FlumeNG通過Sink Processor實(shí)現(xiàn)負(fù)載均衡和故障轉(zhuǎn)移脉顿。多個(gè)Sink可以構(gòu)成一個(gè)Sink Group蝌麸。一個(gè)Sink Processor負(fù)責(zé)從一個(gè)指定的Sink Group中激活一個(gè)Sink。Sink Processor可以通過組中所有Sink實(shí)現(xiàn)負(fù)載均衡艾疟;也可以在一個(gè)Sink失敗時(shí)轉(zhuǎn)移到另一個(gè)祥楣。
e、 事務(wù)支持
Scribe沒有考慮事務(wù)的支持汉柒。
Flume通過應(yīng)答確認(rèn)機(jī)制實(shí)現(xiàn)事務(wù)的支持,參見下圖责鳍,
通常提取發(fā)送消息都是批量操作的碾褂,消息的確認(rèn)是對(duì)一批數(shù)據(jù)的確認(rèn),這樣可以大大提高數(shù)據(jù)發(fā)送的效率历葛。
f正塌、 可恢復(fù)性
FlumeNG的channel根據(jù)可靠性的要求的不同,可以基于內(nèi)存和文件持久化機(jī)制恤溶,基于內(nèi)存的數(shù)據(jù)傳輸?shù)匿N量比較高乓诽,但是在節(jié)點(diǎn)宕機(jī)后,數(shù)據(jù)丟失咒程,不可恢復(fù)鸠天;而文件持久化宕機(jī)是可以恢復(fù)的。
g帐姻、 數(shù)據(jù)的定時(shí)定量歸檔
數(shù)據(jù)經(jīng)過日志收集系統(tǒng)歸集后稠集,一般存儲(chǔ)在分布式文件系統(tǒng)如Hadoop,為了便于對(duì)數(shù)據(jù)進(jìn)行后續(xù)的處理分析饥瓷,需要定時(shí)(TimeTrigger)或者定量(SizeTrigger的rolling分布式系統(tǒng)的文件剥纷。
8) 數(shù)據(jù)同步
在交易系統(tǒng)中,通常需要進(jìn)行異構(gòu)數(shù)據(jù)源的同步呢铆,通常有數(shù)據(jù)文件到關(guān)系型數(shù)據(jù)庫晦鞋,數(shù)據(jù)文件到分布式數(shù)據(jù)庫,關(guān)系型數(shù)據(jù)庫到分布式數(shù)據(jù)庫等。數(shù)據(jù)在異構(gòu)源之間的同步一般是基于性能和業(yè)務(wù)的需求悠垛,數(shù)據(jù)存儲(chǔ)在本地文件中一般是基于性能的考慮线定,文件是順序存儲(chǔ)的,效率還是比較高的鼎文;數(shù)據(jù)同步到關(guān)系型數(shù)據(jù)一般是基于查詢的需求渔肩;而分布式數(shù)據(jù)庫是存儲(chǔ)越來越多的海量數(shù)據(jù)的,而關(guān)系型數(shù)據(jù)庫無法滿足大數(shù)據(jù)量的存儲(chǔ)和查詢請(qǐng)求拇惋。
在數(shù)據(jù)同步的設(shè)計(jì)中需要綜合考慮吞吐量周偎、容錯(cuò)性、可靠性撑帖、一致性的問題
同步有實(shí)時(shí)增量數(shù)據(jù)同步和離線全量數(shù)據(jù)區(qū)分蓉坎,下面從這兩個(gè)維度來介紹一下,
實(shí)時(shí)增量一般是Tail文件來實(shí)時(shí)跟蹤文件變化胡嘿,批量或者多線程往數(shù)據(jù)庫導(dǎo)出,這種方式的架構(gòu)類似于日志收集框架蛉艾。這種方式需要有確認(rèn)機(jī)制,包括兩個(gè)方面衷敌。
一個(gè)方面是Channel需要給agent確認(rèn)已經(jīng)批量收到數(shù)據(jù)記錄了勿侯,發(fā)送LSN號(hào)給agent,這樣在agent失效恢復(fù)時(shí)缴罗,可以從這個(gè)LSN點(diǎn)開始tail助琐;當(dāng)然對(duì)于允許少量的重復(fù)記錄的問題(發(fā)生在channel給agent確認(rèn)的時(shí),agent宕機(jī)并未受到確認(rèn)消息)面氓,需要在業(yè)務(wù)場(chǎng)景中判斷兵钮。
另外一個(gè)方面是sync給channel確認(rèn)已經(jīng)批量完成寫入到數(shù)據(jù)庫的操作,這樣channel可以刪除這部分已經(jīng)confirm的消息舌界。
基于可靠性的要求掘譬,channel可以采用文件持久化的方式。
參見下圖
離線全量遵循空間間換取時(shí)間呻拌,分而治之的原則葱轩,盡量的縮短數(shù)據(jù)同步的時(shí)間,提高同步的效率藐握。
需要對(duì)源數(shù)據(jù)比如mysql進(jìn)行切分酿箭,多線程并發(fā)讀源數(shù)據(jù),多線程并發(fā)批量寫入分布式數(shù)據(jù)庫比如HBase,利用channel作為讀寫之間的緩沖趾娃,實(shí)現(xiàn)更好的解耦缭嫡,channel可以基于文件存儲(chǔ)或者內(nèi)存。參見下圖:
對(duì)于源數(shù)據(jù)的切分抬闷,如果是文件可以根據(jù)文件名稱設(shè)置塊大小來切分妇蛀。
對(duì)于關(guān)系型數(shù)據(jù)庫耕突,由于一般的需求是只離線同步一段時(shí)間的數(shù)據(jù)(比如凌晨把當(dāng)天的訂單數(shù)據(jù)同步到HBase)赡磅,所以需要在數(shù)據(jù)切分時(shí)(按照行數(shù)切分)滞项,會(huì)多線程掃描整個(gè)表(及時(shí)建索引,也要回表)痴怨,對(duì)于表中包含大量的數(shù)據(jù)來講纵诞,IO很高上祈,效率非常低;這里解決的方法是對(duì)數(shù)據(jù)庫按照時(shí)間字段(按照時(shí)間同步的)建立分區(qū)浙芙,每次按照分區(qū)進(jìn)行導(dǎo)出登刺。
9) 數(shù)據(jù)分析
從傳統(tǒng)的基于關(guān)系型數(shù)據(jù)庫并行處理集群、用于內(nèi)存計(jì)算近實(shí)時(shí)的嗡呼,到目前的基于hadoop的海量數(shù)據(jù)的分析纸俭,數(shù)據(jù)的分析在大型電子商務(wù)網(wǎng)站中應(yīng)用非常廣泛,包括流量統(tǒng)計(jì)南窗、推薦引擎揍很、趨勢(shì)分析、用戶行為分析万伤、數(shù)據(jù)挖掘分類器窒悔、分布式索引等等。
并行處理集群有商業(yè)的EMC Greenplum敌买,Greenplum的架構(gòu)采用了MPP(大規(guī)模并行處理)蛉迹,基于postgresql的大數(shù)據(jù)量存儲(chǔ)的分布式數(shù)據(jù)庫。
內(nèi)存計(jì)算方面有SAP的HANA放妈,開源的nosql內(nèi)存型的數(shù)據(jù)庫mongodb也支持mapreduce進(jìn)行數(shù)據(jù)的分析。
海量數(shù)據(jù)的離線分析目前互聯(lián)網(wǎng)公司大量的使用Hadoop荐操,Hadoop在可伸縮性芜抒、健壯性、計(jì)算性能和成本上具有無可替代的優(yōu)勢(shì)托启,事實(shí)上已成為當(dāng)前互聯(lián)網(wǎng)企業(yè)主流的大數(shù)據(jù)分析平臺(tái)
Hadoop通過MapReuce的分布式處理框架宅倒,用于處理大規(guī)模的數(shù)據(jù),伸縮性也非常好屯耸;但是MapReduce最大的不足是不能滿足實(shí)時(shí)性的場(chǎng)景拐迁,主要用于離線的分析。
基于MapRduce模型編程做數(shù)據(jù)的分析疗绣,開發(fā)上效率不高线召,位于hadoop之上Hive的出現(xiàn)使得數(shù)據(jù)的分析可以類似編寫sql的方式進(jìn)行,sql經(jīng)過語法分析多矮、生成執(zhí)行計(jì)劃后最終生成MapReduce任務(wù)進(jìn)行執(zhí)行缓淹,這樣大大提高了開發(fā)的效率哈打,做到以ad-hoc(計(jì)算在query發(fā)生時(shí))方式進(jìn)行的分析。
基于MapReduce模型的分布式數(shù)據(jù)的分析都是離線的分析讯壶,執(zhí)行上都是暴力掃描料仗,無法利用類似索引的機(jī)制;開源的Cloudera Impala是基于MPP的并行編程模型的伏蚊,底層是Hadoop存儲(chǔ)的高性能的實(shí)時(shí)分析平臺(tái)立轧,可以大大降低數(shù)據(jù)分析的延遲。
目前Hadoop使用的版本是Hadoop1.0躏吊,一方面原有的MapReduce框架存在JobTracker單點(diǎn)的問題氛改,另外一方面JobTracker在做資源管理的同時(shí)又做任務(wù)的調(diào)度工作,隨著數(shù)據(jù)量的增大和Job任務(wù)的增多颜阐,明顯存在可擴(kuò)展性平窘、內(nèi)存消耗、線程模型凳怨、可靠性和性能上的缺陷瓶頸瑰艘;Hadoop2.0 yarn對(duì)整個(gè)框架進(jìn)行了重構(gòu),分離了資源管理和任務(wù)調(diào)度肤舞,從架構(gòu)設(shè)計(jì)上解決了這個(gè)問題紫新。
參考Yarn的架構(gòu)
10) 實(shí)時(shí)計(jì)算
在互聯(lián)網(wǎng)領(lǐng)域,實(shí)時(shí)計(jì)算被廣泛實(shí)時(shí)監(jiān)控分析李剖、流控芒率、風(fēng)險(xiǎn)控制等領(lǐng)域。電商平臺(tái)系統(tǒng)或者應(yīng)用對(duì)日常產(chǎn)生的大量日志和異常信息篙顺,需要經(jīng)過實(shí)時(shí)過濾偶芍、分析,以判定是否需要預(yù)警德玫;
同時(shí)需要對(duì)系統(tǒng)做自我保護(hù)機(jī)制匪蟀,比如對(duì)模塊做流量的控制,以防止非預(yù)期的對(duì)系統(tǒng)壓力過大而引起的系統(tǒng)癱瘓宰僧,流量過大時(shí)材彪,可以采取拒絕或者引流等機(jī)制;有些業(yè)務(wù)需要進(jìn)行風(fēng)險(xiǎn)的控制琴儿,比如彩票中有些業(yè)務(wù)需要根據(jù)系統(tǒng)的實(shí)時(shí)銷售情況進(jìn)行限號(hào)與放號(hào)段化。
原始基于單節(jié)點(diǎn)的計(jì)算,隨著系統(tǒng)信息量爆炸式產(chǎn)生以及計(jì)算的復(fù)雜度的增加造成,單個(gè)節(jié)點(diǎn)的計(jì)算已不能滿足實(shí)時(shí)計(jì)算的要求显熏,需要進(jìn)行多節(jié)點(diǎn)的分布式的計(jì)算,分布式實(shí)時(shí)計(jì)算平臺(tái)就出現(xiàn)了晒屎。
這里所說的實(shí)時(shí)計(jì)算佃延,其實(shí)是流式計(jì)算现诀,概念前身其實(shí)是CEP復(fù)雜事件處理,相關(guān)的開源產(chǎn)品如Esper履肃,業(yè)界分布式的流計(jì)算產(chǎn)品Yahoo S4,Twitter storm等仔沿,以storm開源產(chǎn)品使用最為廣泛。
對(duì)于實(shí)時(shí)計(jì)算平臺(tái)尺棋,從架構(gòu)設(shè)計(jì)上需要考慮以下幾個(gè)因素:
1封锉、 伸縮性
隨著業(yè)務(wù)量的增加,計(jì)算量的增加膘螟,通過增加節(jié)點(diǎn)處理成福,就可以處理。
2荆残、 高性能奴艾、低延遲
從數(shù)據(jù)流入計(jì)算平臺(tái)數(shù)據(jù),到計(jì)算輸出結(jié)果内斯,需要性能高效且低延遲蕴潦,保證消息得到快速的處理,做到實(shí)時(shí)計(jì)算俘闯。
3潭苞、 可靠性
保證每個(gè)數(shù)據(jù)消息得到一次完整處理。
4真朗、 容錯(cuò)性
系統(tǒng)可以自動(dòng)管理節(jié)點(diǎn)的宕機(jī)失效此疹,對(duì)應(yīng)用來說,是透明的遮婶。
Twitter的Storm在以上這幾個(gè)方面做的比較好蝗碎,下面簡(jiǎn)介一下Storm的架構(gòu)。
整個(gè)集群的管理是通過zookeeper來進(jìn)行的旗扑。
客戶端提交拓?fù)涞絥imbus蹦骑。
Nimbus針對(duì)該拓?fù)浣⒈镜氐哪夸浉鶕?jù)topology的配置計(jì)算task,分配task肩豁,在zookeeper上建立assignments節(jié)點(diǎn)存儲(chǔ)task和supervisor機(jī)器節(jié)點(diǎn)中woker的對(duì)應(yīng)關(guān)系。
在zookeeper上創(chuàng)建taskbeats節(jié)點(diǎn)來監(jiān)控task的心跳辫呻;啟動(dòng)topology清钥。
Supervisor去zookeeper上獲取分配的tasks,啟動(dòng)多個(gè)woker進(jìn)行放闺,每個(gè)woker生成task祟昭,一個(gè)task一個(gè)線程;根據(jù)topology信息初始化建立task之間的連接;Task和Task之間是通過zeroMQ管理的怖侦;之后整個(gè)拓?fù)溥\(yùn)行起來篡悟。
Tuple是流的基本處理單元谜叹,也就是一個(gè)消息,Tuple在task中流轉(zhuǎn)搬葬,Tuple的發(fā)送和接收過程如下:
發(fā)送Tuple荷腊,Worker提供了一個(gè)transfer的功能,用于當(dāng)前task把tuple發(fā)到到其他的task中急凰。以目的taskid和tuple參數(shù)女仰,序列化tuple數(shù)據(jù)并放到transfer queue中。
在0.8版本之前抡锈,這個(gè)queue是LinkedBlockingQueue疾忍,0.8之后是DisruptorQueue。
在0.8版本之后床三,每一個(gè)woker綁定一個(gè)inbound transfer queue和outbond queue一罩,inbound queue用于接收message,outbond queue用于發(fā)送消息撇簿。
發(fā)送消息時(shí)聂渊,由單個(gè)線程從transferqueue中拉取數(shù)據(jù),把這個(gè)tuple通過zeroMQ發(fā)送到其他的woker中补疑。
接收Tuple歧沪,每個(gè)woker都會(huì)監(jiān)聽zeroMQ的tcp端口來接收消息,消息放到DisruptorQueue中后莲组,后從queue中獲取message(taskid,tuple)诊胞,根據(jù)目的taskid,tuple的值路由到task中執(zhí)行。每個(gè)tuple可以emit到direct steam中锹杈,也可以發(fā)送到regular stream中撵孤,在Reglular方式下,由Stream Group(stream id–>component id –>outbond tasks)功能完成當(dāng)前tuple將要發(fā)送的Tuple的目的地竭望。
通過以上分析可以看到邪码,Storm在伸縮性、容錯(cuò)性咬清、高性能方面的從架構(gòu)設(shè)計(jì)的角度得以支撐闭专;同時(shí)在可靠性方面,Storm的ack組件利用異或xor算法在不失性能的同時(shí)旧烧,保證每一個(gè)消息得到完整處理的同時(shí)影钉。
11) 實(shí)時(shí)推送
實(shí)時(shí)推送的應(yīng)用場(chǎng)景非常多,比如系統(tǒng)的監(jiān)控動(dòng)態(tài)的實(shí)時(shí)曲線繪制掘剪,手機(jī)消息的推送平委,web實(shí)時(shí)聊天等。
實(shí)時(shí)推送有很多技術(shù)可以實(shí)現(xiàn)夺谁,有Comet方式廉赔,有websocket方式等肉微。
Comet基于服務(wù)器長(zhǎng)連接的“服務(wù)器推”技術(shù),包含兩種:
Long Polling:服務(wù)器端在接到請(qǐng)求后掛起蜡塌,有更新時(shí)返回連接即斷掉碉纳,然后客戶端再發(fā)起新的連接
Stream方式: 每次服務(wù)端數(shù)據(jù)傳送不會(huì)關(guān)閉連接,連接只會(huì)在通信出現(xiàn)錯(cuò)誤時(shí)岗照,或是連接重建時(shí)關(guān)閉(一些防火墻常被設(shè)置為丟棄過長(zhǎng)的連接村象, 服務(wù)器端可以設(shè)置一個(gè)超時(shí)時(shí)間, 超時(shí)后通知客戶端重新建立連接攒至,并關(guān)閉原來的連接)厚者。
Websocket:長(zhǎng)連接,全雙工通信
是 Html5 的一種新的協(xié)議迫吐。它實(shí)現(xiàn)了瀏覽器與服務(wù)器的雙向通訊库菲。webSocket API 中,瀏覽器和服務(wù)器端只需要通過一個(gè)握手的動(dòng)作志膀,便能形成瀏覽器與客戶端之間的快速雙向通道熙宇,使得數(shù)據(jù)可以快速的雙向傳播。
Socket.io是一個(gè)NodeJS websocket庫溉浙,包括客戶端的JS和服務(wù)端的的nodejs烫止,用于快速構(gòu)建實(shí)時(shí)的web應(yīng)用。
12) 推薦引擎
待補(bǔ)充
6. 數(shù)據(jù)存儲(chǔ)
****數(shù)據(jù)庫存儲(chǔ)大體分為以下幾類戳稽,有關(guān)系型(事務(wù)型)的數(shù)據(jù)庫馆蠕,以oracle、mysql為代表惊奇,有keyvalue數(shù)據(jù)庫互躬,以redis和memcached db為代表,有文檔型數(shù)據(jù)庫如mongodb颂郎,有列式分布式數(shù)據(jù)庫以HBase吼渡,cassandra,dynamo為代表,還有其他的圖形數(shù)據(jù)庫乓序、對(duì)象數(shù)據(jù) 庫寺酪、xml數(shù)據(jù)庫等。每種類型的數(shù)據(jù)庫應(yīng)用的業(yè)務(wù)領(lǐng)域是不一樣的替劈,下面從內(nèi)存型寄雀、關(guān)系型、分布式三個(gè)維度針對(duì)相關(guān)的產(chǎn)品做性能可用性等方面的考量分析抬纸。
1) 內(nèi)存型數(shù)據(jù)庫
內(nèi)存型的數(shù)據(jù)庫咙俩,以高并發(fā)高性能為目標(biāo)耿戚,在事務(wù)性方面沒那么嚴(yán)格湿故,以開源nosql數(shù)據(jù)庫mongodb阿趁、redis為例
? Mongodb
通信方式
多線程方式,主線程監(jiān)聽新的連接坛猪,連接后脖阵,啟動(dòng)新的線程做數(shù)據(jù)的操作(IO切換)。
數(shù)據(jù)結(jié)構(gòu)
數(shù)據(jù)庫–>collection–>record
MongoDB在數(shù)據(jù)存儲(chǔ)上按命名空間來劃分墅茉,一個(gè)collection是一個(gè)命名空間命黔,一個(gè)索引也是一個(gè)命名空間。
同一個(gè)命名空間的數(shù)據(jù)被分成很多個(gè)Extent就斤,Extent之間使用雙向鏈表連接悍募。
在每一個(gè)Extent中,保存了具體每一行的數(shù)據(jù)洋机,這些數(shù)據(jù)也是通過雙向鏈接連接的坠宴。
每一行數(shù)據(jù)存儲(chǔ)空間不僅包括數(shù)據(jù)占用空間,還可能包含一部分附加空間绷旗,這使得在數(shù)據(jù)update變大后可以不移動(dòng)位置喜鼓。
索引以BTree結(jié)構(gòu)實(shí)現(xiàn)。
如果你開啟了jorunaling日志衔肢,那么還會(huì)有一些文件存儲(chǔ)著你所有的操作記錄庄岖。
持久化存儲(chǔ)
MMap方式把文件地址映射到內(nèi)存的地址空間,直接操作內(nèi)存地址空間就可以操作文件角骤,不用再調(diào)用write,read操作隅忿,性能比較高。
mongodb調(diào)用mmap把磁盤中的數(shù)據(jù)映射到內(nèi)存中的启搂,所以必須有一個(gè)機(jī)制時(shí)刻的刷數(shù)據(jù)到硬盤才能保證可靠性硼控,多久刷一次是與syncdelay參數(shù)相關(guān)的。
journal(進(jìn)行恢復(fù)用)是Mongodb中的redo log胳赌,而Oplog則是負(fù)責(zé)復(fù)制的binlog牢撼。如果打開journal,那么即使斷電也只會(huì)丟失100ms的數(shù)據(jù)疑苫,這對(duì)大多數(shù)應(yīng)用來說都可以容忍了熏版。從1.9.2+,mongodb都會(huì)默認(rèn)打開journal功能捍掺,以確保數(shù)據(jù)安全撼短。而且journal的刷新時(shí)間是可以改變的,2-300ms的范圍,使用 –journalCommitInterval 命令挺勿。Oplog和數(shù)據(jù)刷新到磁盤的時(shí)間是60s曲横,對(duì)于復(fù)制來說,不用等到oplog刷新磁盤,在內(nèi)存中就可以直接復(fù)制到Sencondary節(jié)點(diǎn)禾嫉。
事務(wù)支持
Mongodb只支持對(duì)單行記錄的原子操作
HA集群
用的比較多的是Replica Sets灾杰,采用選舉算法,自動(dòng)進(jìn)行l(wèi)eader選舉熙参,在保證可用性的同時(shí)艳吠,可以做到強(qiáng)一致性要求。
當(dāng)然對(duì)于大量的數(shù)據(jù)孽椰,mongodb也提供了數(shù)據(jù)的切分架構(gòu)Sharding昭娩。
? Redis
豐富的數(shù)據(jù)結(jié)構(gòu),高速的響應(yīng)速度黍匾,內(nèi)存操作
通信方式
因都在內(nèi)存操作栏渺,所以邏輯的操作非常快锐涯,減少了CPU的切換開銷,所以為單線程的模式(邏輯處理線程和主線程是一個(gè))壶笼。
reactor模式责语,實(shí)現(xiàn)自己的多路復(fù)用NIO機(jī)制(epoll,select智末,kqueue等)
單線程處理多任務(wù)
數(shù)據(jù)結(jié)構(gòu)
hash+bucket結(jié)構(gòu),當(dāng)鏈表的長(zhǎng)度過長(zhǎng)時(shí),會(huì)采取遷移的措施(擴(kuò)展原來兩倍的hash表何乎,把數(shù)據(jù)遷移過去指孤,expand+rehash)
持久化存儲(chǔ)
a叉跛、全量持久化RDB(遍歷redisDB,讀取bucket中的key,value)酥艳,save命令阻塞主線程赫冬,bgsave開啟子進(jìn)程進(jìn)行snapshot持久化操作补鼻,生成rdb文件锌半。
在shutdown時(shí),會(huì)調(diào)用save操作
數(shù)據(jù)發(fā)生變化,在多少秒內(nèi)觸發(fā)一次bgsave
sync弛说,master接受slave發(fā)出來的命令
b、增量持久化(aof類似redolog)蒲列,先寫到日志buffer,再flush到日志文件中(flush的策略可以配置的窒朋,而已單條,也可以批量)蝗岖,只有flush到文件上的侥猩,才真正返回客戶端。
要定時(shí)對(duì)aof文件和rdb文件做合并操作(在快照過程中抵赢,變化的數(shù)據(jù)先寫到aof buf中等子進(jìn)程完成快照<內(nèi)存snapshot>后欺劳,再進(jìn)行合并aofbuf變化的部分以及全鏡像數(shù)據(jù))唧取。
在高并發(fā)訪問模式下,RDB模式使服務(wù)的性能指標(biāo)出現(xiàn)明顯的抖動(dòng)划提,aof在性能開銷上比RDB好枫弟,但是恢復(fù)時(shí)重新加載到內(nèi)存的時(shí)間和數(shù)據(jù)量成正比。
集群HA
通用的解決方案是主從備份切換鹏往,采用HA軟件淡诗,使得失效的主redis可以快速的切換到從redis上。主從數(shù)據(jù)的同步采用復(fù)制機(jī)制伊履,該場(chǎng)景可以做讀寫分離韩容。
目前在復(fù)制方面,存在的一個(gè)問題是在遇到網(wǎng)絡(luò)不穩(wěn)定的情況下湾碎,Slave和Master斷開(包括閃斷)會(huì)導(dǎo)致Master需要將內(nèi)存中的數(shù)據(jù)全部重新生成rdb文件(快照文件),然后傳輸給Slave奠货。Slave接收完Master傳遞過來的rdb文件以后會(huì)將自身的內(nèi)存清空介褥,把rdb文件重新加載到內(nèi)存中。這種方式效率比較低下递惋,在后面的未來版本Redis2.8作者已經(jīng)實(shí)現(xiàn)了部分復(fù)制的功能柔滔。
2) 關(guān)系型數(shù)據(jù)庫
關(guān)系型數(shù)據(jù)庫在滿足并發(fā)性能的同時(shí),也需要滿足事務(wù)性萍虽,以mysql數(shù)據(jù)庫為例睛廊,講述架構(gòu)設(shè)計(jì)原理,在性能方面的考慮杉编,以及如何滿足可用性的需求超全。
? mysql的架構(gòu)原理(innodb)
在架構(gòu)上,mysql分為server層和存儲(chǔ)引擎層邓馒。
Server層的架構(gòu)對(duì)于不同的存儲(chǔ)引擎來講都是一樣的,包括連接/線程處理嘶朱、查詢處理(parser、optimizer)以及其他系統(tǒng)任務(wù)光酣。存儲(chǔ)引擎層有很多種疏遏,mysql提供了存儲(chǔ)引擎的插件式結(jié)構(gòu),支持多種存儲(chǔ)引擎救军,用的最廣泛的是innodb和myisamin财异;inodb主要面向OLTP方面的應(yīng)用,支持事務(wù)處理唱遭,myisam不支持事務(wù)戳寸,表鎖,對(duì)OLAP操作速度快拷泽。
以下主要針對(duì)innodb存儲(chǔ)引擎做相關(guān)介紹庆揩。
在線程處理方面俐东,Mysql是多線程的架構(gòu),由一個(gè)master線程订晌,一個(gè)鎖監(jiān)控線程虏辫,一個(gè)錯(cuò)誤監(jiān)控線程,和多個(gè)IO線程組成锈拨。并且對(duì)一個(gè)連接會(huì)開啟一個(gè)線程進(jìn)行服務(wù)砌庄。io線程又分為節(jié)省隨機(jī)IO的insert buffer,用于事務(wù)控制的類似于oracle的redo log奕枢,以及多個(gè)write娄昆,多個(gè)read的硬盤和內(nèi)存交換的IO線程。
在內(nèi)存分配方面缝彬,包括innodb buffer pool 萌焰,以及l(fā)og buffer。其中innodb buffer pool包括insert buffer谷浅、datapage扒俯、index page、數(shù)據(jù)字典一疯、自適應(yīng)hash撼玄。Log buffer用于緩存事務(wù)日志,提供性能墩邀。
在數(shù)據(jù)結(jié)構(gòu)方面掌猛,innodb包括表空間、段眉睹、區(qū)荔茬、頁/塊,行竹海。索引結(jié)構(gòu)是B+tree結(jié)構(gòu)兔院,包括二級(jí)索引和主鍵索引,二級(jí)索引的葉子節(jié)點(diǎn)是主鍵PK站削,根據(jù)主鍵索引的葉子節(jié)點(diǎn)指向存儲(chǔ)的數(shù)據(jù)塊坊萝。這種B+樹存儲(chǔ)結(jié)構(gòu)可以更好的滿足隨機(jī)查詢操作IO要求,分為數(shù)據(jù)頁和二級(jí)索引頁许起,修改二級(jí)索引頁面涉及到隨機(jī)操作十偶,為了提高寫入時(shí)的性能,采用insert buffer做順序的寫入园细,再由后臺(tái)線程以一定頻率將多個(gè)插入合并到二級(jí)索引頁面惦积。為了保證數(shù)據(jù)庫的一致性(內(nèi)存和硬盤數(shù)據(jù)文件),以及縮短實(shí)例恢復(fù)的時(shí)間猛频,關(guān)系型數(shù)據(jù)庫還有一個(gè)checkpoint的功能狮崩,用于把內(nèi)存buffer中之前的臟頁按照比例(老的LSN)寫入磁盤蛛勉,這樣redolog文件的LSN以前的日志就可以被覆蓋了,進(jìn)行循環(huán)使用睦柴;在失效恢復(fù)時(shí)诽凌,只需要從日志中LSN點(diǎn)進(jìn)行恢復(fù)即可。
在事務(wù)特性支持上坦敌,關(guān)系型數(shù)據(jù)庫需要滿足ACID四個(gè)特性侣诵,需要根據(jù)不同的事務(wù)并發(fā)和數(shù)據(jù)可見性要求,定義了不同的事務(wù)隔離級(jí)別狱窘,并且離不開對(duì)資源爭(zhēng)用的鎖機(jī)制杜顺,要避免產(chǎn)生死鎖,mysql在Server層和存儲(chǔ)引擎層做并發(fā)控制蘸炸,主要體現(xiàn)在讀寫鎖躬络,根據(jù)鎖粒度不同,有各個(gè)級(jí)別的鎖(表鎖搭儒、行鎖穷当、頁鎖、MVCC)仗嗦;基于提高并發(fā)性能的考慮膘滨,使用多版本并發(fā)控制MVCC來支持事務(wù)的隔離甘凭,并基于undo來實(shí)現(xiàn)稀拐,在做事務(wù)回滾時(shí),也會(huì)用到undo段丹弱。mysql 用redolog來保證數(shù)據(jù)的寫入的性能和失效恢復(fù)德撬,在修改數(shù)據(jù)時(shí)只需要修改內(nèi)存,再把修改行為記錄到事務(wù)日志中(順序IO)躲胳,不用每次將數(shù)據(jù)修改本身持久化到硬盤(隨機(jī)IO)蜓洪,大大提高性能。
在可靠性方面坯苹,innodb存儲(chǔ)引擎提供了兩次寫機(jī)制double writer用于防止在flush頁面到存儲(chǔ)上出現(xiàn)的錯(cuò)誤隆檀,解決磁盤half-writern的問題。
? 對(duì)于高并發(fā)高性能的mysql來講粹湃,可以在多個(gè)維度進(jìn)行性能方面的調(diào)優(yōu)恐仑。
a、硬件級(jí)別为鳄,
日志和數(shù)據(jù)的存儲(chǔ)裳仆,需要分開,日志是順序的寫孤钦,需要做raid1+0歧斟,并且用buffer-IO纯丸;數(shù)據(jù)是離散的讀寫,走direct IO即可静袖,避免走文件系統(tǒng)cache帶來的開銷觉鼻。
存儲(chǔ)能力,SAS盤raid操作(raid卡緩存勾徽,關(guān)閉讀cache滑凉,關(guān)閉磁盤cache,關(guān)閉預(yù)讀喘帚,只用writeback buffer畅姊,不過需要考慮充放電的問題),當(dāng)然如果數(shù)據(jù)規(guī)模不大吹由,數(shù)據(jù)的存儲(chǔ)可以用高速的設(shè)備若未,F(xiàn)usion IO、SSD倾鲫。
對(duì)于數(shù)據(jù)的寫入粗合,控制臟頁刷新的頻率,對(duì)于數(shù)據(jù)的讀取乌昔,控制cache hit率隙疚;因此而估算系統(tǒng)需要的IOPS,評(píng)估需要的硬盤數(shù)量(fusion io上到IOPS 在10w以上磕道,普通的硬盤150)供屉。
Cpu方面,單實(shí)例關(guān)閉NUMA溺蕉,mysql對(duì)多核的支持不是太好伶丐,可以對(duì)多實(shí)例進(jìn)行CPU綁定。
b疯特、操作系統(tǒng)級(jí)別哗魂,
內(nèi)核以及socket的優(yōu)化,網(wǎng)絡(luò)優(yōu)化bond漓雅、文件系統(tǒng)录别、IO調(diào)度
innodb主要用在OLTP類應(yīng)用,一般都是IO密集型的應(yīng)用邻吞,在提高IO能力的基礎(chǔ)上组题,充分利用cache機(jī)制。需要考慮的內(nèi)容有吃衅,
在保證系統(tǒng)可用內(nèi)存的基礎(chǔ)上往踢,盡可能的擴(kuò)大innodb buffer pool,一般設(shè)置為物理內(nèi)存的3/4
文件系統(tǒng)的使用徘层,只在記錄事務(wù)日志的時(shí)候用文件系統(tǒng)的cache峻呕;盡量避免mysql用到swap(可以將vm.swappiness=0利职,內(nèi)存緊張時(shí),釋放文件系統(tǒng)cache)
IO調(diào)度優(yōu)化瘦癌,減少不必要的阻塞猪贪,降低隨機(jī)IO訪問的延時(shí)(CFQ、Deadline讯私、NOOP)
c热押、server以及存儲(chǔ)引擎級(jí)別(連接管理、網(wǎng)絡(luò)管理斤寇、table管理桶癣、日志)
包括cache/buffer、Connection、IO
d、應(yīng)用級(jí)別(比如索引的考慮拦止,schema的優(yōu)化適當(dāng)冗余;優(yōu)化sql查詢導(dǎo)致的CPU問題和內(nèi)存問題欣除,減少鎖的范圍,減少回表掃描,覆蓋索引)
? 在高可用實(shí)踐方面,
支持master-master惹挟、master-slave模式,master-master模式是一個(gè)作為主負(fù)責(zé)讀寫缝驳,另外一個(gè)作為standby提供災(zāi)備连锯,maser-slave是一個(gè)作為主提供寫操作,其他幾個(gè)節(jié)點(diǎn)作為讀操作党巾,支持讀寫分離萎庭。
對(duì)于節(jié)點(diǎn)主備失效檢測(cè)和切換霜医,可以采用HA軟件齿拂,當(dāng)然也可以從更細(xì)粒度定制的角度,采用zookeeper作為集群的協(xié)調(diào)服務(wù)肴敛。
對(duì)于分布式的系統(tǒng)來講署海,數(shù)據(jù)庫主備切換的一致性始終是一個(gè)問題,可以有以下幾種方式:
a医男、集群方式砸狞,如oracle的rack,缺點(diǎn)是比較復(fù)雜
b镀梭、共享SAN存儲(chǔ)方式刀森,相關(guān)的數(shù)據(jù)文件和日志文件都放在共享存儲(chǔ)上,優(yōu)點(diǎn)是主備切換時(shí)數(shù)據(jù)保持一致报账,不會(huì)丟失研底,但由于備機(jī)有一段時(shí)間的拉起埠偿,會(huì)有短暫的不可用狀態(tài)
c、主備進(jìn)行數(shù)據(jù)同步的方式榜晦,常見的是日志的同步冠蒋,可以保障熱備,實(shí)時(shí)性好乾胶,但是切換時(shí)抖剿,可能有部分?jǐn)?shù)據(jù)沒有同步過來,帶來了數(shù)據(jù)的一致性問題识窿≌独桑可以在操作主數(shù)據(jù)庫的同時(shí),記錄操作日志喻频,切換到備時(shí)孽拷,會(huì)和操作日志做個(gè)check,補(bǔ)齊未同步過來的數(shù)據(jù)半抱;
d脓恕、還有一種做法是備庫切換到主庫的regolog的存儲(chǔ)上,保證數(shù)據(jù)不丟失窿侈。
數(shù)據(jù)庫主從復(fù)制的效率在mysql上不是太高炼幔,主要原因是事務(wù)是嚴(yán)格保持順序的,索引mysql在復(fù)制方面包括日志IO和relog log兩個(gè)過程都是單線程的串行操作史简,在數(shù)據(jù)復(fù)制優(yōu)化方面乃秀,盡量減少IO的影響。不過到了Mysql5.6版本圆兵,可以支持在不同的庫上的并行復(fù)制跺讯。
? 基于不同業(yè)務(wù)要求的存取方式
平臺(tái)業(yè)務(wù)中,不同的業(yè)務(wù)有不同的存取要求殉农,比如典型的兩大業(yè)務(wù)用戶和訂單刀脏,用戶一般來講總量是可控的,而訂單是不斷地遞增的超凳,對(duì)于用戶表首先采取分庫切分愈污,每個(gè)sharding做一主多讀,同樣對(duì)于訂單因更多需求的是用戶查詢自己的訂單轮傍,也需要按照用戶進(jìn)行切分訂單庫暂雹,并且支持一主多讀。
在硬件存儲(chǔ)方面创夜,對(duì)于事務(wù)日志因是順序?qū)懞脊颍W存的優(yōu)勢(shì)比硬盤高不了多少,所以采取電池保護(hù)的寫緩存的raid卡存儲(chǔ);對(duì)于數(shù)據(jù)文件涧尿,無論是對(duì)用戶或者訂單都會(huì)存在大量的隨機(jī)讀寫操作桨醋,當(dāng)然加大內(nèi)存是一個(gè)方面,另外可以采用高速的IO設(shè)備閃存现斋,比如PCIe卡 fusion-io喜最。使用閃存也適合在單線程的負(fù)載中,比如主從復(fù)制庄蹋,可以對(duì)從節(jié)點(diǎn)配置fusion-IO卡瞬内,降低復(fù)制的延遲。
對(duì)于訂單業(yè)務(wù)來講限书,量是不斷遞增的虫蝶,PCIe卡存儲(chǔ)容量比較有限,并且訂單業(yè)務(wù)的熱數(shù)據(jù)只有最近一段時(shí)間的(比如近3個(gè)月的)倦西,對(duì)此這里列兩種解決方案能真,一種是flashcache方式,采用基于閃存和硬盤存儲(chǔ)的開源混合存儲(chǔ)方式扰柠,在閃存中存儲(chǔ)熱點(diǎn)的數(shù)據(jù)粉铐。另外一種是可以定期把老的數(shù)據(jù)導(dǎo)出到分布式數(shù)據(jù)庫HBase中,用戶在查詢訂單列表是近期的數(shù)據(jù)從mysql中獲取卤档,老的數(shù)據(jù)可以從HBase中查詢蝙泼,當(dāng)然需要HBase良好的rowkey設(shè)計(jì)以適應(yīng)查詢需求。
3) 分布式數(shù)據(jù)庫
對(duì)于數(shù)據(jù)的高并發(fā)的訪問劝枣,傳統(tǒng)的關(guān)系型數(shù)據(jù)庫提供讀寫分離的方案汤踏,但是帶來的確實(shí)數(shù)據(jù)的一致性問題提供的數(shù)據(jù)切分的方案;對(duì)于越來越多的海量數(shù)據(jù)舔腾,傳統(tǒng)的數(shù)據(jù)庫采用的是分庫分表溪胶,實(shí)現(xiàn)起來比較復(fù)雜,后期要不斷的進(jìn)行遷移維護(hù)稳诚;對(duì)于高可用和伸縮方面哗脖,傳統(tǒng)數(shù)據(jù)采用的是主備、主從采桃、多主的方案懒熙,但是本身擴(kuò)展性比較差丘损,增加節(jié)點(diǎn)和宕機(jī)需要進(jìn)行數(shù)據(jù)的遷移普办。對(duì)于以上提出的這些問題,分布式數(shù)據(jù)庫HBase有一套完善的解決方案徘钥,適用于高并發(fā)海量數(shù)據(jù)存取的要求衔蹲。
? HBase
基于列式的高效存儲(chǔ)降低IO通常的查詢不需要一行的全部字段,大多數(shù)只需要幾個(gè)字段對(duì)與面向行的存儲(chǔ)系統(tǒng),每次查詢都會(huì)全部數(shù)據(jù)取出舆驶,然后再?gòu)闹羞x出需要的字段面向列的存儲(chǔ)系統(tǒng)可以單獨(dú)查詢某一列橱健,從而大大降低IO提高壓縮效率同列數(shù)據(jù)具有很高的相似性,會(huì)增加壓縮效率Hbase的很多特性沙廉,都是由列存儲(chǔ)決定的
強(qiáng)一致的數(shù)據(jù)訪問
MVCC
HBase的一致性數(shù)據(jù)訪問是通過MVCC來實(shí)現(xiàn)的拘荡。
HBase在寫數(shù)據(jù)的過程中,需要經(jīng)過好幾個(gè)階段撬陵,寫HLog珊皿,寫memstore,更新MVCC;
只有更新了MVCC巨税,才算真正memstore寫成功蟋定,其中事務(wù)的隔離需要有mvcc的來控制,比如讀數(shù)據(jù)不可以獲取別的線程還未提交的數(shù)據(jù)草添。
高可靠
HBase的數(shù)據(jù)存儲(chǔ)基于HDFS驶兜,提供了冗余機(jī)制。
Region節(jié)點(diǎn)的宕機(jī)远寸,對(duì)于內(nèi)存中的數(shù)據(jù)還未flush到文件中抄淑,提供了可靠的恢復(fù)機(jī)制。
可伸縮驰后,自動(dòng)切分蝇狼,遷移
通過Zookeeper定位目標(biāo)Region Server,最后定位Region倡怎。
Region Server擴(kuò)容迅耘,通過將自身發(fā)布到Master,Master均勻分布监署。
可用性
存在單點(diǎn)故障颤专,Region Server宕機(jī)后,短時(shí)間內(nèi)該server維護(hù)的region無法訪問钠乏,等待failover生效栖秕。
通過Master維護(hù)各Region Server健康狀況和Region分布。
多個(gè)Master晓避,Master宕機(jī)有zookeeper的paxos投票機(jī)制選取下一任Master簇捍。Master就算全宕機(jī),也不影響Region讀寫俏拱。Master僅充當(dāng)一個(gè)自動(dòng)運(yùn)維角色暑塑。
HDFS為分布式存儲(chǔ)引擎,一備三锅必,高可靠事格,0數(shù)據(jù)丟失。
HDFS的namenode是一個(gè)SPOF。
為避免單個(gè)region訪問過于頻繁驹愚,單機(jī)壓力過大远搪,提供了split機(jī)制
HBase的寫入是LSM-TREE的架構(gòu)方式,隨著數(shù)據(jù)的append逢捺,HFile越來越多谁鳍,HBase提供了HFile文件進(jìn)行compact,對(duì)過期數(shù)據(jù)進(jìn)行清除劫瞳,提高查詢的性能棠耕。
Schema free
HBase沒有像關(guān)系型數(shù)據(jù)庫那樣的嚴(yán)格的schema,可以自由的增加和刪除schema中的字段柠新。
HBase分布式數(shù)據(jù)庫窍荧,對(duì)于二級(jí)索引支持的不太好,目前只支持在rowkey上的索引恨憎,所以rowkey的設(shè)計(jì)對(duì)于查詢的性能來講非常關(guān)鍵蕊退。
7. 管理與部署配置
統(tǒng)一的配置庫
部署平臺(tái)
8. 監(jiān)控、統(tǒng)計(jì)
大型分布式系統(tǒng)涉及各種設(shè)備憔恳,比如網(wǎng)絡(luò)交換機(jī)瓤荔,普通PC機(jī),各種型號(hào)的網(wǎng)卡钥组,硬盤输硝,內(nèi)存等等,還有應(yīng)用業(yè)務(wù)層次的監(jiān)控程梦,數(shù)量非常多的時(shí)候点把,出現(xiàn)錯(cuò)誤的概率也會(huì)變大,并且有些監(jiān)控的時(shí)效性要求比較高屿附,有些達(dá)到秒級(jí)別郎逃;在大量的數(shù)據(jù)流中需要過濾異常的數(shù)據(jù),有時(shí)候也對(duì)數(shù)據(jù)會(huì)進(jìn)行上下文相關(guān)的復(fù)雜計(jì)算挺份,進(jìn)而決定是否需要告警褒翰。因此監(jiān)控平臺(tái)的性能、吞吐量匀泊、已經(jīng)可用性就比較重要优训,需要規(guī)劃統(tǒng)一的一體化的監(jiān)控平臺(tái)對(duì)系統(tǒng)進(jìn)行各個(gè)層次的監(jiān)控。
平臺(tái)的數(shù)據(jù)分類
應(yīng)用業(yè)務(wù)級(jí)別:應(yīng)用事件各聘、業(yè)務(wù)日志揣非、審計(jì)日志、請(qǐng)求日志伦吠、異常妆兑、請(qǐng)求業(yè)務(wù)metrics魂拦、性能度量
系統(tǒng)級(jí)別:CPU毛仪、內(nèi)存搁嗓、網(wǎng)絡(luò)、IO
時(shí)效性要求
閥值箱靴,告警:
實(shí)時(shí)計(jì)算:
近實(shí)時(shí)分鐘計(jì)算
按小時(shí)腺逛、天的離線分析
實(shí)時(shí)查詢
架構(gòu)
節(jié)點(diǎn)中Agent代理可以接收日志、應(yīng)用的事件以及通過探針的方式采集數(shù)據(jù)衡怀,agent采集數(shù)據(jù)的一個(gè)原則是和業(yè)務(wù)應(yīng)用的流程是異步隔離的棍矛,不影響交易流程。
數(shù)據(jù)統(tǒng)一通過collector集群進(jìn)行收集抛杨,按照數(shù)據(jù)的不同類型分發(fā)到不同的計(jì)算集群進(jìn)行處理够委;有些數(shù)據(jù)時(shí)效性不是那么高,比如按小時(shí)進(jìn)行統(tǒng)計(jì)怖现,放入hadoop集群茁帽;有些數(shù)據(jù)是請(qǐng)求流轉(zhuǎn)的跟蹤數(shù)據(jù),需要可以查詢的屈嗤,那么就可以放入solr集群進(jìn)行索引潘拨;有些數(shù)據(jù)需要進(jìn)行實(shí)時(shí)計(jì)算的進(jìn)而告警的,需要放到storm集群中進(jìn)行處理饶号。
數(shù)據(jù)經(jīng)過計(jì)算集群處理后铁追,結(jié)果存儲(chǔ)到Mysql或者HBase中。
監(jiān)控的web應(yīng)用可以把監(jiān)控的實(shí)時(shí)結(jié)果推送到瀏覽器中茫船,也可以提供API供結(jié)果的展現(xiàn)和搜索琅束。