日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

高并发高可用的 架构实践

發(fā)布時(shí)間:2025/3/15 编程问答 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 高并发高可用的 架构实践 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一、?設(shè)計(jì)理念

?

?

?

1.?????空間換時(shí)間

1)?????多級(jí)緩存,靜態(tài)化

客戶端頁(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ù),中間件等)

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模型是無(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ì)算問題的過(guò)程,是提高計(jì)算機(jī)系統(tǒng)計(jì)算速度和處理能力的一種有效手段。它的基本思想是用多個(gè)處理器/進(jìn)程/線程來(lái)協(xié)同求解同一問題,即將被求解的問題分解成若干個(gè)部分,各部分均由一個(gè)獨(dú)立的處理機(jī)來(lái)并行計(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ī)失效帶來(lái)的不可用問題;備份有在線的和離線備份,可以根據(jù)失效性要求的不同,進(jìn)行選擇不同的備份策略。

2)?????讀寫分離

讀寫分離是對(duì)數(shù)據(jù)庫(kù)來(lái)講的,隨著系統(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ò)相關(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ù)庫(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ù)的路由邏輯支持。

2)?????無(wú)狀態(tài)

對(duì)于系統(tǒng)的伸縮性而言,模塊最好是無(wú)狀態(tài)的,通過(guò)增加節(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ù)性來(lái)保證交易的一致性,所以在交易系統(tǒng)的設(shè)計(jì)時(shí),需考慮原子操作和并發(fā)控制。

保證并發(fā)控制一些常用高性能手段有,樂觀鎖、Latch、mutex、寫時(shí)復(fù)制、CAS等;多版本的并發(fā)控制MVCC通常是保證一致性的重要手段,這個(gè)在數(shù)據(jù)庫(kù)的設(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í),一定要在最后釋放資源,無(wú)論是請(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)過(guò)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模式支持通過(guò)廣域網(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做一些分流。通過(guò)端口檢測(cè)到服務(wù)器內(nèi)部的故障,比如根據(jù)服務(wù)器處理網(wǎng)頁(yè)返回的狀態(tài)碼、超時(shí)等等,并且會(huì)把返回錯(cuò)誤的請(qǐng)求重新提交到另一個(gè)節(jié)點(diǎn),不過(guò)其中缺點(diǎn)就是不支持url來(lái)檢測(cè)。對(duì)于session?sticky,可以基于ip?hash的算法來(lái)實(shí)現(xiàn),通過(guò)基于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)過(guò)Nginx,通過(guò)負(fù)載均衡算法分到到App的某一節(jié)點(diǎn),這一層層擴(kuò)容起來(lái)比較簡(jiǎn)單。

除了利用cookie保存少量用戶部分信息外(cookie一般不能超過(guò)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í)候,就可以通過(guò)增加更多的應(yīng)用節(jié)點(diǎn)來(lái)達(dá)到水平擴(kuò)展的目的。

Session的集中式存儲(chǔ),需要滿足以下幾點(diǎn)要求:

a、高效的通訊協(xié)議

b、session的分布式緩存,支持節(jié)點(diǎn)的伸縮,數(shù)據(jù)的冗余備份以及數(shù)據(jù)的遷移

c、session過(guò)期的管理

?

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)(比原來(lái)方案的優(yōu)點(diǎn))

一致性、事務(wù):

