中文字幕在线观看,亚洲а∨天堂久久精品9966,亚洲成a人片在线观看你懂的,亚洲av成人片无码网站,亚洲国产精品无码久久久五月天

構(gòu)建高并發(fā)高可用的電商平臺架構(gòu)實踐(二)——架構(gòu)剖析

2018-07-20    來源:編程學(xué)習(xí)網(wǎng)

容器云強勢上線!快速搭建集群,上萬Linux鏡像隨意使用

CDN

CDN系統(tǒng)能夠?qū)崟r地根據(jù)網(wǎng)絡(luò)流量和各節(jié)點的連接、負(fù)載狀況以及到用戶的距離和響應(yīng)時間等綜合信息將用戶的請求重新導(dǎo)向離用戶最近的服務(wù)節(jié)點上。其目的是使用戶可就近取得所需內(nèi)容,解決 Internet網(wǎng)絡(luò)擁擠的狀況,提高用戶訪問網(wǎng)站的響應(yīng)速度。

對于大規(guī)模電子商務(wù)平臺一般需要建CDN做網(wǎng)絡(luò)加速,大型平臺如淘寶、京東都采用自建CDN,中小型的企業(yè)可以采用第三方CDN廠商合作,如藍汛、網(wǎng)宿、快網(wǎng)等。

當(dāng)然在選擇CDN廠商時,需要考慮經(jīng)營時間長短,是否有可擴充的帶寬資源、靈活的流量和帶寬選擇、穩(wěn)定的節(jié)點、性價比。

負(fù)載均衡、反向代理

一個大型的平臺包括很多個業(yè)務(wù)域,不同的業(yè)務(wù)域有不同的集群,可以用DNS做域名解析的分發(fā)或輪詢,DNS方式實現(xiàn)簡單,但是因存在cache而缺乏靈活性;一般基于商用的硬件F5、NetScaler或者開源的軟負(fù)載lvs在4層做分發(fā),當(dāng)然會采用做冗余(比如lvs+keepalived)的考慮,采取主備方式。

4層分發(fā)到業(yè)務(wù)集群上后,會經(jīng)過web服務(wù)器如nginx或者HAProxy在7層做負(fù)載均衡或者反向代理分發(fā)到集群中的應(yīng)用節(jié)點。

選擇哪種負(fù)載,需要綜合考慮各種因素(是否滿足高并發(fā)高性能,Session保持如何解決,負(fù)載均衡的算法如何,支持壓縮,緩存的內(nèi)存消耗);下面基于幾種常用的負(fù)載均衡軟件做個介紹。

LVS,工作在4層,Linux實現(xiàn)的高性能高并發(fā)、可伸縮性、可靠的的負(fù)載均衡器,支持多種轉(zhuǎn)發(fā)方式(NAT、DR、IP Tunneling),其中DR模式支持通過廣域網(wǎng)進行負(fù)載均衡。支持雙機熱備(Keepalived或者Heartbeat)。對網(wǎng)絡(luò)環(huán)境的依賴性比較高。

Nginx工作在7層,事件驅(qū)動的、異步非阻塞的架構(gòu)、支持多進程的高并發(fā)的負(fù)載均衡器/反向代理軟件?梢葬槍τ蛎、目錄結(jié)構(gòu)、正則規(guī)則針對http做一些分流。通過端口檢測到服務(wù)器內(nèi)部的故障,比如根據(jù)服務(wù)器處理網(wǎng)頁返回的狀態(tài)碼、超時等等,并且會把返回錯誤的請求重新提交到另一個節(jié)點,不過其中缺點就是不支持url來檢測。對于session sticky,可以基于ip hash的算法來實現(xiàn),通過基于cookie的擴展nginx-sticky-module支持session sticky。

HAProxy支持4層和7層做負(fù)載均衡,支持session的會話保持,cookie的引導(dǎo);支持后端url方式的檢測;負(fù)載均衡的算法比較豐富,有RR、權(quán)重等。

對于圖片,需要有單獨的域名,獨立或者分布式的圖片服務(wù)器或者如mogileFS,可以圖片服務(wù)器之上加varnish做圖片緩存。

App接入

應(yīng)用層運行在jboss或者tomcat容器中,代表獨立的系統(tǒng),比如前端購物、用戶自主服務(wù)、后端系統(tǒng)等

協(xié)議接口,HTTP、JSON

可以采用servlet3.0,異步化servlet,提高整個系統(tǒng)的吞吐量

http請求經(jīng)過Nginx,通過負(fù)載均衡算法分到到App的某一節(jié)點,這一層層擴容起來比較簡單。

除了利用cookie保存少量用戶部分信息外(cookie一般不能超過4K的大小),對于App接入層,保存有用戶相關(guān)的session數(shù)據(jù),但是有些反向代理或者負(fù)載均衡不支持對session sticky支持不是很好或者對接入的可用性要求比較高(app接入節(jié)點宕機,session隨之丟失),這就需要考慮session的集中式存儲,使得App接入層無狀態(tài)化,同時系統(tǒng)用戶變多的時候,就可以通過增加更多的應(yīng)用節(jié)點來達到水平擴展的目的。

Session的集中式存儲,需要滿足以下幾點要求:

  • 高效的通訊協(xié)議
  • session的分布式緩存,支持節(jié)點的伸縮,數(shù)據(jù)的冗余備份以及數(shù)據(jù)的遷移
  • session過期的管理

業(yè)務(wù)服務(wù)

代表某一領(lǐng)域的業(yè)務(wù)提供的服務(wù),對于電商而言,領(lǐng)域有用戶、商品、訂單、紅包、支付業(yè)務(wù)等等,不同的領(lǐng)域提供不同的服務(wù),

這些不同的領(lǐng)域構(gòu)成一個個模塊,良好的模塊劃分和接口設(shè)計非常重要,一般是參考高內(nèi)聚、接口收斂的原則,

