一、 設(shè)計(jì)理念
1. 空間換時(shí)間
1) 多級緩存藻烤,靜態(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)的場景,避免多次的IO雾消,提高查詢的效率灾搏。
倒排索引實(shí)現(xiàn)單詞到文檔映射關(guān)系的最佳實(shí)現(xiàn)方式和最有效的索引結(jié)構(gòu)挫望,廣泛用在搜索領(lǐng)域。
Bitmap是一種非常簡潔快速的數(shù)據(jù)結(jié)構(gòu)狂窑,他能同時(shí)使存儲空間和速度最優(yōu)化(而不必空間換時(shí)間)媳板,適合于海量數(shù)據(jù)的的計(jì)算場景。
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)就近讀取本地存儲的數(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)担锤、備份
隨著平臺并發(fā)量的增大,需要擴(kuò)容節(jié)點(diǎn)進(jìn)行集群乍钻,利用負(fù)載均衡設(shè)備進(jìn)行請求的分發(fā)肛循;負(fù)載均衡設(shè)備通常在提供負(fù)載均衡的同時(shí),也提供失效檢測功能银择;同時(shí)為了提高可用性多糠,需要有容災(zāi)備份,以防止節(jié)點(diǎn)宕機(jī)失效帶來的不可用問題浩考;備份有在線的和離線備份夹孔,可以根據(jù)失效性要求的不同,進(jìn)行選擇不同的備份策略。
2) 讀寫分離
讀寫分離是對數(shù)據(jù)庫來講的搭伤,隨著系統(tǒng)并發(fā)量的增大只怎,提高數(shù)據(jù)訪問可用性的一個(gè)重要手段就是寫數(shù)據(jù)和讀數(shù)據(jù)進(jìn)行分離;當(dāng)然在讀寫分離的同時(shí)怜俐,需要關(guān)注數(shù)據(jù)的一致性問題身堡;對于一致性的問題,在分布式的系統(tǒng)CAP定量中佑菩,更多的關(guān)注于可用性盾沫。
3) 依賴關(guān)系
平臺中各個(gè)模塊之間的關(guān)系盡量是低耦合的裁赠,可以通過相關(guān)的消息組件進(jìn)行交互殿漠,能異步則異步,分清楚數(shù)據(jù)流轉(zhuǎn)的主流程和副流程佩捞,主副是異步的绞幌,比如記錄日志可以是異步操作的,增加整個(gè)系統(tǒng)的可用性一忱。
當(dāng)然在異步處理中莲蜘,為了確保數(shù)據(jù)得到接收或者處理,往往需要確認(rèn)機(jī)制(confirm帘营、ack)票渠。
但是有些場景中,雖然請求已經(jīng)得到處理芬迄,但是因其他原因(比如網(wǎng)絡(luò)不穩(wěn)定)问顷,確認(rèn)消息沒有返回,那么這種情況下需要進(jìn)行請求的重發(fā)禀梳,對請求的處理設(shè)計(jì)因重發(fā)因素需要考慮冪等性杜窄。
4) 監(jiān)控
監(jiān)控也是提高整個(gè)平臺可用性的一個(gè)重要手段,多平臺進(jìn)行多個(gè)維度的監(jiān)控算途;模塊在運(yùn)行時(shí)候是透明的塞耕,以達(dá)到運(yùn)行期白盒化。
4. 伸縮
1) 拆分
拆分包括對業(yè)務(wù)的拆分和對數(shù)據(jù)庫的拆分嘴瓤。
系統(tǒng)的資源總是有限的扫外,一段比較長的業(yè)務(wù)執(zhí)行如果是一竿子執(zhí)行的方式,在大量并發(fā)的操作下廓脆,這種阻塞的方式筛谚,無法有效的及時(shí)釋放資源給其他進(jìn)程執(zhí)行,這樣系統(tǒng)的吞吐量不高狞贱。
需要把業(yè)務(wù)進(jìn)行邏輯的分段刻获,采用異步非阻塞的方式,提高系統(tǒng)的吞吐量。
隨著數(shù)據(jù)量和并發(fā)量的增加蝎毡,讀寫分離不能滿足系統(tǒng)并發(fā)性能的要求厚柳,需要對數(shù)據(jù)進(jìn)行切分,包括對數(shù)據(jù)進(jìn)行分庫和分表沐兵。這種分庫分表的方式别垮,需要增加對數(shù)據(jù)的路由邏輯支持。
2) 無狀態(tài)
對于系統(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í)增加流控的措施岩遗,可考慮對請求進(jìn)行排隊(duì)凤瘦,超出預(yù)期的范圍,可以進(jìn)行告警或者丟棄梆靖。
2) 原子操作與并發(fā)控制
對于共享資源的訪問,為了防止沖突涤姊,需要進(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) 基于邏輯的不同阀坏,采取不一樣的策略
平臺中業(yè)務(wù)邏輯存在不同的類型,有計(jì)算復(fù)雜型的士修,有消耗IO型的,同時(shí)就同一種類型而言沸移,不同的業(yè)務(wù)邏輯消耗的資源數(shù)量也是不一樣的雹锣,這就需要針對不同的邏輯采取不同的策略绅这。
針對IO型的,可以采取基于事件驅(qū)動(dòng)的異步非阻塞的方式浑度,單線程方式可以減少線程的切換引起的開銷,或者在多線程的情況下采取自旋spin的方式先慷,減少對線程的切換(比如oracle latch設(shè)計(jì));對于計(jì)算型的脓诡,充分利用多線程進(jìn)行操作。
同一類型的調(diào)用方式交惯,不同的業(yè)務(wù)進(jìn)行合適的資源分配,設(shè)置不同的計(jì)算節(jié)點(diǎn)數(shù)量或者線程數(shù)量,對業(yè)務(wù)進(jìn)行分流炬藤,優(yōu)先執(zhí)行優(yōu)先級別高的業(yè)務(wù)上真。
4) 容錯(cuò)隔離
系統(tǒng)的有些業(yè)務(wù)模塊在出現(xiàn)錯(cuò)誤時(shí)睡互,為了減少并發(fā)下對正常請求的處理的影響,有時(shí)候需要考慮對這些異常狀態(tài)的請求進(jìn)行單獨(dú)渠道的處理,甚至?xí)簳r(shí)自動(dòng)禁止這些異常的業(yè)務(wù)模塊逼侦。
有些請求的失敗可能是偶然的暫時(shí)的失敗(比如網(wǎng)絡(luò)不穩(wěn)定),需要進(jìn)行請求重試的考慮涕滋。
5) 資源釋放
系統(tǒng)的資源是有限的溯饵,在使用資源時(shí)隘谣,一定要在最后釋放資源,無論是請求走的是正常路徑還是異常的路徑码泛,以便于資源的及時(shí)回收晌缘,供其他請求使用。
在設(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ù)存儲層。水平方向包括對整個(gè)平臺的配置管理部署和監(jiān)控。
三败玉、 剖析架構(gòu)
1. CDN
CDN系統(tǒng)能夠?qū)崟r(shí)地根據(jù)網(wǎng)絡(luò)流量和各節(jié)點(diǎn)的連接返干、負(fù)載狀況以及到用戶的距離和響應(yīng)時(shí)間等綜合信息將用戶的請求重新導(dǎo)向離用戶最近的服務(wù)節(jié)點(diǎn)上。其目的是使用戶可就近取得所需內(nèi)容,解決 Internet網(wǎng)絡(luò)擁擠的狀況乳蓄,提高用戶訪問網(wǎng)站的響應(yīng)速度。
對于大規(guī)模電子商務(wù)平臺一般需要建CDN做網(wǎng)絡(luò)加速,大型平臺如淘寶耻煤、京東都采用自建CDN,中小型的企業(yè)可以采用第三方CDN廠商合作,如藍(lán)汛、網(wǎng)宿、快網(wǎng)等幌陕。
當(dāng)然在選擇CDN廠商時(shí)棚唆,需要考慮經(jīng)營時(shí)間長短,是否有可擴(kuò)充的帶寬資源、靈活的流量和帶寬選擇瓜喇、穩(wěn)定的節(jié)點(diǎn)匪补、性價(jià)比始锚。
2. 負(fù)載均衡、反向代理
一個(gè)大型的平臺包括很多個(gè)業(yè)務(wù)域姐呐,不同的業(yè)務(wù)域有不同的集群,可以用DNS做域名解析的分發(fā)或輪詢,DNS方式實(shí)現(xià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)。對網(wǎng)絡(luò)環(huán)境的依賴性比較高奈籽。
Nginx工作在7層饥侵,事件驅(qū)動(dòng)的、異步非阻塞的架構(gòu)衣屏、支持多進(jìn)程的高并發(fā)的負(fù)載均衡器/反向代理軟件躏升±浅溃可以針對域名膨疏、目錄結(jié)構(gòu)、正則規(guī)則針對http做一些分流钻弄。通過端口檢測到服務(wù)器內(nèi)部的故障佃却,比如根據(jù)服務(wù)器處理網(wǎng)頁返回的狀態(tài)碼、超時(shí)等等斧蜕,并且會(huì)把返回錯(cuò)誤的請求重新提交到另一個(gè)節(jié)點(diǎn)双霍,不過其中缺點(diǎn)就是不支持url來檢測。對于session sticky批销,可以基于ip hash的算法來實(shí)現(xiàn)洒闸,通過基于cookie的擴(kuò)展nginx-sticky-module支持session sticky。
HAProxy支持4層和7層做負(fù)載均衡均芽,支持session的會(huì)話保持丘逸,cookie的引導(dǎo);支持后端url方式的檢測掀宋;負(fù)載均衡的算法比較豐富深纲,有RR、權(quán)重等劲妙。
對于圖片湃鹊,需要有單獨(dú)的域名,獨(dú)立或者分布式的圖片服務(wù)器或者如mogileFS镣奋,可以圖片服務(wù)器之上加varnish做圖片緩存币呵。
3. App接入
應(yīng)用層運(yùn)行在jboss或者tomcat容器中,代表獨(dú)立的系統(tǒng)侨颈,比如前端購物余赢、用戶自主服務(wù)、后端系統(tǒng)等
協(xié)議接口哈垢,HTTP妻柒、JSON
可以采用servlet3.0,異步化servlet,提高整個(gè)系統(tǒng)的吞吐量
http請求經(jīng)過Nginx,通過負(fù)載均衡算法分到到App的某一節(jié)點(diǎn)耘分,這一層層擴(kuò)容起來比較簡單举塔。
除了利用cookie保存少量用戶部分信息外(cookie一般不能超過4K的大小)绑警,對于App接入層,保存有用戶相關(guān)的session數(shù)據(jù)啤贩,但是有些反向代理或者負(fù)載均衡不支持對session sticky支持不是很好或者對接入的可用性要求比較高(app接入節(jié)點(diǎn)宕機(jī)待秃,session隨之丟失),這就需要考慮session的集中式存儲痹屹,使得App接入層無狀態(tài)化,同時(shí)系統(tǒng)用戶變多的時(shí)候枉氮,就可以通過增加更多的應(yīng)用節(jié)點(diǎn)來達(dá)到水平擴(kuò)展的目的志衍。
Session的集中式存儲,需要滿足以下幾點(diǎn)要求:
a聊替、高效的通訊協(xié)議
b楼肪、session的分布式緩存,支持節(jié)點(diǎn)的伸縮惹悄,數(shù)據(jù)的冗余備份以及數(shù)據(jù)的遷移
c春叫、session過期的管理
4. 業(yè)務(wù)服務(wù)
代表某一領(lǐng)域的業(yè)務(wù)提供的服務(wù),對于電商而言泣港,領(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ī)模的大小悯恍,模塊可以部署在一起库糠,對于大規(guī)模的應(yīng)用,一般是獨(dú)立部署的坪稽。
高并發(fā):
業(yè)務(wù)層對外協(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ù):
對于分布式系統(tǒng)的一致性,盡量滿足可用性,一致性可以通過校對來達(dá)到最終一致的狀態(tài)贬墩。
5. 基礎(chǔ)服務(wù)中間件
1) 通信組件
通信組件用于業(yè)務(wù)系統(tǒng)內(nèi)部服務(wù)之間的調(diào)用榴嗅,在大并發(fā)的電商平臺中勋功,需要滿足高并發(fā)高吞吐量的要求熬粗。
整個(gè)通信組件包括客戶端和服務(wù)端兩部分。
客戶端和服務(wù)器端維護(hù)的是長連接蓉坎,可以減少每次請求建立連接的開銷肿孵,在客戶端對于每個(gè)服務(wù)器定義一個(gè)連接池唠粥,初始化連接后,可以并發(fā)連接服務(wù)端進(jìn)行rpc操作停做,連接池中的長連接需要心跳維護(hù)晤愧,設(shè)置請求超時(shí)時(shí)間。
對于長連接的維護(hù)過程可以分兩個(gè)階段蛉腌,一個(gè)是發(fā)送請求過程官份,另外一個(gè)是接收響應(yīng)過程。在發(fā)送請求過程中烙丛,若發(fā)生IOException舅巷,則把該連接標(biāo)記失效。接收響應(yīng)時(shí)蜀变,服務(wù)端返回SocketTimeoutException悄谐,如果設(shè)置了超時(shí)時(shí)間,那么就直接返回異常库北,清除當(dāng)前連接中那些超時(shí)的請求爬舰。否則繼續(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è)連接對于接收響應(yīng)來說都以單獨(dú)的線程運(yùn)行,客戶端可以通過同步(wait,notify)方式或者異步進(jìn)行rpc調(diào)用少辣,
序列化采用更高效的hession序列化方式凌摄。
服務(wù)端采用事件驅(qū)動(dòng)的NIO的MINA框架,支撐高并發(fā)高吞吐量的請求漓帅。
2) 路由Router
在大多數(shù)的數(shù)據(jù)庫切分解決方案中锨亏,為了提高數(shù)據(jù)庫的吞吐量痴怨,首先是對不同的表進(jìn)行垂直切分到不同的數(shù)據(jù)庫中,然后當(dāng)數(shù)據(jù)庫中一個(gè)表超過一定大小時(shí)器予,需要對該表進(jìn)行水平切分浪藻,這里也是一樣,這里以用戶表為例乾翔;對于訪問數(shù)據(jù)庫客戶端來講爱葵,需要根據(jù)用戶的ID,定位到需要訪問的數(shù)據(jù)反浓;數(shù)據(jù)切分算法钧惧,根據(jù)用戶的ID做hash操作巧婶,一致性Hash,這種方式存在失效數(shù)據(jù)的遷移問題丈莺,遷移時(shí)間內(nèi)服務(wù)不可用維護(hù)路由表遏佣,路由表中存儲用戶和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是一一對應(yīng)的后众,只訪問一個(gè)數(shù)據(jù)庫sharding.
biz業(yè)務(wù)注冊節(jié)點(diǎn)到zookeeper上/bizs/shard/下。
router監(jiān)聽zookeeper上/bizs/下節(jié)點(diǎn)狀態(tài)颅拦,緩存在線biz在router中蒂誉。
client請求router獲取biz時(shí),router首先從mongodb中獲取用戶對應(yīng)的shard,router根據(jù)緩存的內(nèi)容通過RR算法獲取biz節(jié)點(diǎn)距帅。
為了解決router的可用性和并發(fā)吞吐量問題右锨,對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ù)載均衡轧抗,通過檢測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ù)載均衡碳褒;對于master-master模式折砸、master-slave模式,可以通過zookeeper分布式鎖的機(jī)制來支持沙峻。
4) 消息Message
對于平臺各個(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ù)處理上季惩。
對消息一致性要求比較高的場合需要有應(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號输虱,從broker中某個(gè)LSN點(diǎn)批量拉取消息,這樣無須應(yīng)答機(jī)制脂凶,kafka分布式消息中間件就是這種方式宪睹。
消息的在broker中的存儲愁茁,根據(jù)消息的可靠性的要求以及性能方面的綜合衡量,可以在內(nèi)存中亭病,可以持久化到存儲上鹅很。
對于可用性和高吞吐量的要求,集群和主備模式都可以在實(shí)際的場景應(yīng)用的到罪帖。RabbitMQ解決方案中有普通的集群和可用性更高的mirror queue方式促煮。 kafka采用zookeeper對集群中的broker、consumer進(jìn)行管理整袁,可以注冊topic到zookeeper上菠齿;通過zookeeper的協(xié)調(diào)機(jī)制,producer保存對應(yīng)topic的broker信息坐昙,可以隨機(jī)或者輪詢發(fā)送到broker上绳匀;并且producer可以基于語義指定分片,消息發(fā)送到broker的某分片上炸客。
總體來講疾棵,RabbitMQ用在實(shí)時(shí)的對可靠性要求比較高的消息傳遞上。kafka主要用于處理活躍的流式數(shù)據(jù),大數(shù)據(jù)量的數(shù)據(jù)處理上痹仙。
5) Cache&Buffer
Cache系統(tǒng)
在一些高并發(fā)高性能的場景中是尔,使用cache可以減少對后端系統(tǒng)的負(fù)載,承擔(dān)可大部分讀的壓力开仰,可以大大提高系統(tǒng)的吞吐量嗜历,比如通常在數(shù)據(jù)庫存儲之前增加cache緩存。
但是引入cache架構(gòu)不可避免的帶來一些問題抖所,cache命中率的問題, cache失效引起的抖動(dòng),cache和存儲的一致性痕囱。
Cache中的數(shù)據(jù)相對于存儲來講田轧,畢竟是有限的,比較理想的情況是存儲系統(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)范圍稽莉;而對于可用性要求比較高的場景,每個(gè)節(jié)點(diǎn)都是需要有備份的涩搓。數(shù)據(jù)在cache和存儲上都存有同一份備份污秆,必然有一致性的問題劈猪,一致性比較強(qiáng)的,在更新數(shù)據(jù)庫的同時(shí)良拼,更新數(shù)據(jù)庫cache战得。對于一致性要求不高的,可以去設(shè)置緩存失效時(shí)間的策略庸推。
Memcached作為高速的分布式緩存服務(wù)器常侦,協(xié)議比較簡單,基于libevent的事件處理機(jī)制贬媒。
Cache系統(tǒng)在平臺中用在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都對數(shù)據(jù)進(jìn)行了持久化器赞,而memcache沒有這個(gè)功能垢袱,因此memcache更加適合在關(guān)系型數(shù)據(jù)庫之上的數(shù)據(jù)的緩存。
Buffer系統(tǒng)
用在高速的寫操作的場景中港柜,平臺中有些數(shù)據(jù)需要寫入數(shù)據(jù)庫请契,并且數(shù)據(jù)是分庫分表的,但對數(shù)據(jù)的可靠性不是那么高夏醉,為了減少對數(shù)據(jù)庫的寫壓力爽锥,可以采取批量寫操作的方式。
開辟一個(gè)內(nèi)存區(qū)域畔柔,當(dāng)數(shù)據(jù)到達(dá)區(qū)域的一定閥值時(shí)如80%時(shí)氯夷,在內(nèi)存中做分庫梳理工作(內(nèi)存速度還是比較快的),后分庫批量flush靶擦。
6) 搜索
在電子商務(wù)平臺中搜索是一個(gè)非常的重要功能腮考,主要有搜索詞類目導(dǎo)航、自動(dòng)提示和搜索排序功能玄捕。
開源的企業(yè)級搜索引擎主要有l(wèi)ucene, sphinx踩蔚,這里不去論述哪種搜索引擎更好一些,不過選擇搜索引擎除了基本的功能需要支持外枚粘,非功能方面需要考慮以下兩點(diǎn):
a馅闽、 搜索引擎是否支持分布式的索引和搜索,來應(yīng)對海量的數(shù)據(jù),支持讀寫分離捞蛋,提高可用性
b孝冒、 索引的實(shí)時(shí)性
c、 性能
Solr是基于lucene的高性能的全文搜索服務(wù)器拟杉,提供了比lucene更為豐富的查詢語言庄涡,可配置可擴(kuò)展,對外提供基于http協(xié)議的XML/JSON格式的接口搬设。
從Solr4版本開始提供了SolrCloud方式來支持分布式的索引穴店,自動(dòng)進(jìn)行sharding數(shù)據(jù)切分;通過每個(gè)sharding的master-slave(leader拿穴、replica)模式提高搜索的性能泣洞;利用zookeeper對集群進(jìn)行管理,包括leader選舉等等默色,保障集群的可用性球凰。
Lucene索引的Reader是基于索引的snapshot的,所以必須在索引commit的后腿宰,重新打開一個(gè)新的snapshot呕诉,才能搜索到新添加的內(nèi)容;而索引的commit是非常耗性能的吃度,這樣達(dá)到實(shí)時(shí)索引搜索效率就比較低下甩挫。
對于索引搜索實(shí)時(shí)性,Solr4的之前解決方案是結(jié)合文件全量索引和內(nèi)存增量索引合并的方式椿每,參見下圖伊者。
Solr4提供了NRT softcommit的解決方案,softcommit無需進(jìn)行提交索引操作间护,就可以搜素到最新對索引的變更亦渗,不過對索引的變更并沒有sync commit到硬盤存儲上,若發(fā)生意外導(dǎo)致程序非正常結(jié)束汁尺,未commit的數(shù)據(jù)會(huì)丟失法精,因此需要定時(shí)的進(jìn)行commit操作。
平臺中對數(shù)據(jù)的索引和存儲操作是異步的均函,可以大大提高可用性和吞吐量;只對某些屬性字段做索引操作菱涤,存儲數(shù)據(jù)的標(biāo)識key苞也,減少索引的大小粘秆;數(shù)據(jù)是存儲在分布式存儲HBase 中的如迟,HBase對二級索引搜索支持的不好,然而可以結(jié)合Solr搜索功能進(jìn)行多維度的檢索統(tǒng)計(jì)。
索引數(shù)據(jù)和HBase數(shù)據(jù)存儲的一致性殷勘,也就是如何保障HBase存儲的數(shù)據(jù)都被索引過此再,可以采用confirm確認(rèn)機(jī)制,通過在索引前建立待索引數(shù)據(jù)隊(duì)列玲销,在數(shù)據(jù)存儲并索引完成后输拇,從待索引數(shù)據(jù)隊(duì)列中刪除數(shù)據(jù)。
7) 日志收集
在整個(gè)交易過程中贤斜,會(huì)產(chǎn)生大量的日志策吠,這些日志需要收集到分布式存儲系統(tǒng)中存儲起來,以便于集中式的查詢和分析處理瘩绒。
日志系統(tǒng)需具備三個(gè)基本組件猴抹,分別為agent(封裝數(shù)據(jù)源,將數(shù)據(jù)源中的數(shù)據(jù)發(fā)送給collector)锁荔,collector(接收多個(gè)agent的數(shù)據(jù)蟀给,并進(jìn)行匯總后導(dǎo)入后端的store中),store(中央存儲系統(tǒng)阳堕,應(yīng)該具有可擴(kuò)展性和可靠性跋理,應(yīng)該支持當(dāng)前非常流行的HDFS)。
開源的日志收集系統(tǒng)業(yè)界使用的比較多的是cloudera的Flume和facebook的Scribe嘱丢,其中Flume目前的版本FlumeNG對Flume從架構(gòu)上做了較大的改動(dòng)薪介。
在設(shè)計(jì)或者對日志收集系統(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è)層次都可伸縮目木,對數(shù)據(jù)的處理不需要帶狀態(tài),伸縮性方面也比較容易實(shí)現(xiàn)懊渡。
c刽射、 近實(shí)時(shí)性
在一些時(shí)效性要求比較高的場景中,需要可以及時(shí)的收集日志剃执,進(jìn)行數(shù)據(jù)分析誓禁;
一般的日志文件都會(huì)定時(shí)或者定量的進(jìn)行rolling,所以實(shí)時(shí)檢測日志文件的生成肾档,及時(shí)對日志文件進(jìn)行類似的tail操作摹恰,并支持批量發(fā)送提高傳輸效率辫继;批量發(fā)送的時(shí)機(jī)需要滿足消息數(shù)量和時(shí)間間隔的要求。
d俗慈、 容錯(cuò)性
Scribe在容錯(cuò)方面的考慮是姑宽,當(dāng)后端的存儲系統(tǒng)crash時(shí),scribe會(huì)將數(shù)據(jù)寫到本地磁盤上闺阱,當(dāng)存儲系統(tǒng)恢復(fù)正常后炮车,scribe將日志重新加載到存儲系統(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)是對一批數(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)歸集后争拐,一般存儲在分布式文件系統(tǒng)如Hadoop腋粥,為了便于對數(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ù)存儲在本地文件中一般是基于性能的考慮纵竖,文件是順序存儲的,效率還是比較高的杏愤;數(shù)據(jù)同步到關(guān)系型數(shù)據(jù)一般是基于查詢的需求靡砌;而分布式數(shù)據(jù)庫是存儲越來越多的海量數(shù)據(jù)的,而關(guān)系型數(shù)據(jù)庫無法滿足大數(shù)據(jù)量的存儲和查詢請求珊楼。
在數(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號給agent,這樣在agent失效恢復(fù)時(shí)膜楷,可以從這個(gè)LSN點(diǎn)開始tail旭咽;當(dāng)然對于允許少量的重復(fù)記錄的問題(發(fā)生在channel給agent確認(rèn)的時(shí),agent宕機(jī)并未受到確認(rèn)消息)赌厅,需要在業(yè)務(wù)場景中判斷穷绵。
另外一個(gè)方面是sync給channel確認(rèn)已經(jīng)批量完成寫入到數(shù)據(jù)庫的操作,這樣channel可以刪除這部分已經(jīng)confirm的消息特愿。
基于可靠性的要求仲墨,channel可以采用文件持久化的方式。
參見下圖
離線全量遵循空間間換取時(shí)間洽议,分而治之的原則宗收,盡量的縮短數(shù)據(jù)同步的時(shí)間,提高同步的效率亚兄。
需要對源數(shù)據(jù)比如mysql進(jìn)行切分混稽,多線程并發(fā)讀源數(shù)據(jù),多線程并發(fā)批量寫入分布式數(shù)據(jù)庫比如HBase,利用channel作為讀寫之間的緩沖审胚,實(shí)現(xiàn)更好的解耦匈勋,channel可以基于文件存儲或者內(nèi)存。參見下圖:
對于源數(shù)據(jù)的切分膳叨,如果是文件可以根據(jù)文件名稱設(shè)置塊大小來切分洽洁。
對于關(guān)系型數(shù)據(jù)庫,由于一般的需求是只離線同步一段時(shí)間的數(shù)據(jù)(比如凌晨把當(dāng)天的訂單數(shù)據(jù)同步到HBase)菲嘴,所以需要在數(shù)據(jù)切分時(shí)(按照行數(shù)切分)饿自,會(huì)多線程掃描整個(gè)表(及時(shí)建索引汰翠,也要回表),對于表中包含大量的數(shù)據(jù)來講昭雌,IO很高复唤,效率非常低;這里解決的方法是對數(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ù)據(jù)挖掘分類器型豁、分布式索引等等。
并行處理集群有商業(yè)的EMC Greenplum尚蝌,Greenplum的架構(gòu)采用了MPP(大規(guī)模并行處理)迎变,基于postgresql的大數(shù)據(jù)量存儲的分布式數(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í)上已成為當(dāng)前互聯(lián)網(wǎng)企業(yè)主流的大數(shù)據(jù)分析平臺
Hadoop通過MapReuce的分布式處理框架苛预,用于處理大規(guī)模的數(shù)據(jù)句狼,伸縮性也非常好;但是MapReduce最大的不足是不能滿足實(shí)時(shí)性的場景热某,主要用于離線的分析腻菇。
基于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存儲的高性能的實(shí)時(shí)分析平臺希坚,可以大大降低數(shù)據(jù)分析的延遲妥粟。
目前Hadoop使用的版本是Hadoop1.0,一方面原有的MapReduce框架存在JobTracker單點(diǎn)的問題吏够,另外一方面JobTracker在做資源管理的同時(shí)又做任務(wù)的調(diào)度工作,隨著數(shù)據(jù)量的增大和Job任務(wù)的增多滩报,明顯存在可擴(kuò)展性锅知、內(nèi)存消耗、線程模型脓钾、可靠性和性能上的缺陷瓶頸售睹;Hadoop2.0 yarn對整個(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ǒng)或者應(yīng)用對日常產(chǎn)生的大量日志和異常信息谨胞,需要經(jīng)過實(shí)時(shí)過濾固歪、分析,以判定是否需要預(yù)警胯努;
同時(shí)需要對系統(tǒng)做自我保護(hù)機(jī)制牢裳,比如對模塊做流量的控制,以防止非預(yù)期的對系統(tǒng)壓力過大而引起的系統(tǒng)癱瘓叶沛,流量過大時(shí)蒲讯,可以采取拒絕或者引流等機(jī)制;有些業(yè)務(wù)需要進(jìn)行風(fēng)險(xiǎn)的控制灰署,比如彩票中有些業(yè)務(wù)需要根據(jù)系統(tǒng)的實(shí)時(shí)銷售情況進(jìn)行限號與放號判帮。
原始基于單節(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ì)算平臺就出現(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)品使用最為廣泛。
對于實(shí)時(shí)計(jì)算平臺谓谦,從架構(gòu)設(shè)計(jì)上需要考慮以下幾個(gè)因素:
1贫橙、 伸縮性
隨著業(yè)務(wù)量的增加,計(jì)算量的增加反粥,通過增加節(jié)點(diǎn)處理卢肃,就可以處理。
2才顿、 高性能莫湘、低延遲
從數(shù)據(jù)流入計(jì)算平臺數(shù)據(jù),到計(jì)算輸出結(jié)果郑气,需要性能高效且低延遲幅垮,保證消息得到快速的處理,做到實(shí)時(shí)計(jì)算尾组。
3忙芒、 可靠性
保證每個(gè)數(shù)據(jù)消息得到一次完整處理。
4讳侨、 容錯(cuò)性
系統(tǒng)可以自動(dòng)管理節(jié)點(diǎn)的宕機(jī)失效呵萨,對應(yīng)用來說,是透明的跨跨。
Twitter的Storm在以上這幾個(gè)方面做的比較好甘桑,下面簡介一下Storm的架構(gòu)。
整個(gè)集群的管理是通過zookeeper來進(jìn)行的歹叮。
客戶端提交拓?fù)涞絥imbus跑杭。
Nimbus針對該拓?fù)浣⒈镜氐哪夸浉鶕?jù)topology的配置計(jì)算task,分配task咆耿,在zookeeper上建立assignments節(jié)點(diǎn)存儲task和supervisor機(jī)器節(jié)點(diǎn)中woker的對應(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)用場景非常多,比如系統(tǒng)的監(jiān)控動(dòng)態(tài)的實(shí)時(shí)曲線繪制逝薪,手機(jī)消息的推送隅要,web實(shí)時(shí)聊天等。
實(shí)時(shí)推送有很多技術(shù)可以實(shí)現(xiàn)董济,有Comet方式步清,有websocket方式等。
Comet基于服務(wù)器長連接的“服務(wù)器推”技術(shù)虏肾,包含兩種:
Long Polling:服務(wù)器端在接到請求后掛起尼啡,有更新時(shí)返回連接即斷掉暂衡,然后客戶端再發(fā)起新的連接
Stream方式: 每次服務(wù)端數(shù)據(jù)傳送不會(huì)關(guān)閉連接,連接只會(huì)在通信出現(xiàn)錯(cuò)誤時(shí)崖瞭,或是連接重建時(shí)關(guān)閉(一些防火墻常被設(shè)置為丟棄過長的連接狂巢, 服務(wù)器端可以設(shè)置一個(gè)超時(shí)時(shí)間, 超時(shí)后通知客戶端重新建立連接书聚,并關(guān)閉原來的連接)唧领。
Websocket:長連接,全雙工通信
是 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ù)存儲
數(shù)據(jù)庫存儲大體分為以下幾類顽频,有關(guān)系型(事務(wù)型)的數(shù)據(jù)庫藤肢,以oracle、mysql為代表糯景,有keyvalue數(shù)據(jù)庫嘁圈,以redis和memcached db為代表,有文檔型數(shù)據(jù)庫如mongodb蟀淮,有列式分布式數(shù)據(jù)庫以HBase最住,cassandra,dynamo為代表,還有其他的圖形數(shù)據(jù)庫怠惶、對象數(shù)據(jù) 庫温学、xml數(shù)據(jù)庫等。每種類型的數(shù)據(jù)庫應(yīng)用的業(yè)務(wù)領(lǐng)域是不一樣的甚疟,下面從內(nèi)存型仗岖、關(guān)系型、分布式三個(gè)維度針對相關(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ù)存儲上按命名空間來劃分,一個(gè)collection是一個(gè)命名空間卓箫,一個(gè)索引也是一個(gè)命名空間载矿。
同一個(gè)命名空間的數(shù)據(jù)被分成很多個(gè)Extent,Extent之間使用雙向鏈表連接烹卒。
在每一個(gè)Extent中闷盔,保存了具體每一行的數(shù)據(jù),這些數(shù)據(jù)也是通過雙向鏈接連接的旅急。
每一行數(shù)據(jù)存儲空間不僅包括數(shù)據(jù)占用空間逢勾,還可能包含一部分附加空間,這使得在數(shù)據(jù)update變大后可以不移動(dòng)位置藐吮。
索引以BTree結(jié)構(gòu)實(shí)現(xiàn)溺拱。
如果你開啟了jorunaling日志,那么還會(huì)有一些文件存儲著你所有的操作記錄谣辞。
持久化存儲
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ù)戏阅,這對大多數(shù)應(yīng)用來說都可以容忍了昼弟。從1.9.2+,mongodb都會(huì)默認(rèn)打開journal功能奕筐,以確保數(shù)據(jù)安全舱痘。而且journal的刷新時(shí)間是可以改變的,2-300ms的范圍,使用 –journalCommitInterval 命令离赫。Oplog和數(shù)據(jù)刷新到磁盤的時(shí)間是60s芭逝,對于復(fù)制來說,不用等到oplog刷新磁盤渊胸,在內(nèi)存中就可以直接復(fù)制到Sencondary節(jié)點(diǎn)旬盯。
事務(wù)支持
Mongodb只支持對單行記錄的原子操作
HA集群
用的比較多的是Replica Sets,采用選舉算法,自動(dòng)進(jìn)行l(wèi)eader選舉胖翰,在保證可用性的同時(shí)接剩,可以做到強(qiáng)一致性要求。
當(dāng)然對于大量的數(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)鏈表的長度過長時(shí)抗果,會(huì)采取遷移的措施(擴(kuò)展原來兩倍的hash表,把數(shù)據(jù)遷移過去奸晴,expand+rehash)
持久化存儲
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í)對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ī)制晰房,該場景可以做讀寫分離。
目前在復(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層和存儲引擎層壤玫。
Server層的架構(gòu)對于不同的存儲引擎來講都是一樣的,包括連接/線程處理豁护、查詢處理(parser、optimizer)以及其他系統(tǒng)任務(wù)垦细。存儲引擎層有很多種择镇,mysql提供了存儲引擎的插件式結(jié)構(gòu)挡逼,支持多種存儲引擎括改,用的最廣泛的是innodb和myisamin;inodb主要面向OLTP方面的應(yīng)用家坎,支持事務(wù)處理嘱能,myisam不支持事務(wù),表鎖虱疏,對OLAP操作速度快惹骂。
以下主要針對innodb存儲引擎做相關(guān)介紹。
在線程處理方面做瞪,Mysql是多線程的架構(gòu)对粪,由一個(gè)master線程右冻,一個(gè)鎖監(jiān)控線程,一個(gè)錯(cuò)誤監(jiān)控線程著拭,和多個(gè)IO線程組成纱扭。并且對一個(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),包括二級索引和主鍵索引控乾,二級索引的葉子節(jié)點(diǎn)是主鍵PK么介,根據(jù)主鍵索引的葉子節(jié)點(diǎn)指向存儲的數(shù)據(jù)塊。這種B+樹存儲結(jié)構(gòu)可以更好的滿足隨機(jī)查詢操作IO要求蜕衡,分為數(shù)據(jù)頁和二級索引頁壤短,修改二級索引頁面涉及到隨機(jī)操作,為了提高寫入時(shí)的性能慨仿,采用insert buffer做順序的寫入久脯,再由后臺線程以一定頻率將多個(gè)插入合并到二級索引頁面。為了保證數(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ī)制,要避免產(chǎn)生死鎖休里,mysql在Server層和存儲引擎層做并發(fā)控制蛆挫,主要體現(xiàn)在讀寫鎖,根據(jù)鎖粒度不同妙黍,有各個(gè)級別的鎖(表鎖悴侵、行鎖、頁鎖拭嫁、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存儲引擎提供了兩次寫機(jī)制double writer用于防止在flush頁面到存儲上出現(xiàn)的錯(cuò)誤涨薪,解決磁盤half-writern的問題。
? 對于高并發(fā)高性能的mysql來講炫乓,可以在多個(gè)維度進(jìn)行性能方面的調(diào)優(yōu)刚夺。
a、硬件級別厢岂,
日志和數(shù)據(jù)的存儲光督,需要分開阳距,日志是順序的寫塔粒,需要做raid1+0,并且用buffer-IO筐摘;數(shù)據(jù)是離散的讀寫卒茬,走direct IO即可船老,避免走文件系統(tǒng)cache帶來的開銷。
存儲能力圃酵,SAS盤raid操作(raid卡緩存柳畔,關(guān)閉讀cache,關(guān)閉磁盤cache郭赐,關(guān)閉預(yù)讀薪韩,只用writeback buffer,不過需要考慮充放電的問題)捌锭,當(dāng)然如果數(shù)據(jù)規(guī)模不大俘陷,數(shù)據(jù)的存儲可以用高速的設(shè)備,F(xiàn)usion IO观谦、SSD拉盾。
對于數(shù)據(jù)的寫入,控制臟頁刷新的頻率豁状,對于數(shù)據(jù)的讀取捉偏,控制cache hit率;因此而估算系統(tǒng)需要的IOPS泻红,評估需要的硬盤數(shù)量(fusion io上到IOPS 在10w以上夭禽,普通的硬盤150)。
Cpu方面谊路,單實(shí)例關(guān)閉NUMA驻粟,mysql對多核的支持不是太好,可以對多實(shí)例進(jìn)行CPU綁定凶异。
b蜀撑、操作系統(tǒng)級別,
內(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以及存儲引擎級別(連接管理绩聘、網(wǎng)絡(luò)管理沥割、table管理、日志)
包括cache/buffer凿菩、Connection驯遇、IO
d、應(yīng)用級別(比如索引的考慮蓄髓,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)作為讀操作,支持讀寫分離耻陕。
對于節(jié)點(diǎn)主備失效檢測和切換拙徽,可以采用HA軟件,當(dāng)然也可以從更細(xì)粒度定制的角度诗宣,采用zookeeper作為集群的協(xié)調(diào)服務(wù)膘怕。
對于分布式的系統(tǒng)來講,數(shù)據(jù)庫主備切換的一致性始終是一個(gè)問題召庞,可以有以下幾種方式:
a岛心、集群方式,如oracle的rack篮灼,缺點(diǎn)是比較復(fù)雜
b忘古、共享SAN存儲方式,相關(guān)的數(shù)據(jù)文件和日志文件都放在共享存儲上诅诱,優(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的存儲上柏蘑,保證數(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ù)要求的存取方式
平臺業(yè)務(wù)中又官,不同的業(yè)務(wù)有不同的存取要求,比如典型的兩大業(yè)務(wù)用戶和訂單漫试,用戶一般來講總量是可控的赏胚,而訂單是不斷地遞增的,對于用戶表首先采取分庫切分商虐,每個(gè)sharding做一主多讀觉阅,同樣對于訂單因更多需求的是用戶查詢自己的訂單,也需要按照用戶進(jìn)行切分訂單庫秘车,并且支持一主多讀典勇。
在硬件存儲方面,對于事務(wù)日志因是順序?qū)懀W存的優(yōu)勢比硬盤高不了多少,所以采取電池保護(hù)的寫緩存的raid卡存儲硬鞍;對于數(shù)據(jù)文件梦碗,無論是對用戶或者訂單都會(huì)存在大量的隨機(jī)讀寫操作照雁,當(dāng)然加大內(nèi)存是一個(gè)方面聘裁,另外可以采用高速的IO設(shè)備閃存担锤,比如PCIe卡 fusion-io被丧。使用閃存也適合在單線程的負(fù)載中乱顾,比如主從復(fù)制板祝,可以對從節(jié)點(diǎn)配置fusion-IO卡,降低復(fù)制的延遲走净。
對于訂單業(yè)務(wù)來講券时,量是不斷遞增的,PCIe卡存儲容量比較有限伏伯,并且訂單業(yè)務(wù)的熱數(shù)據(jù)只有最近一段時(shí)間的(比如近3個(gè)月的)橘洞,對此這里列兩種解決方案,一種是flashcache方式说搅,采用基于閃存和硬盤存儲的開源混合存儲方式炸枣,在閃存中存儲熱點(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ù)庫
對于數(shù)據(jù)的高并發(fā)的訪問迂猴,傳統(tǒng)的關(guān)系型數(shù)據(jù)庫提供讀寫分離的方案,但是帶來的確實(shí)數(shù)據(jù)的一致性問題提供的數(shù)據(jù)切分的方案背伴;對于越來越多的海量數(shù)據(jù)沸毁,傳統(tǒng)的數(shù)據(jù)庫采用的是分庫分表,實(shí)現(xiàn)起來比較復(fù)雜傻寂,后期要不斷的進(jìn)行遷移維護(hù)息尺;對于高可用和伸縮方面,傳統(tǒng)數(shù)據(jù)采用的是主備疾掰、主從搂誉、多主的方案,但是本身擴(kuò)展性比較差静檬,增加節(jié)點(diǎn)和宕機(jī)需要進(jìn)行數(shù)據(jù)的遷移炭懊。對于以上提出的這些問題,分布式數(shù)據(jù)庫HBase有一套完善的解決方案拂檩,適用于高并發(fā)海量數(shù)據(jù)存取的要求侮腹。
? HBase
基于列式的高效存儲降低IO
通常的查詢不需要一行的全部字段,大多數(shù)只需要幾個(gè)字段
對與面向行的存儲系統(tǒng)稻励,每次查詢都會(huì)全部數(shù)據(jù)取出父阻,然后再從中選出需要的字段
面向列的存儲系統(tǒng)可以單獨(dú)查詢某一列,從而大大降低IO
提高壓縮效率
同列數(shù)據(jù)具有很高的相似性,會(huì)增加壓縮效率
Hbase的很多特性加矛,都是由列存儲決定的
強(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ù)存儲基于HDFS,提供了冗余機(jī)制塌鸯。
Region節(jié)點(diǎn)的宕機(jī)侍瑟,對于內(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為分布式存儲引擎溶浴,一備三乍迄,高可靠,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邦投,對過期數(shù)據(jù)進(jìn)行清除伤锚,提高查詢的性能。
Schema free
HBase沒有像關(guān)系型數(shù)據(jù)庫那樣的嚴(yán)格的schema志衣,可以自由的增加和刪除schema中的字段屯援。
HBase分布式數(shù)據(jù)庫,對于二級索引支持的不太好念脯,目前只支持在rowkey上的索引狞洋,所以rowkey的設(shè)計(jì)對于查詢的性能來講非常關(guān)鍵。
7. 管理與部署配置
統(tǒng)一的配置庫
部署平臺
8. 監(jiān)控绿店、統(tǒng)計(jì)
大型分布式系統(tǒng)涉及各種設(shè)備吉懊,比如網(wǎng)絡(luò)交換機(jī),普通PC機(jī)假勿,各種型號的網(wǎng)卡借嗽,硬盤,內(nèi)存等等转培,還有應(yīng)用業(yè)務(wù)層次的監(jiān)控恶导,數(shù)量非常多的時(shí)候,出現(xiàn)錯(cuò)誤的概率也會(huì)變大浸须,并且有些監(jiān)控的時(shí)效性要求比較高惨寿,有些達(dá)到秒級別;在大量的數(shù)據(jù)流中需要過濾異常的數(shù)據(jù)羽戒,有時(shí)候也對數(shù)據(jù)會(huì)進(jìn)行上下文相關(guān)的復(fù)雜計(jì)算缤沦,進(jìn)而決定是否需要告警。因此監(jiān)控平臺的性能易稠、吞吐量缸废、已經(jīng)可用性就比較重要,需要規(guī)劃統(tǒng)一的一體化的監(jiān)控平臺對系統(tǒng)進(jìn)行各個(gè)層次的監(jiān)控驶社。
平臺的數(shù)據(jù)分類
應(yīng)用業(yè)務(wù)級別:應(yīng)用事件企量、業(yè)務(wù)日志、審計(jì)日志亡电、請求日志届巩、異常、請求業(yè)務(wù)metrics份乒、性能度量
系統(tǒng)級別: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ù)是請求流轉(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é)果存儲到Mysql或者HBase中祝高。
監(jiān)控的web應(yīng)用可以把監(jiān)控的實(shí)時(shí)結(jié)果推送到瀏覽器中栗弟,也可以提供API供結(jié)果的展現(xiàn)和搜索。