對(duì)于分布式系統(tǒng)的一致性,盡量滿足可用性,一致性可以通過(guò)校對(duì)來(lái)達(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ù)過(guò)程可以分兩個(gè)階段,一個(gè)是發(fā)送請(qǐng)求過(guò)程,另外一個(gè)是接收響應(yīng)過(guò)程。在發(fā)送請(qǐng)求過(guò)程中,若發(fā)生IOException,則把該連接標(biāo)記失效。接收響應(yīng)時(shí),服務(wù)端返回SocketTimeoutException,如果設(shè)置了超時(shí)時(shí)間,那么就直接返回異常,清除當(dāng)前連接中那些超時(shí)的請(qǐng)求。否則繼續(xù)發(fā)送心跳包(因?yàn)榭赡苁莵G包,超過(guò)pingInterval間隔時(shí)間就發(fā)送ping操作),若ping不通(發(fā)送IOException),則說(shuō)明當(dāng)前連接是有問題的,那么就把當(dāng)前連接標(biāo)記成已經(jīng)失效;若ping通,則說(shuō)明當(dāng)前連接是可靠的,繼續(xù)進(jìn)行讀操作。失效的連接會(huì)從連接池中清除掉。

每個(gè)連接對(duì)于接收響應(yīng)來(lái)說(shuō)都以單獨(dú)的線程運(yùn)行,客戶端可以通過(guò)同步(wait,notify)方式或者異步進(jìn)行rpc調(diào)用,

序列化采用更高效的hession序列化方式。

服務(wù)端采用事件驅(qū)動(dòng)的NIO的MINA框架,支撐高并發(fā)高吞吐量的請(qǐng)求。

?

2)?路由Router

在大多數(shù)的數(shù)據(jù)庫(kù)切分解決方案中,為了提高數(shù)據(jù)庫(kù)的吞吐量,首先是對(duì)不同的表進(jìn)行垂直切分到不同的數(shù)據(jù)庫(kù)中,

然后當(dāng)數(shù)據(jù)庫(kù)中一個(gè)表超過(guò)一定大小時(shí),需要對(duì)該表進(jìn)行水平切分,這里也是一樣,這里以用戶表為例;

對(duì)于訪問數(shù)據(jù)庫(kù)客戶端來(lái)講,需要根據(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)容通過(guò)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ù)載均衡,通過(guò)檢測(cè)vrrp數(shù)據(jù)包來(lái)切換,做冗余熱備更加適合與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模式,可以通過(guò)zookeeper分布式鎖的機(jī)制來(lái)支持。

4)?消息Message

對(duì)于平臺(tái)各個(gè)系統(tǒng)之間的異步交互,是通過(guò)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)消息的過(guò)程;不過(guò)因網(wǎng)絡(luò)等原理導(dǎo)致的應(yīng)答缺失,可能會(huì)導(dǎo)致消息的重復(fù),這個(gè)可以在業(yè)務(wù)層次根據(jù)冪等性進(jìn)行判斷過(guò)濾;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上;通過(guò)zookeeper的協(xié)調(diào)機(jī)制,producer保存對(duì)應(yīng)topic的broker信息,可以隨機(jī)或者輪詢發(fā)送到broker上;并且producer可以基于語(yǔ)義指定分片,消息發(fā)送到broker的某分片上。

總體來(lái)講,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ù)庫(kù)存儲(chǔ)之前增加cache緩存。

但是引入cache架構(gòu)不可避免的帶來(lái)一些問題,cache命中率的問題,?cache失效引起的抖動(dòng),cache和存儲(chǔ)的一致性。

Cache中的數(shù)據(jù)相對(duì)于存儲(chǔ)來(lái)講,畢竟是有限的,比較理想的情況是存儲(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。

6)?搜索

在電子商務(wù)平臺(tái)中搜索是一個(gè)非常的重要功能,主要有搜索詞類目導(dǎo)航、自動(dòng)提示和搜索排序功能。

開源的企業(yè)級(jí)搜索引擎主要有l(wèi)ucene,?sphinx,這里不去論述哪種搜索引擎更好一些,不過(guò)選擇搜索引擎除了基本的功能需要支持外,非功能方面需要考慮以下兩點(diǎn):

a、?搜索引擎是否支持分布式的索引和搜索,來(lái)應(yīng)對(duì)海量的數(shù)據(jù),支持讀寫分離,提高可用性

b、?索引的實(shí)時(shí)性

c、?性能