這樣可以提高整個系統(tǒng)的可用性。當(dāng)然可以根據(jù)應(yīng)用規(guī)模的大小,模塊可以部署在一起,對于大規(guī)模的應(yīng)用,一般是獨立部署的。

高并發(fā):

業(yè)務(wù)層對外協(xié)議以NIO的RPC方式暴露,可以采用比較成熟的NIO通訊框架,如netty、mina

可用性:

為了提高模塊服務(wù)的可用性,一個模塊部署在多個節(jié)點做冗余,并自動進行負(fù)載轉(zhuǎn)發(fā)和失效轉(zhuǎn)移;

最初可以利用VIP+heartbeat方式,目前系統(tǒng)有一個單獨的組件HA,利用zookeeper實現(xiàn)(比原來方案的優(yōu)點)

一致性、事務(wù):

對于分布式系統(tǒng)的一致性,盡量滿足可用性,一致性可以通過校對來達到最終一致的狀態(tài)。

基礎(chǔ)服務(wù)中間件

通信組件

通信組件用于業(yè)務(wù)系統(tǒng)內(nèi)部服務(wù)之間的調(diào)用,在大并發(fā)的電商平臺中,需要滿足高并發(fā)高吞吐量的要求。

整個通信組件包括客戶端和服務(wù)端兩部分。

客戶端和服務(wù)器端維護的是長連接,可以減少每次請求建立連接的開銷,在客戶端對于每個服務(wù)器定義一個連接池,初始化連接后,可以并發(fā)連接服務(wù)端進行rpc操作,連接池中的長連接需要心跳維護,設(shè)置請求超時時間。

對于長連接的維護過程可以分兩個階段,一個是發(fā)送請求過程,另外一個是接收響應(yīng)過程。在發(fā)送請求過程中,若發(fā)生IOException,則把該連接標(biāo)記失效。接收響應(yīng)時,服務(wù)端返回SocketTimeoutException,如果設(shè)置了超時時間,那么就直接返回異常,清除當(dāng)前連接中那些超時的請求。否則繼續(xù)發(fā)送心跳包(因為可能是丟包,超過pingInterval間隔時間就發(fā)送ping操作),若ping不通(發(fā)送IOException),則說明當(dāng)前連接是有問題的,那么就把當(dāng)前連接標(biāo)記成已經(jīng)失效;若ping通,則說明當(dāng)前連接是可靠的,繼續(xù)進行讀操作。失效的連接會從連接池中清除掉。

每個連接對于接收響應(yīng)來說都以單獨的線程運行,客戶端可以通過同步(wait,notify)方式或者異步進行rpc調(diào)用,

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

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

通信組件

路由Router

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

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

對于訪問數(shù)據(jù)庫客戶端來講,需要根據(jù)用戶的ID,定位到需要訪問的數(shù)據(jù);

數(shù)據(jù)切分算法,

根據(jù)用戶的ID做hash操作,一致性Hash,這種方式存在失效數(shù)據(jù)的遷移問題,遷移時間內(nèi)服務(wù)不可用

維護路由表,路由表中存儲用戶和sharding的映射關(guān)系,sharding分為leader和replica,分別負(fù)責(zé)寫和讀

這樣每個biz客戶端都需要保持所有sharding的連接池,這樣有個缺點是會產(chǎn)生全連接的問題;

一種解決方法是sharding的切分提到業(yè)務(wù)服務(wù)層進行,每個業(yè)務(wù)節(jié)點只維護一個shard的連接即可。

見圖(router)

路由router

路由組件的實現(xiàn)是這樣的(可用性、高性能、高并發(fā))

基于性能方面的考慮,采用mongodb中維護用戶id和shard的關(guān)系,為了保證可用性,搭建replicatset集群。

biz的sharding和數(shù)據(jù)庫的sharding是一一對應(yīng)的,只訪問一個數(shù)據(jù)庫sharding.

biz業(yè)務(wù)注冊節(jié)點到zookeeper上/bizs/shard/下。

router監(jiān)聽zookeeper上/bizs/下節(jié)點狀態(tài),緩存在線biz在router中。

client請求router獲取biz時,router首先從mongodb中獲取用戶對應(yīng)的shard,router根據(jù)緩存的內(nèi)容通過RR算法獲取biz節(jié)點。

為了解決router的可用性和并發(fā)吞吐量問題,對router進行冗余,同時client監(jiān)聽zookeeper的/routers節(jié)點并緩存在線router節(jié)點列表。

HA

傳統(tǒng)實現(xiàn)HA的做法一般是采用虛擬IP漂移,結(jié)合Heartbeat、keepalived等實現(xiàn)HA,

Keepalived使用vrrp方式進行數(shù)據(jù)包的轉(zhuǎn)發(fā),提供4層的負(fù)載均衡,通過檢測vrrp數(shù)據(jù)包來切換,做冗余熱備更加適合與LVS搭配。Linux Heartbeat是基于網(wǎng)絡(luò)或者主機的服務(wù)的高可用,HAProxy或者Nginx可以基于7層進行數(shù)據(jù)包的轉(zhuǎn)發(fā),因此Heatbeat更加適合做HAProxy、Nginx,包括業(yè)務(wù)的高可用。

在分布式的集群中,可以用zookeeper做分布式的協(xié)調(diào),實現(xiàn)集群的列表維護和失效通知,客戶端可以選擇hash算法或者roudrobin實現(xiàn)負(fù)載均衡;對于master-master模式、master-slave模式,可以通過zookeeper分布式鎖的機制來支持。

消息Message

對于平臺各個系統(tǒng)之間的異步交互,是通過MQ組件進行的。

