一、 設(shè)計(jì)理念
客戶端頁(yè)面緩存(http header中包含Expires/Cache of Control,last modified(304,server不返回body灾常,客戶端可以繼續(xù)用cache,減少流量)铃拇,ETag)
反向代理緩存
應(yīng)用端的緩存(memcache)
內(nèi)存數(shù)據(jù)庫(kù)
Buffer钞瀑、cache機(jī)制(數(shù)據(jù)庫(kù),中間件等)
哈希慷荔、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)景。
在大規(guī)模的數(shù)據(jù)中忠怖,數(shù)據(jù)存在一定的局部性的特征,利用局部性的原理將海量數(shù)據(jù)計(jì)算的問題分而治之抄瑟。
MR模型是無(wú)共享的架構(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ù)分解。
隨著平臺(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)行選擇不同的備份策略派哲。
讀寫分離是對(duì)數(shù)據(jù)庫(kù)來講的臼氨,隨著系統(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)注于可用性。
平臺(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ā)因素需要考慮冪等性凡资。
監(jiān)控也是提高整個(gè)平臺(tái)可用性的一個(gè)重要手段,多平臺(tái)進(jìn)行多個(gè)維度的監(jiān)控谬运;模塊在運(yùn)行時(shí)候是透明的隙赁,以達(dá)到運(yùn)行期白盒化。
拆分包括對(duì)業(yè)務(wù)的拆分和對(duì)數(shù)據(jù)庫(kù)的拆分梆暖。
系統(tǒng)的資源總是有限的伞访,一段比較長(zhǎng)的業(yè)務(wù)執(zhí)行如果是一竿子執(zhí)行的方式,在大量并發(fā)的操作下轰驳,這種阻塞的方式厚掷,無(wú)法有效的及時(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)行分庫(kù)和分表冬竟。這種分庫(kù)分表的方式欧穴,需要增加對(duì)數(shù)據(jù)的路由邏輯支持。
對(duì)于系統(tǒng)的伸縮性而言诱咏,模塊最好是無(wú)狀態(tài)的苔可,通過增加節(jié)點(diǎn)就可以提高整個(gè)的吞吐量。
系統(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)行告警或者丟棄。
對(duì)于共享資源的訪問砌梆,為了防止沖突默责,需要進(jìn)行并發(fā)的控制,同時(shí)有些交易需要有事務(wù)性來保證交易的一致性咸包,所以在交易系統(tǒng)的設(shè)計(jì)時(shí)桃序,需考慮原子操作和并發(fā)控制。
保證并發(fā)控制一些常用高性能手段有烂瘫,樂觀鎖媒熊、Latch、mutex坟比、寫時(shí)復(fù)制芦鳍、CAS等;多版本的并發(fā)控制MVCC通常是保證一致性的重要手段葛账,這個(gè)在數(shù)據(jù)庫(kù)的設(shè)計(jì)中經(jīng)常會(huì)用到柠衅。
平臺(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ù)。
系統(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)求重試的考慮。
系統(tǒng)的資源是有限的琼牧,在使用資源時(shí)恢筝,一定要在最后釋放資源,無(wú)論是請(qǐng)求走的是正常路徑還是異常的路徑巨坊,以便于資源的及時(shí)回收撬槽,供其他請(qǐng)求使用。
在設(shè)計(jì)通信的架構(gòu)時(shí)抱究,往往需要考慮超時(shí)的控制恢氯。
整個(gè)架構(gòu)是分層的分布式的架構(gòu)鼓寺,縱向包括CDN勋拟,負(fù)載均衡/反向代理,web應(yīng)用妈候,業(yè)務(wù)層敢靡,基礎(chǔ)服務(wù)層,數(shù)據(jù)存儲(chǔ)層苦银。水平方向包括對(duì)整個(gè)平臺(tái)的配置管理部署和監(jiān)控啸胧。
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à)比蛤虐。
一個(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)頁(yè)返回的狀態(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做圖片緩存瘪弓。
應(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接入層無(wú)狀態(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過期的管理
代表某一領(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)。
通信組件用于業(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)求。
在大多數(shù)的數(shù)據(jù)庫(kù)切分解決方案中盗扒,為了提高數(shù)據(jù)庫(kù)的吞吐量跪楞,首先是對(duì)不同的表進(jìn)行垂直切分到不同的數(shù)據(jù)庫(kù)中,
然后當(dāng)數(shù)據(jù)庫(kù)中一個(gè)表超過一定大小時(shí)侣灶,需要對(duì)該表進(jìn)行水平切分甸祭,這里也是一樣,這里以用戶表為例褥影;
對(duì)于訪問數(shù)據(jù)庫(kù)客戶端來講池户,需要根據(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ù)庫(kù)的sharding是一一對(duì)應(yīng)的,只訪問一個(gè)數(shù)據(jù)庫(kù)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)列表拐云。
傳統(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ī)制來支持壳鹤。
對(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語(yǔ)言開發(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)批量拉取消息鹤树,這樣無(wú)須應(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可以基于語(yǔ)義指定分片蜂奸,消息發(fā)送到broker的某分片上。
總體來講硬萍,RabbitMQ用在實(shí)時(shí)的對(duì)可靠性要求比較高的消息傳遞上扩所。kafka主要用于處理活躍的流式數(shù)據(jù),大數(shù)據(jù)量的數(shù)據(jù)處理上。
Cache系統(tǒng)
在一些高并發(fā)高性能的場(chǎng)景中朴乖,使用cache可以減少對(duì)后端系統(tǒng)的負(fù)載祖屏,承擔(dān)可大部分讀的壓力,可以大大提高系統(tǒng)的吞吐量买羞,比如通常在數(shù)據(jù)庫(kù)存儲(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ù)庫(kù)的同時(shí)众雷,更新數(shù)據(jù)庫(kù)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ù)庫(kù)做cache悯嗓,比如redis件舵、mongodb;redis比memcache有豐富的數(shù)據(jù)操作的API脯厨;redis和mongodb都對(duì)數(shù)據(jù)進(jìn)行了持久化铅祸,而memcache沒有這個(gè)功能,因此memcache更加適合在關(guān)系型數(shù)據(jù)庫(kù)之上的數(shù)據(jù)的緩存合武。
Buffer系統(tǒng)
用在高速的寫操作的場(chǎng)景中临梗,平臺(tái)中有些數(shù)據(jù)需要寫入數(shù)據(jù)庫(kù),并且數(shù)據(jù)是分庫(kù)分表的稼跳,但對(duì)數(shù)據(jù)的可靠性不是那么高盟庞,為了減少對(duì)數(shù)據(jù)庫(kù)的寫壓力,可以采取批量寫操作的方式岂贩。
開辟一個(gè)內(nèi)存區(qū)域茫经,當(dāng)數(shù)據(jù)到達(dá)區(qū)域的一定閥值時(shí)如80%時(shí)巷波,在內(nèi)存中做分庫(kù)梳理工作(內(nèi)存速度還是比較快的)萎津,后分庫(kù)批量flush。
在電子商務(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更為豐富的查詢語(yǔ)言竹揍,可配置可擴(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無(wú)需進(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ù)樟结。
在整個(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)的文件。
在交易系統(tǒng)中友多,通常需要進(jìn)行異構(gòu)數(shù)據(jù)源的同步牲平,通常有數(shù)據(jù)文件到關(guān)系型數(shù)據(jù)庫(kù),數(shù)據(jù)文件到分布式數(shù)據(jù)庫(kù)域滥,關(guān)系型數(shù)據(jù)庫(kù)到分布式數(shù)據(jù)庫(kù)等纵柿。數(shù)據(jù)在異構(gòu)源之間的同步一般是基于性能和業(yè)務(wù)的需求蜈抓,數(shù)據(jù)存儲(chǔ)在本地文件中一般是基于性能的考慮,文件是順序存儲(chǔ)的昂儒,效率還是比較高的沟使;數(shù)據(jù)同步到關(guān)系型數(shù)據(jù)一般是基于查詢的需求;而分布式數(shù)據(jù)庫(kù)是存儲(chǔ)越來越多的海量數(shù)據(jù)的渊跋,而關(guān)系型數(shù)據(jù)庫(kù)無(wú)法滿足大數(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ù)庫(kù)導(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ù)庫(kù)的操作譬重,這樣channel可以刪除這部分已經(jīng)confirm的消息拒逮。
基于可靠性的要求,channel可以采用文件持久化的方式臀规。
參見下圖
離線全量遵循空間間換取時(shí)間滩援,分而治之的原則,盡量的縮短數(shù)據(jù)同步的時(shí)間塔嬉,提高同步的效率玩徊。
需要對(duì)源數(shù)據(jù)比如MySQL進(jìn)行切分,多線程并發(fā)讀源數(shù)據(jù)谨究,多線程并發(fā)批量寫入分布式數(shù)據(jù)庫(kù)比如HBase,利用channel作為讀寫之間的緩沖恩袱,實(shí)現(xiàn)更好的解耦,channel可以基于文件存儲(chǔ)或者內(nèi)存胶哲。參見下圖:
對(duì)于源數(shù)據(jù)的切分畔塔,如果是文件可以根據(jù)文件名稱設(shè)置塊大小來切分。
對(duì)于關(guān)系型數(shù)據(jù)庫(kù),由于一般的需求是只離線同步一段時(shí)間的數(shù)據(jù)(比如凌晨把當(dāng)天的訂單數(shù)據(jù)同步到HBase)澈吨,所以需要在數(shù)據(jù)切分時(shí)(按照行數(shù)切分)把敢,會(huì)多線程掃描整個(gè)表(及時(shí)建索引,也要回表)棚辽,對(duì)于表中包含大量的數(shù)據(jù)來講,IO很高冰肴,效率非常低屈藐;這里解決的方法是對(duì)數(shù)據(jù)庫(kù)按照時(shí)間字段(按照時(shí)間同步的)建立分區(qū),每次按照分區(qū)進(jìn)行導(dǎo)出熙尉。
從傳統(tǒng)的基于關(guān)系型數(shù)據(jù)庫(kù)并行處理集群联逻、用于內(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ù)庫(kù)确憨。
內(nèi)存計(jì)算方面有SAP的HANA,開源的nosql內(nèi)存型的數(shù)據(jù)庫(kù)mongodb也支持mapreduce進(jìn)行數(shù)據(jù)的分析瓤的。
海量數(shù)據(jù)的離線分析目前互聯(lián)網(wǎng)公司大量的使用Hadoop休弃,Hadoop在可伸縮性、健壯性圈膏、計(jì)算性能和成本上具有無(wú)可替代的優(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)過語(yǔ)法分析祈匙、生成執(zhí)行計(jì)劃后最終生成MapReduce任務(wù)進(jìn)行執(zhí)行,這樣大大提高了開發(fā)的效率,做到以ad-hoc(計(jì)算在query發(fā)生時(shí))方式進(jìn)行的分析夺欲。
基于MapReduce模型的分布式數(shù)據(jù)的分析都是離線的分析跪帝,執(zhí)行上都是暴力掃描,無(wú)法利用類似索引的機(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)
在互聯(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í)。
實(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庫(kù)怎燥,包括客戶端的JS和服務(wù)端的的nodejs瘫筐,用于快速構(gòu)建實(shí)時(shí)的web應(yīng)用蜜暑。
更多Java學(xué)習(xí)資料歡迎加群,策肝,肛捍, 6 4 7 6 3 1 0 3 0
待補(bǔ)充