Solr是基于lucene的高性能的全文搜索服務(wù)器,提供了比lucene更為豐富的查詢語(yǔ)言,可配置可擴(kuò)展,對(duì)外提供基于http協(xié)議的XML/JSON格式的接口。

從Solr4版本開始提供了SolrCloud方式來(lái)支持分布式的索引,自動(dòng)進(jìn)行sharding數(shù)據(jù)切分;通過(guò)每個(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ì)索引的變更,不過(guò)對(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ù)都被索引過(guò),可以采用confirm確認(rèn)機(jī)制,通過(guò)在索引前建立待索引數(shù)據(jù)隊(duì)列,在數(shù)據(jù)存儲(chǔ)并索引完成后,從待索引數(shù)據(jù)隊(duì)列中刪除數(shù)據(jù)。

?

?

7)?日志收集

在整個(gè)交易過(guò)程中,會(huì)產(chǎn)生大量的日志,這些日志需要收集到分布式存儲(chǔ)系統(tǒng)中存儲(chǔ)起來(lái),以便于集中式的查詢和分析處理。

日志系統(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í),可以通過(guò)增加節(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通過(guò)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可以通過(guò)組中所有Sink實(shí)現(xiàn)負(fù)載均衡;也可以在一個(gè)Sink失敗時(shí)轉(zhuǎn)移到另一個(gè)。

e、?事務(wù)支持

Scribe沒有考慮事務(wù)的支持。

Flume通過(guò)應(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)過(guò)日志收集系統(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ù)庫(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ǔ)越來(lái)越多的海量數(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è)維度來(lái)介紹一下,

實(shí)時(shí)增量一般是Tail文件來(lái)實(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è)置塊大小來(lái)切分。

對(duì)于關(guān)系型數(shù)據(jù)庫(kù),由于一般的需求是只離線同步一段時(shí)間的數(shù)據(jù)(比如凌晨把當(dāng)天的訂單數(shù)據(jù)同步到HBase),所以需要在數(shù)據(jù)切分時(shí)(按照行數(shù)切分),會(huì)多線程掃描整個(gè)表(及時(shí)建索引,也要回表),對(duì)于表中包含大量的數(shù)據(jù)來(lái)講,IO很高,效率非常低;這里解決的方法是對(duì)數(shù)據(jù)庫(kù)按照時(shí)間字段(按照時(shí)間同步的)建立分區(qū),每次按照分區(qū)進(jìn)行導(dǎo)出。

9)?數(shù)據(jù)分析

從傳統(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通過(guò)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)過(guò)語(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)

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)過(guò)實(shí)時(shí)過(guò)濾、分析,以判定是否需要預(yù)警;

同時(shí)需要對(duì)系統(tǒng)做自我保護(hù)機(jī)制,比如對(duì)模塊做流量的控制,以防止非預(yù)期的對(duì)系統(tǒng)壓力過(guò)大而引起的系統(tǒng)癱瘓,流量過(guò)大時(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)了。

這里所說(shuō)的實(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ì)算量的增加,通過(guò)增加節(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)用來(lái)說(shuō),是透明的。

Twitter的Storm在以上這幾個(gè)方面做的比較好,下面簡(jiǎn)介一下Storm的架構(gòu)。

整個(gè)集群的管理是通過(guò)zookeeper來(lái)進(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)來(lái)監(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之間是通過(guò)zeroMQ管理的;之后整個(gè)拓?fù)溥\(yùn)行起來(lái)。

Tuple是流的基本處理單元,也就是一個(gè)消息,Tuple在task中流轉(zhuǎn),Tuple的發(fā)送和接收過(guò)程如下:

發(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通過(guò)zeroMQ發(fā)送到其他的woker中。

接收Tuple,每個(gè)woker都會(huì)監(jiān)聽zeroMQ的tcp端口來(lái)接收消息,消息放到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的目的地。

通過(guò)以上分析可以看到,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è)置為丟棄過(guò)長(zhǎng)的連接,?服務(wù)器端可以設(shè)置一個(gè)超時(shí)時(shí)間,?超時(shí)后通知客戶端重新建立連接,并關(guān)閉原來(lái)的連接)。

Websocket:長(zhǎng)連接,全雙工通信

是?Html5?的一種新的協(xié)議。它實(shí)現(xiàn)了瀏覽器與服務(wù)器的雙向通訊。webSocket?API?中,瀏覽器和服務(wù)器端只需要通過(guò)一個(gè)握手的動(dòng)作,便能形成瀏覽器與客戶端之間的快速雙向通道,使得數(shù)據(jù)可以快速的雙向傳播。

Socket.io是一個(gè)NodeJS?websocket庫(kù),包括客戶端的JS和服務(wù)端的的nodejs,用于快速構(gòu)建實(shí)時(shí)的web應(yīng)用。

12) 推薦引擎

?待補(bǔ)充

?

6.?數(shù)據(jù)存儲(chǔ)

數(shù)據(jù)庫(kù)存儲(chǔ)大體分為以下幾類,有關(guān)系型(事務(wù)型)的數(shù)據(jù)庫(kù),以oracle、mysql為代表,有keyvalue數(shù)據(jù)庫(kù),以redis和memcached?db為代表,有文檔型數(shù)據(jù)庫(kù)如mongodb,有列式分布式數(shù)據(jù)庫(kù)以HBase,cassandra,dynamo為代表,還有其他的圖形數(shù)據(jù)庫(kù)、對(duì)象數(shù)據(jù)?庫(kù)、xml數(shù)據(jù)庫(kù)等。每種類型的數(shù)據(jù)庫(kù)應(yīng)用的業(yè)務(wù)領(lǐng)域是不一樣的,下面從內(nèi)存型、關(guān)系型、分布式三個(gè)維度針對(duì)相關(guān)的產(chǎn)品做性能可用性等方面的考量分析。

1)?內(nèi)存型數(shù)據(jù)庫(kù)

內(nèi)存型的數(shù)據(jù)庫(kù),以高并發(fā)高性能為目標(biāo),在事務(wù)性方面沒那么嚴(yán)格,以開源nosql數(shù)據(jù)庫(kù)mongodb、redis為例

??Mongodb

通信方式

多線程方式,主線程監(jiān)聽新的連接,連接后,啟動(dòng)新的線程做數(shù)據(jù)的操作(IO切換)。

數(shù)據(jù)結(jié)構(gòu)

?

?

?

數(shù)據(jù)庫(kù)-->collection-->record

MongoDB在數(shù)據(jù)存儲(chǔ)上按命名空間來(lái)劃分,一個(gè)collection是一個(gè)命名空間,一個(gè)索引也是一個(gè)命名空間。

同一個(gè)命名空間的數(shù)據(jù)被分成很多個(gè)Extent,Extent之間使用雙向鏈表連接。

在每一個(gè)Extent中,保存了具體每一行的數(shù)據(jù),這些數(shù)據(jù)也是通過(guò)雙向鏈接連接的。

每一行數(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)用來(lái)說(shuō)都可以容忍了。從1.9.2+,mongodb都會(huì)默認(rèn)打開journal功能,以確保數(shù)據(jù)安全。而且journal的刷新時(shí)間是可以改變的,2-300ms的范圍,使用?--journalCommitInterval?命令。Oplog和數(shù)據(jù)刷新到磁盤的時(shí)間是60s,對(duì)于復(fù)制來(lái)說(shuō),不用等到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)度過(guò)長(zhǎng)時(shí),會(huì)采取遷移的措施(擴(kuò)展原來(lái)兩倍的hash表,把數(shù)據(jù)遷移過(guò)去,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ā)出來(lái)的命令