在設(shè)計消息服務(wù)組件時,需要考慮消息一致性、持久化、可用性、以及完善的監(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)機制,包括生產(chǎn)消息和消費消息的過程;不過因網(wǎng)絡(luò)等原理導(dǎo)致的應(yīng)答缺失,可能會導(dǎo)致消息的重復(fù),這個可以在業(yè)務(wù)層次根據(jù)冪等性進行判斷過濾;RabbitMQ采用的是這種方式。還有一種機制是消費端從broker拉取消息時帶上LSN號,從broker中某個LSN點批量拉取消息,這樣無須應(yīng)答機制,kafka分布式消息中間件就是這種方式。

消息的在broker中的存儲,根據(jù)消息的可靠性的要求以及性能方面的綜合衡量,可以在內(nèi)存中,可以持久化到存儲上。

對于可用性和高吞吐量的要求,集群和主備模式都可以在實際的場景應(yīng)用的到。RabbitMQ解決方案中有普通的集群和可用性更高的mirror queue方式。 kafka采用zookeeper對集群中的broker、consumer進行管理,可以注冊topic到zookeeper上;通過zookeeper的協(xié)調(diào)機制,producer保存對應(yīng)topic的broker信息,可以隨機或者輪詢發(fā)送到broker上;并且producer可以基于語義指定分片,消息發(fā)送到broker的某分片上。

總體來講,RabbitMQ用在實時的對可靠性要求比較高的消息傳遞上。kafka主要用于處理活躍的流式數(shù)據(jù),大數(shù)據(jù)量的數(shù)據(jù)處理上。

Cache&Buffer

Cache系統(tǒng)

在一些高并發(fā)高性能的場景中,使用cache可以減少對后端系統(tǒng)的負(fù)載,承擔(dān)可大部分讀的壓力,可以大大提高系統(tǒng)的吞吐量,比如通常在數(shù)據(jù)庫存儲之前增加cache緩存。

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

Cache中的數(shù)據(jù)相對于存儲來講,畢竟是有限的,比較理想的情況是存儲系統(tǒng)的熱點數(shù)據(jù),這里可以用一些常見的算法LRU等等淘汰老的數(shù)據(jù);隨著系統(tǒng)規(guī)模的增加,單個節(jié)點cache不能滿足要求,就需要搭建分布式Cache;為了解決單個節(jié)點失效引起的抖動 ,分布式cache一般采用一致性hash的解決方案,大大減少因單個節(jié)點失效引起的抖動范圍;而對于可用性要求比較高的場景,每個節(jié)點都是需要有備份的。數(shù)據(jù)在cache和存儲上都存有同一份備份,必然有一致性的問題,一致性比較強的,在更新數(shù)據(jù)庫的同時,更新數(shù)據(jù)庫cache。對于一致性要求不高的,可以去設(shè)置緩存失效時間的策略。

Memcached作為高速的分布式緩存服務(wù)器,協(xié)議比較簡單,基于libevent的事件處理機制。

Cache系統(tǒng)在平臺中用在router系統(tǒng)的客戶端中,熱點的數(shù)據(jù)會緩存在客戶端,當(dāng)數(shù)據(jù)訪問失效時,才去訪問router系統(tǒng)。

當(dāng)然目前更多的利用內(nèi)存型的數(shù)據(jù)庫做cache,比如redis、mongodb;redis比memcache有豐富的數(shù)據(jù)操作的API;redis和mongodb都對數(shù)據(jù)進行了持久化,而memcache沒有這個功能,因此memcache更加適合在關(guān)系型數(shù)據(jù)庫之上的數(shù)據(jù)的緩存。

Buffer系統(tǒng)

用在高速的寫操作的場景中,平臺中有些數(shù)據(jù)需要寫入數(shù)據(jù)庫,并且數(shù)據(jù)是分庫分表的,但對數(shù)據(jù)的可靠性不是那么高,為了減少對數(shù)據(jù)庫的寫壓力,可以采取批量寫操作的方式。

開辟一個內(nèi)存區(qū)域,當(dāng)數(shù)據(jù)到達區(qū)域的一定閥值時如80%時,在內(nèi)存中做分庫梳理工作(內(nèi)存速度還是比較快的),后分庫批量flush。

搜索

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

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

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

b、 索引的實時性

c、 性能

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

從Solr4版本開始提供了SolrCloud方式來支持分布式的索引,自動進行sharding數(shù)據(jù)切分;通過每個sharding的master-slave(leader、replica)模式提高搜索的性能;利用zookeeper對集群進行管理,包括leader選舉等等,保障集群的可用性。

Lucene索引的Reader是基于索引的snapshot的,所以必須在索引commit的后,重新打開一個新的snapshot,才能搜索到新添加的內(nèi)容;而索引的commit是非常耗性能的,這樣達到實時索引搜索效率就比較低下。

對于索引搜索實時性,Solr4的之前解決方案是結(jié)合文件全量索引和內(nèi)存增量索引合并的方式,參見下圖。

搜索

Solr4提供了NRT softcommit的解決方案,softcommit無需進行提交索引操作,就可以搜素到最新對索引的變更,不過對索引的變更并沒有sync commit到硬盤存儲上,若發(fā)生意外導(dǎo)致程序非正常結(jié)束,未commit的數(shù)據(jù)會丟失,因此需要定時的進行commit操作。

平臺中對數(shù)據(jù)的索引和存儲操作是異步的,可以大大提高可用性和吞吐量;只對某些屬性字段做索引操作,存儲數(shù)據(jù)的標(biāo)識key,減少索引的大;數(shù)據(jù)是存儲在分布式存儲HBase 中的,HBase對二級索引搜索支持的不好,然而可以結(jié)合Solr搜索功能進行多維度的檢索統(tǒng)計。

索引數(shù)據(jù)和HBase數(shù)據(jù)存儲的一致性,也就是如何保障HBase存儲的數(shù)據(jù)都被索引過,可以采用confirm確認(rèn)機制,通過在索引前建立待索引數(shù)據(jù)隊列,在數(shù)據(jù)存儲并索引完成后,從待索引數(shù)據(jù)隊列中刪除數(shù)據(jù)。

日志收集

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