b、增量持久化(aof類似redolog),先寫到日志buffer,再flush到日志文件中(flush的策略可以配置的,而已單條,也可以批量),只有flush到文件上的,才真正返回客戶端。

要定時(shí)對(duì)aof文件和rdb文件做合并操作(在快照過(guò)程中,變化的數(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傳遞過(guò)來(lái)的rdb文件以后會(huì)將自身的內(nèi)存清空,把rdb文件重新加載到內(nèi)存中。這種方式效率比較低下,在后面的未來(lái)版本Redis2.8作者已經(jīng)實(shí)現(xiàn)了部分復(fù)制的功能。

2)?關(guān)系型數(shù)據(jù)庫(kù)

關(guān)系型數(shù)據(jù)庫(kù)在滿足并發(fā)性能的同時(shí),也需要滿足事務(wù)性,以mysql數(shù)據(jù)庫(kù)為例,講述架構(gòu)設(shè)計(jì)原理,在性能方面的考慮,以及如何滿足可用性的需求。?

??mysql的架構(gòu)原理(innodb)

在架構(gòu)上,mysql分為server層和存儲(chǔ)引擎層。

Server層的架構(gòu)對(duì)于不同的存儲(chǔ)引擎來(lái)講都是一樣的,包括連接/線程處理、查詢處理(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ū)、頁(yè)/塊,行。索引結(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ù)頁(yè)和二級(jí)索引頁(yè),修改二級(jí)索引頁(yè)面涉及到隨機(jī)操作,為了提高寫入時(shí)的性能,采用insert?buffer做順序的寫入,再由后臺(tái)線程以一定頻率將多個(gè)插入合并到二級(jí)索引頁(yè)面。為了保證數(shù)據(jù)庫(kù)的一致性(內(nèi)存和硬盤數(shù)據(jù)文件),以及縮短實(shí)例恢復(fù)的時(shí)間,關(guān)系型數(shù)據(jù)庫(kù)還有一個(gè)checkpoint的功能,用于把內(nèi)存buffer中之前的臟頁(yè)按照比例(老的LSN)寫入磁盤,這樣redolog文件的LSN以前的日志就可以被覆蓋了,進(jìn)行循環(huán)使用;在失效恢復(fù)時(shí),只需要從日志中LSN點(diǎn)進(jìn)行恢復(fù)即可。

在事務(wù)特性支持上,關(guān)系型數(shù)據(jù)庫(kù)需要滿足ACID四個(gè)特性,需要根據(jù)不同的事務(wù)并發(fā)和數(shù)據(jù)可見性要求,定義了不同的事務(wù)隔離級(jí)別,并且離不開對(duì)資源爭(zhēng)用的鎖機(jī)制,要避免產(chǎn)生死鎖,mysql在Server層和存儲(chǔ)引擎層做并發(fā)控制,主要體現(xiàn)在讀寫鎖,根據(jù)鎖粒度不同,有各個(gè)級(jí)別的鎖(表鎖、行鎖、頁(yè)鎖、MVCC);基于提高并發(fā)性能的考慮,使用多版本并發(fā)控制MVCC來(lái)支持事務(wù)的隔離,并基于undo來(lái)實(shí)現(xiàn),在做事務(wù)回滾時(shí),也會(huì)用到undo段。mysql?用redolog來(lái)保證數(shù)據(jù)的寫入的性能和失效恢復(fù),在修改數(shù)據(jù)時(shí)只需要修改內(nèi)存,再把修改行為記錄到事務(wù)日志中(順序IO),不用每次將數(shù)據(jù)修改本身持久化到硬盤(隨機(jī)IO),大大提高性能。

在可靠性方面,innodb存儲(chǔ)引擎提供了兩次寫機(jī)制double?writer用于防止在flush頁(yè)面到存儲(chǔ)上出現(xiàn)的錯(cuò)誤,解決磁盤half-writern的問題。

?

??對(duì)于高并發(fā)高性能的mysql來(lái)講,可以在多個(gè)維度進(jìn)行性能方面的調(diào)優(yōu)。

a、硬件級(jí)別,

日志和數(shù)據(jù)的存儲(chǔ),需要分開,日志是順序的寫,需要做raid1+0,并且用buffer-IO;數(shù)據(jù)是離散的讀寫,走direct?IO即可,避免走文件系統(tǒng)cache帶來(lái)的開銷。

存儲(chǔ)能力,SAS盤raid操作(raid卡緩存,關(guān)閉讀cache,關(guān)閉磁盤cache,關(guān)閉預(yù)讀,只用writeback?buffer,不過(guò)需要考慮充放電的問題),當(dāng)然如果數(shù)據(jù)規(guī)模不大,數(shù)據(jù)的存儲(chǔ)可以用高速的設(shè)備,Fusion?IO、SSD。

對(duì)于數(shù)據(jù)的寫入,控制臟頁(yè)刷新的頻率,對(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)來(lái)講,數(shù)據(jù)庫(kù)主備切換的一致性始終是一個(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ù)沒有同步過(guò)來(lái),帶來(lái)了數(shù)據(jù)的一致性問題。可以在操作主數(shù)據(jù)庫(kù)的同時(shí),記錄操作日志,切換到備時(shí),會(huì)和操作日志做個(gè)check,補(bǔ)齊未同步過(guò)來(lái)的數(shù)據(jù);

d、還有一種做法是備庫(kù)切換到主庫(kù)的regolog的存儲(chǔ)上,保證數(shù)據(jù)不丟失。

數(shù)據(jù)庫(kù)主從復(fù)制的效率在mysql上不是太高,主要原因是事務(wù)是嚴(yán)格保持順序的,索引mysql在復(fù)制方面包括日志IO和relog?log兩個(gè)過(guò)程都是單線程的串行操作,在數(shù)據(jù)復(fù)制優(yōu)化方面,盡量減少IO的影響。不過(guò)到了Mysql5.6版本,可以支持在不同的庫(kù)上的并行復(fù)制。

??基于不同業(yè)務(wù)要求的存取方式

平臺(tái)業(yè)務(wù)中,不同的業(yè)務(wù)有不同的存取要求,比如典型的兩大業(yè)務(wù)用戶和訂單,用戶一般來(lái)講總量是可控的,而訂單是不斷地遞增的,對(duì)于用戶表首先采取分庫(kù)切分,每個(gè)sharding做一主多讀,同樣對(duì)于訂單因更多需求的是用戶查詢自己的訂單,也需要按照用戶進(jìn)行切分訂單庫(kù),并且支持一主多讀。

在硬件存儲(chǔ)方面,對(duì)于事務(wù)日志因是順序?qū)?#xff0c;閃存的優(yōu)勢(shì)比硬盤高不了多少,所以采取電池保護(hù)的寫緩存的raid卡存儲(chǔ);對(duì)于數(shù)據(jù)文件,無(wú)論是對(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ù)來(lái)講,量是不斷遞增的,PCIe卡存儲(chǔ)容量比較有限,并且訂單業(yè)務(wù)的熱數(shù)據(jù)只有最近一段時(shí)間的(比如近3個(gè)月的),對(duì)此這里列兩種解決方案,一種是flashcache方式,采用基于閃存和硬盤存儲(chǔ)的開源混合存儲(chǔ)方式,在閃存中存儲(chǔ)熱點(diǎn)的數(shù)據(jù)。另外一種是可以定期把老的數(shù)據(jù)導(dǎo)出到分布式數(shù)據(jù)庫(kù)HBase中,用戶在查詢訂單列表是近期的數(shù)據(jù)從mysql中獲取,老的數(shù)據(jù)可以從HBase中查詢,當(dāng)然需要HBase良好的rowkey設(shè)計(jì)以適應(yīng)查詢需求。