日志系統(tǒng)需具備三個基本組件,分別為agent(封裝數(shù)據(jù)源,將數(shù)據(jù)源中的數(shù)據(jù)發(fā)送給collector),collector(接收多個agent的數(shù)據(jù),并進行匯總后導(dǎo)入后端的store中),store(中央存儲系統(tǒng),應(yīng)該具有可擴展性和可靠性,應(yīng)該支持當(dāng)前非常流行的HDFS)。

開源的日志收集系統(tǒng)業(yè)界使用的比較多的是cloudera的Flume和facebook的Scribe,其中Flume目前的版本FlumeNG對Flume從架構(gòu)上做了較大的改動。

在設(shè)計或者對日志收集系統(tǒng)做技術(shù)選型時,通常需要具有以下特征:

a、 應(yīng)用系統(tǒng)和分析系統(tǒng)之間的橋梁,將他們之間的關(guān)系解耦

b、 分布式可擴展,具有高的擴展性,當(dāng)數(shù)據(jù)量增加時,可以通過增加節(jié)點水平擴展

日志收集系統(tǒng)是可以伸縮的,在系統(tǒng)的各個層次都可伸縮,對數(shù)據(jù)的處理不需要帶狀態(tài),伸縮性方面也比較容易實現(xiàn)。

c、 近實時性

在一些時效性要求比較高的場景中,需要可以及時的收集日志,進行數(shù)據(jù)分析;

一般的日志文件都會定時或者定量的進行rolling,所以實時檢測日志文件的生成,及時對日志文件進行類似的tail操作,并支持批量發(fā)送提高傳輸效率;批量發(fā)送的時機需要滿足消息數(shù)量和時間間隔的要求。

d、 容錯性

Scribe在容錯方面的考慮是,當(dāng)后端的存儲系統(tǒng)crash時,scribe會將數(shù)據(jù)寫到本地磁盤上,當(dāng)存儲系統(tǒng)恢復(fù)正常后,scribe將日志重新加載到存儲系統(tǒng)中。

FlumeNG通過Sink Processor實現(xiàn)負(fù)載均衡和故障轉(zhuǎn)移。多個Sink可以構(gòu)成一個Sink Group。一個Sink Processor負(fù)責(zé)從一個指定的Sink Group中激活一個Sink。Sink Processor可以通過組中所有Sink實現(xiàn)負(fù)載均衡;也可以在一個Sink失敗時轉(zhuǎn)移到另一個。

e、 事務(wù)支持

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

Flume通過應(yīng)答確認(rèn)機制實現(xiàn)事務(wù)的支持,參見下圖:

日志搜集

通常提取發(fā)送消息都是批量操作的,消息的確認(rèn)是對一批數(shù)據(jù)的確認(rèn),這樣可以大大提高數(shù)據(jù)發(fā)送的效率。

f、 可恢復(fù)性

FlumeNG的channel根據(jù)可靠性的要求的不同,可以基于內(nèi)存和文件持久化機制,基于內(nèi)存的數(shù)據(jù)傳輸?shù)匿N量比較高,但是在節(jié)點宕機后,數(shù)據(jù)丟失,不可恢復(fù);而文件持久化宕機是可以恢復(fù)的。

g、 數(shù)據(jù)的定時定量歸檔