?

?

3)?分布式數(shù)據(jù)庫(kù)

對(duì)于數(shù)據(jù)的高并發(fā)的訪問,傳統(tǒng)的關(guān)系型數(shù)據(jù)庫(kù)提供讀寫分離的方案,但是帶來(lái)的確實(shí)數(shù)據(jù)的一致性問題提供的數(shù)據(jù)切分的方案;對(duì)于越來(lái)越多的海量數(shù)據(jù),傳統(tǒng)的數(shù)據(jù)庫(kù)采用的是分庫(kù)分表,實(shí)現(xiàn)起來(lái)比較復(fù)雜,后期要不斷的進(jìn)行遷移維護(hù);對(duì)于高可用和伸縮方面,傳統(tǒng)數(shù)據(jù)采用的是主備、主從、多主的方案,但是本身擴(kuò)展性比較差,增加節(jié)點(diǎn)和宕機(jī)需要進(jìn)行數(shù)據(jù)的遷移。對(duì)于以上提出的這些問題,分布式數(shù)據(jù)庫(kù)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ǔ)決定的

高性能

LSM?Tree

適合高速寫的場(chǎng)景

?

?

強(qiáng)一致的數(shù)據(jù)訪問

MVCC

HBase的一致性數(shù)據(jù)訪問是通過(guò)MVCC來(lái)實(shí)現(xiàn)的。