數(shù)據(jù)經(jīng)過日志收集系統(tǒng)歸集后,一般存儲在分布式文件系統(tǒng)如Hadoop,為了便于對數(shù)據(jù)進行后續(xù)的處理分析,需要定時(TimeTrigger)或者定量(SizeTrigger的rolling分布式系統(tǒng)的文件。

數(shù)據(jù)同步

在交易系統(tǒng)中,通常需要進行異構(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è)計中需要綜合考慮吞吐量、容錯性、可靠性、一致性的問題

同步有實時增量數(shù)據(jù)同步和離線全量數(shù)據(jù)區(qū)分,下面從這兩個維度來介紹一下,

實時增量一般是Tail文件來實時跟蹤文件變化,批量或者多線程往數(shù)據(jù)庫導(dǎo)出,這種方式的架構(gòu)類似于日志收集框架。這種方式需要有確認(rèn)機制,包括兩個方面。

一個方面是Channel需要給agent確認(rèn)已經(jīng)批量收到數(shù)據(jù)記錄了,發(fā)送LSN號給agent,這樣在agent失效恢復(fù)時,可以從這個LSN點開始tail;當(dāng)然對于允許少量的重復(fù)記錄的問題(發(fā)生在channel給agent確認(rèn)的時,agent宕機并未受到確認(rèn)消息),需要在業(yè)務(wù)場景中判斷。

另外一個方面是sync給channel確認(rèn)已經(jīng)批量完成寫入到數(shù)據(jù)庫的操作,這樣channel可以刪除這部分已經(jīng)confirm的消息。

基于可靠性的要求,channel可以采用文件持久化的方式。

參見下圖

數(shù)據(jù)同步

離線全量遵循空間間換取時間,分而治之的原則,盡量的縮短數(shù)據(jù)同步的時間,提高同步的效率。

需要對源數(shù)據(jù)比如mysql進行切分,多線程并發(fā)讀源數(shù)據(jù),多線程并發(fā)批量寫入分布式數(shù)據(jù)庫比如HBase,利用channel作為讀寫之間的緩沖,實現(xiàn)更好的解耦,channel可以基于文件存儲或者內(nèi)存。參見下圖:

數(shù)據(jù)同步

對于源數(shù)據(jù)的切分,如果是文件可以根據(jù)文件名稱設(shè)置塊大小來切分。

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

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

從傳統(tǒng)的基于關(guān)系型數(shù)據(jù)庫并行處理集群、用于內(nèi)存計算近實時的,到目前的基于hadoop的海量數(shù)據(jù)的分析,數(shù)據(jù)的分析在大型電子商務(wù)網(wǎng)站中應(yīng)用非常廣泛,包括流量統(tǒng)計、推薦引擎、趨勢分析、用戶行為分析、數(shù)據(jù)挖掘分類器、分布式索引等等。

并行處理集群有商業(yè)的EMC Greenplum,Greenplum的架構(gòu)采用了MPP(大規(guī)模并行處理),基于postgresql的大數(shù)據(jù)量存儲的分布式數(shù)據(jù)庫。

內(nèi)存計算方面有SAP的HANA,開源的nosql內(nèi)存型的數(shù)據(jù)庫mongodb也支持mapreduce進行數(shù)據(jù)的分析。

海量數(shù)據(jù)的離線分析目前互聯(lián)網(wǎng)公司大量的使用Hadoop,Hadoop在可伸縮性、健壯性、計算性能和成本上具有無可替代的優(yōu)勢,事實上已成為當(dāng)前互聯(lián)網(wǎng)企業(yè)主流的大數(shù)據(jù)分析平臺

Hadoop通過MapReuce的分布式處理框架,用于處理大規(guī)模的數(shù)據(jù),伸縮性也非常好;但是MapReduce最大的不足是不能滿足實時性的場景,主要用于離線的分析。

基于MapRduce模型編程做數(shù)據(jù)的分析,開發(fā)上效率不高,位于hadoop之上Hive的出現(xiàn)使得數(shù)據(jù)的分析可以類似編寫sql的方式進行,sql經(jīng)過語法分析、生成執(zhí)行計劃后最終生成MapReduce任務(wù)進行執(zhí)行,這樣大大提高了開發(fā)的效率,做到以ad-hoc(計算在query發(fā)生時)方式進行的分析。

基于MapReduce模型的分布式數(shù)據(jù)的分析都是離線的分析,執(zhí)行上都是暴力掃描,無法利用類似索引的機制;開源的Cloudera Impala是基于MPP的并行編程模型的,底層是Hadoop存儲的高性能的實時分析平臺,可以大大降低數(shù)據(jù)分析的延遲。

目前Hadoop使用的版本是Hadoop1.0,一方面原有的MapReduce框架存在JobTracker單點的問題,另外一方面JobTracker在做資源管理的同時又做任務(wù)的調(diào)度工作,隨著數(shù)據(jù)量的增大和Job任務(wù)的增多,明顯存在可擴展性、內(nèi)存消耗、線程模型、可靠性和性能上的缺陷瓶頸;Hadoop2.0 yarn對整個框架進行了重構(gòu),分離了資源管理和任務(wù)調(diào)度,從架構(gòu)設(shè)計上解決了這個問題。

實時計算

在互聯(lián)網(wǎng)領(lǐng)域,實時計算被廣泛實時監(jiān)控分析、流控、風(fēng)險控制等領(lǐng)域。電商平臺系統(tǒng)或者應(yīng)用對日常產(chǎn)生的大量日志和異常信息,需要經(jīng)過實時過濾、分析,以判定是否需要預(yù)警;

同時需要對系統(tǒng)做自我保護機制,比如對模塊做流量的控制,以防止非預(yù)期的對系統(tǒng)壓力過大而引起的系統(tǒng)癱瘓,流量過大時,可以采取拒絕或者引流等機制;有些業(yè)務(wù)需要進行風(fēng)險的控制,比如彩票中有些業(yè)務(wù)需要根據(jù)系統(tǒng)的實時銷售情況進行限號與放號。

原始基于單節(jié)點的計算,隨著系統(tǒng)信息量爆炸式產(chǎn)生以及計算的復(fù)雜度的增加,單個節(jié)點的計算已不能滿足實時計算的要求,需要進行多節(jié)點的分布式的計算,分布式實時計算平臺就出現(xiàn)了。

這里所說的實時計算,其實是流式計算,概念前身其實是CEP復(fù)雜事件處理,相關(guān)的開源產(chǎn)品如Esper,業(yè)界分布式的流計算產(chǎn)品Yahoo S4,Twitter storm等,以storm開源產(chǎn)品使用最為廣泛。

對于實時計算平臺,從架構(gòu)設(shè)計上需要考慮以下幾個因素:

  • 伸縮性:隨著業(yè)務(wù)量的增加,計算量的增加,通過增加節(jié)點處理,就可以處理。
  • 高性能、低延遲:從數(shù)據(jù)流入計算平臺數(shù)據(jù),到計算輸出結(jié)果,需要性能高效且低延遲,保證消息得到快速的處理,做到實時計算。
  • 可靠性:保證每個數(shù)據(jù)消息得到一次完整處理。
  • 容錯性:系統(tǒng)可以自動管理節(jié)點的宕機失效,對應(yīng)用來說,是透明的。

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

Storm的架構(gòu)

整個集群的管理是通過zookeeper來進行的。

客戶端提交拓?fù)涞絥imbus。

Nimbus針對該拓?fù)浣⒈镜氐哪夸浉鶕?jù)topology的配置計算task,分配task,在zookeeper上建立assignments節(jié)點存儲task和supervisor機器節(jié)點中woker的對應(yīng)關(guān)系。

在zookeeper上創(chuàng)建taskbeats節(jié)點來監(jiān)控task的心跳;啟動topology。

Supervisor去zookeeper上獲取分配的tasks,啟動多個woker進行,每個woker生成task,一個task一個線程;根據(jù)topology信息初始化建立task之間的連接;Task和Task之間是通過zeroMQ管理的;之后整個拓?fù)溥\行起來。

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

發(fā)送Tuple,Worker提供了一個transfer的功能,用于當(dāng)前task把tuple發(fā)到到其他的task中。以目的taskid和tuple參數(shù),序列化tuple數(shù)據(jù)并放到transfer queue中。

在0.8版本之前,這個queue是LinkedBlockingQueue,0.8之后是DisruptorQueue。

在0.8版本之后,每一個woker綁定一個inbound transfer queue和outbond queue,inbound queue用于接收message,outbond queue用于發(fā)送消息。

發(fā)送消息時,由單個線程從transferqueue中拉取數(shù)據(jù),把這個tuple通過zeroMQ發(fā)送到其他的woker中。

接收Tuple,每個woker都會監(jiān)聽zeroMQ的tcp端口來接收消息,消息放到DisruptorQueue中后,后從queue中獲取message(taskid,tuple),根據(jù)目的taskid,tuple的值路由到task中執(zhí)行。每個tuple可以emit到direct steam中,也可以發(fā)送到regular stream中,在Reglular方式下,由Stream Group(stream id–>component id –>outbond tasks)功能完成當(dāng)前tuple將要發(fā)送的Tuple的目的地。

通過以上分析可以看到,Storm在伸縮性、容錯性、高性能方面的從架構(gòu)設(shè)計的角度得以支撐;同時在可靠性方面,Storm的ack組件利用異或xor算法在不失性能的同時,保證每一個消息得到完整處理的同時。

實時推送

實時推送的應(yīng)用場景非常多,比如系統(tǒng)的監(jiān)控動態(tài)的實時曲線繪制,手機消息的推送,web實時聊天等。

實時推送有很多技術(shù)可以實現(xiàn),有Comet方式,有websocket方式等。

Comet基于服務(wù)器長連接的“服務(wù)器推”技術(shù),包含兩種:

Long Polling:服務(wù)器端在接到請求后掛起,有更新時返回連接即斷掉,然后客戶端再發(fā)起新的連接

Stream方式: 每次服務(wù)端數(shù)據(jù)傳送不會關(guān)閉連接,連接只會在通信出現(xiàn)錯誤時,或是連接重建時關(guān)閉(一些防火墻常被設(shè)置為丟棄過長的連接, 服務(wù)器端可以設(shè)置一個超時時間, 超時后通知客戶端重新建立連接,并關(guān)閉原來的連接)。

Websocket:長連接,全雙工通信

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

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

數(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)系型、分布式三個維度針對相關(guān)的產(chǎn)品做性能可用性等方面的考量分析。

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

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

? MongoDB

通信方式:

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

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

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

數(shù)據(jù)庫–>collection–>record

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

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

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

每一行數(shù)據(jù)存儲空間不僅包括數(shù)據(jù)占用空間,還可能包含一部分附加空間,這使得在數(shù)據(jù)update變大后可以不移動位置。

索引以BTree結(jié)構(gòu)實現(xiàn)。

如果你開啟了jorunaling日志,那么還會有一些文件存儲著你所有的操作記錄。

持久化存儲:

MMap方式把文件地址映射到內(nèi)存的地址空間,直接操作內(nèi)存地址空間就可以操作文件,不用再調(diào)用write,read操作,性能比較高。

mongodb調(diào)用mmap把磁盤中的數(shù)據(jù)映射到內(nèi)存中的,所以必須有一個機制時刻的刷數(shù)據(jù)到硬盤才能保證可靠性,多久刷一次是與syncdelay參數(shù)相關(guān)的。

journal(進行恢復(fù)用)是Mongodb中的redo log,而Oplog則是負(fù)責(zé)復(fù)制的binlog。如果打開journal,那么即使斷電也只會丟失100ms的數(shù)據(jù),這對大多數(shù)應(yīng)用來說都可以容忍了。從1.9.2+,mongodb都會默認(rèn)打開journal功能,以確保數(shù)據(jù)安全。而且journal的刷新時間是可以改變的,2-300ms的范圍,使用 –journalCommitInterval 命令。Oplog和數(shù)據(jù)刷新到磁盤的時間是60s,對于復(fù)制來說,不用等到oplog刷新磁盤,在內(nèi)存中就可以直接復(fù)制到Sencondary節(jié)點。

事務(wù)支持:

Mongodb只支持對單行記錄的原子操作

HA集群:

用的比較多的是Replica Sets,采用選舉算法,自動進行l(wèi)eader選舉,在保證可用性的同時,可以做到強一致性要求。

HA集群

當(dāng)然對于大量的數(shù)據(jù),mongodb也提供了數(shù)據(jù)的切分架構(gòu)Sharding。

? Redis

豐富的數(shù)據(jù)結(jié)構(gòu),高速的響應(yīng)速度,內(nèi)存操作

通信方式:

因都在內(nèi)存操作,所以邏輯的操作非?,減少了CPU的切換開銷,所以為單線程的模式(邏輯處理線程和主線程是一個)。

reactor模式,實現(xiàn)自己的多路復(fù)用NIO機制(epoll,select,kqueue等)

單線程處理多任務(wù)

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

hash+bucket結(jié)構(gòu),當(dāng)鏈表的長度過長時,會采取遷移的措施(擴展原來兩倍的hash表,把數(shù)據(jù)遷移過去,expand+rehash)

持久化存儲:

a、全量持久化RDB(遍歷redisDB,讀取bucket中的key,value),save命令阻塞主線程,bgsave開啟子進程進行snapshot持久化操作,生成rdb文件。

在shutdown時,會調(diào)用save操作

數(shù)據(jù)發(fā)生變化,在多少秒內(nèi)觸發(fā)一次bgsave

sync,master接受slave發(fā)出來的命令

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

要定時對aof文件和rdb文件做合并操作(在快照過程中,變化的數(shù)據(jù)先寫到aof buf中等子進程完成快照<內(nèi)存snapshot>后,再進行合并aofbuf變化的部分以及全鏡像數(shù)據(jù))。

在高并發(fā)訪問模式下,RDB模式使服務(wù)的性能指標(biāo)出現(xiàn)明顯的抖動,aof在性能開銷上比RDB好,但是恢復(fù)時重新加載到內(nèi)存的時間和數(shù)據(jù)量成正比。

集群HA:

通用的解決方案是主從備份切換,采用HA軟件,使得失效的主redis可以快速的切換到從redis上。主從數(shù)據(jù)的同步采用復(fù)制機制,該場景可以做讀寫分離。