HBase在寫數(shù)據(jù)的過(guò)程中,需要經(jīng)過(guò)好幾個(gè)階段,寫HLog,寫memstore,更新MVCC;

只有更新了MVCC,才算真正memstore寫成功,其中事務(wù)的隔離需要有mvcc的來(lái)控制,比如讀數(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)切分,遷移

通過(guò)Zookeeper定位目標(biāo)Region?Server,最后定位Region。?

Region?Server擴(kuò)容,通過(guò)將自身發(fā)布到Master,Master均勻分布。

?

可用性

存在單點(diǎn)故障,Region?Server宕機(jī)后,短時(shí)間內(nèi)該server維護(hù)的region無(wú)法訪問,等待failover生效。?

通過(guò)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訪問過(guò)于頻繁,單機(jī)壓力過(guò)大,提供了split機(jī)制

HBase的寫入是LSM-TREE的架構(gòu)方式,隨著數(shù)據(jù)的append,HFile越來(lái)越多,HBase提供了HFile文件進(jìn)行compact,對(duì)過(guò)期數(shù)據(jù)進(jìn)行清除,提高查詢的性能。

Schema?free

HBase沒有像關(guān)系型數(shù)據(jù)庫(kù)那樣的嚴(yán)格的schema,可以自由的增加和刪除schema中的字段。

?

HBase分布式數(shù)據(jù)庫(kù),對(duì)于二級(jí)索引支持的不太好,目前只支持在rowkey上的索引,所以rowkey的設(shè)計(jì)對(duì)于查詢的性能來(lái)講非常關(guān)鍵。

7.?管理與部署配置

統(tǒng)一的配置庫(kù)

部署平臺(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ù)流中需要過(guò)濾異常的數(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)用的事件以及通過(guò)探針的方式采集數(shù)據(jù),agent采集數(shù)據(jù)的一個(gè)原則是和業(yè)務(wù)應(yīng)用的流程是異步隔離的,不影響交易流程。

數(shù)據(jù)統(tǒng)一通過(guò)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)過(guò)計(jì)算集群處理后,結(jié)果存儲(chǔ)到Mysql或者HBase中。

監(jiān)控的web應(yīng)用可以把監(jiān)控的實(shí)時(shí)結(jié)果推送到瀏覽器中,也可以提供API供結(jié)果的展現(xiàn)和搜索。

?

轉(zhuǎn)載于:https://www.cnblogs.com/qy6868668/p/8547723.html

總結(jié)

以上是生活随笔為你收集整理的高并发高可用的 架构实践的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。