目前在復(fù)制方面,存在的一個問題是在遇到網(wǎng)絡(luò)不穩(wěn)定的情況下,Slave和Master斷開(包括閃斷)會導(dǎo)致Master需要將內(nèi)存中的數(shù)據(jù)全部重新生成rdb文件(快照文件),然后傳輸給Slave。Slave接收完Master傳遞過來的rdb文件以后會將自身的內(nèi)存清空,把rdb文件重新加載到內(nèi)存中。這種方式效率比較低下,在后面的未來版本Redis2.8作者已經(jīng)實現(xiàn)了部分復(fù)制的功能。

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

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

? 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)介紹。

InnoDB存儲引擎

在線程處理方面,Mysql是多線程的架構(gòu),由一個master線程,一個鎖監(jiān)控線程,一個錯誤監(jiān)控線程,和多個IO線程組成。并且對一個連接會開啟一個線程進行服務(wù)。io線程又分為節(jié)省隨機IO的insert buffer,用于事務(wù)控制的類似于oracle的redo log,以及多個write,多個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é)點是主鍵PK,根據(jù)主鍵索引的葉子節(jié)點指向存儲的數(shù)據(jù)塊。這種B+樹存儲結(jié)構(gòu)可以更好的滿足隨機查詢操作IO要求,分為數(shù)據(jù)頁和二級索引頁,修改二級索引頁面涉及到隨機操作,為了提高寫入時的性能,采用insert buffer做順序的寫入,再由后臺線程以一定頻率將多個插入合并到二級索引頁面。為了保證數(shù)據(jù)庫的一致性(內(nèi)存和硬盤數(shù)據(jù)文件),以及縮短實例恢復(fù)的時間,關(guān)系型數(shù)據(jù)庫還有一個checkpoint的功能,用于把內(nèi)存buffer中之前的臟頁按照比例(老的LSN)寫入磁盤,這樣redolog文件的LSN以前的日志就可以被覆蓋了,進行循環(huán)使用;在失效恢復(fù)時,只需要從日志中LSN點進行恢復(fù)即可。

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

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

? 對于高并發(fā)高性能的mysql來講,可以在多個維度進行性能方面的調(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方面,單實例關(guān)閉NUMA,mysql對多核的支持不是太好,可以對多實例進行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機制。需要考慮的內(nèi)容有,

在保證系統(tǒng)可用內(nèi)存的基礎(chǔ)上,盡可能的擴大innodb buffer pool,一般設(shè)置為物理內(nèi)存的3/4

文件系統(tǒng)的使用,只在記錄事務(wù)日志的時候用文件系統(tǒng)的cache;盡量避免mysql用到swap(可以將vm.swappiness=0,內(nèi)存緊張時,釋放文件系統(tǒng)cache)

IO調(diào)度優(yōu)化,減少不必要的阻塞,降低隨機IO訪問的延時(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)存問題,減少鎖的范圍,減少回表掃描,覆蓋索引)

? 在高可用實踐方面,

支持master-master、master-slave模式,master-master模式是一個作為主負(fù)責(zé)讀寫,另外一個作為standby提供災(zāi)備,maser-slave是一個作為主提供寫操作,其他幾個節(jié)點作為讀操作,支持讀寫分離。

對于節(jié)點主備失效檢測和切換,可以采用HA軟件,當(dāng)然也可以從更細(xì)粒度定制的角度,采用zookeeper作為集群的協(xié)調(diào)服務(wù)。

對于分布式的系統(tǒng)來講,數(shù)據(jù)庫主備切換的一致性始終是一個問題,可以有以下幾種方式:

a、集群方式,如oracle的rack,缺點是比較復(fù)雜

b、共享SAN存儲方式,相關(guān)的數(shù)據(jù)文件和日志文件都放在共享存儲上,優(yōu)點是主備切換時數(shù)據(jù)保持一致,不會丟失,但由于備機有一段時間的拉起,會有短暫的不可用狀態(tài)

c、主備進行數(shù)據(jù)同步的方式,常見的是日志的同步,可以保障熱備,實時性好,但是切換時,可能有部分?jǐn)?shù)據(jù)沒有同步過來,帶來了數(shù)據(jù)的一致性問題?梢栽诓僮髦鲾(shù)據(jù)庫的同時,記錄操作日志,切換到備時,會和操作日志做個check,補齊未同步過來的數(shù)據(jù);

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

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

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

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

在硬件存儲方面,對于事務(wù)日志因是順序?qū),閃存的優(yōu)勢比硬盤高不了多少,所以采取電池保護的寫緩存的raid卡存儲;對于數(shù)據(jù)文件,無論是對用戶或者訂單都會存在大量的隨機讀寫操作,當(dāng)然加大內(nèi)存是一個方面,另外可以采用高速的IO設(shè)備閃存,比如PCIe卡 fusion-io。使用閃存也適合在單線程的負(fù)載中,比如主從復(fù)制,可以對從節(jié)點配置fusion-IO卡,降低復(fù)制的延遲。

對于訂單業(yè)務(wù)來講,量是不斷遞增的,PCIe卡存儲容量比較有限,并且訂單業(yè)務(wù)的熱數(shù)據(jù)只有最近一段時間的(比如近3個月的),對此這里列兩種解決方案,一種是flashcache方式,采用基于閃存和硬盤存儲的開源混合存儲方式,在閃存中存儲熱點的數(shù)據(jù)。另外一種是可以定期把老的數(shù)據(jù)導(dǎo)出到分布式數(shù)據(jù)庫HBase中,用戶在查詢訂單列表是近期的數(shù)據(jù)從mysql中獲取,老的數(shù)據(jù)可以從HBase中查詢,當(dāng)然需要HBase良好的rowkey設(shè)計以適應(yīng)查詢需求。

分布式數(shù)據(jù)庫

對于數(shù)據(jù)的高并發(fā)的訪問,傳統(tǒng)的關(guān)系型數(shù)據(jù)庫提供讀寫分離的方案,但是帶來的確實數(shù)據(jù)的一致性問題提供的數(shù)據(jù)切分的方案;對于越來越多的海量數(shù)據(jù),傳統(tǒng)的數(shù)據(jù)庫采用的是分庫分表,實現(xiàn)起來比較復(fù)雜,后期要不斷的進行遷移維護;對于高可用和伸縮方面,傳統(tǒng)數(shù)據(jù)采用的是主備、主從、多主的方案,但是本身擴展性比較差,增加節(jié)點和宕機需要進行數(shù)據(jù)的遷移。對于以上提出的這些問題,分布式數(shù)據(jù)庫HBase有一套完善的解決方案,適用于高并發(fā)海量數(shù)據(jù)存取的要求。

? HBase

  • 基于列式的高效存儲降低IO
  • 通常的查詢不需要一行的全部字段,大多數(shù)只需要幾個字段
  • 對與面向行的存儲系統(tǒng),每次查詢都會全部數(shù)據(jù)取出,然后再從中選出需要的字段
  • 面向列的存儲系統(tǒng)可以單獨查詢某一列,從而大大降低IO
  • 提高壓縮效率
  • 同列數(shù)據(jù)具有很高的相似性,會增加壓縮效率
  • Hbase的很多特性,都是由列存儲決定的

HBase

強一致的數(shù)據(jù)訪問:

MVCC

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

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

只有更新了MVCC,才算真正memstore寫成功,其中事務(wù)的隔離需要有mvcc的來控制,比如讀數(shù)據(jù)不可以獲取別的線程還未提交的數(shù)據(jù)。

高可靠:

HBase的數(shù)據(jù)存儲基于HDFS,提供了冗余機制。

Region節(jié)點的宕機,對于內(nèi)存中的數(shù)據(jù)還未flush到文件中,提供了可靠的恢復(fù)機制。

Region節(jié)點恢復(fù)機制

可伸縮,自動切分,遷移:

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

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

可用性:

存在單點故障,Region Server宕機后,短時間內(nèi)該server維護的region無法訪問,等待failover生效。

通過Master維護各Region Server健康狀況和Region分布。

多個Master,Master宕機有zookeeper的paxos投票機制選取下一任Master。Master就算全宕機,也不影響Region讀寫。Master僅充當(dāng)一個自動運維角色。

HDFS為分布式存儲引擎,一備三,高可靠,0數(shù)據(jù)丟失。

HDFS的namenode是一個SPOF。

為避免單個region訪問過于頻繁,單機壓力過大,提供了split機制

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

Schema free:

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

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

管理與部署配置

統(tǒng)一的配置庫

部署平臺

監(jiān)控、統(tǒng)計

大型分布式系統(tǒng)涉及各種設(shè)備,比如網(wǎng)絡(luò)交換機,普通PC機,各種型號的網(wǎng)卡,硬盤,內(nèi)存等等,還有應(yīng)用業(yè)務(wù)層次的監(jiān)控,數(shù)量非常多的時候,出現(xiàn)錯誤的概率也會變大,并且有些監(jiān)控的時效性要求比較高,有些達到秒級別;在大量的數(shù)據(jù)流中需要過濾異常的數(shù)據(jù),有時候也對數(shù)據(jù)會進行上下文相關(guān)的復(fù)雜計算,進而決定是否需要告警。因此監(jiān)控平臺的性能、吞吐量、已經(jīng)可用性就比較重要,需要規(guī)劃統(tǒng)一的一體化的監(jiān)控平臺對系統(tǒng)進行各個層次的監(jiān)控。

平臺的數(shù)據(jù)分類

應(yīng)用業(yè)務(wù)級別:應(yīng)用事件、業(yè)務(wù)日志、審計日志、請求日志、異常、請求業(yè)務(wù)metrics、性能度量

系統(tǒng)級別:CPU、內(nèi)存、網(wǎng)絡(luò)、IO

時效性要求

  • 閥值,告警
  • 實時計算
  • 近實時分鐘計算
  • 按小時、天的離線分析
  • 實時查詢

架構(gòu)

節(jié)點中Agent代理可以接收日志、應(yīng)用的事件以及通過探針的方式采集數(shù)據(jù),agent采集數(shù)據(jù)的一個原則是和業(yè)務(wù)應(yīng)用的流程是異步隔離的,不影響交易流程。

數(shù)據(jù)統(tǒng)一通過collector集群進行收集,按照數(shù)據(jù)的不同類型分發(fā)到不同的計算集群進行處理;有些數(shù)據(jù)時效性不是那么高,比如按小時進行統(tǒng)計,放入hadoop集群;有些數(shù)據(jù)是請求流轉(zhuǎn)的跟蹤數(shù)據(jù),需要可以查詢的,那么就可以放入solr集群進行索引;有些數(shù)據(jù)需要進行實時計算的進而告警的,需要放到storm集群中進行處理。

數(shù)據(jù)經(jīng)過計算集群處理后,結(jié)果存儲到Mysql或者HBase中。

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

監(jiān)控統(tǒng)計

標(biāo)簽: dns linux Mysql ssd swap web服務(wù)器 安全 大數(shù)據(jù) 大數(shù)據(jù)分析 大數(shù)據(jù)分析平臺 電商 電商平臺 電商平臺系統(tǒng) 電子商務(wù) 電子商務(wù)平臺 

版權(quán)申明:本站文章部分自網(wǎng)絡(luò),如有侵權(quán),請聯(lián)系:west999com@outlook.com
特別注意:本站所有轉(zhuǎn)載文章言論不代表本站觀點!
本站所提供的圖片等素材,版權(quán)歸原作者所有,如需使用,請與原作者聯(lián)系。

上一篇:如果沒有 Android 世界會是什么樣子?

下一篇:深入探討Java中的異常與錯誤處理