客戶端頁面緩存(http header中包含Expires/Cache of Control,last modified(304,server不返回body,客戶端能夠繼續用cache,減小流量),ETag)前端
反向代理緩存node
應用端的緩存(memcache)nginx
內存數據庫web
Buffer、cache機制(數據庫,中間件等)redis
哈希、B樹、倒排、bitmap算法
哈希索引適合綜合數組的尋址和鏈表的插入特性,能夠實現數據的快速存取。sql
B樹索引適合於查詢爲主導的場景,避免屢次的IO,提升查詢的效率。mongodb
倒排索引實現單詞到文檔映射關係的最佳實現方式和最有效的索引結構,普遍用在搜索領域。數據庫
Bitmap是一種很是簡潔快速的數據結構,他能同時使存儲空間和速度最優化(而沒必要空間換時間),適合於海量數據的的計算場景。npm
在大規模的數據中,數據存在必定的局部性的特徵,利用局部性的原理將海量數據計算的問題分而治之。
MR模型是無共享的架構,數據集分佈至各個節點。處理時,每一個節點就近讀取本地存儲的數據處理(map),將處理後的數據進行合併(combine)、排序(shuffle and sort)後再分發(至reduce節點),避免了大量數據的傳輸,提升了處理效率。
並行計算(Parallel Computing)是指同時使用多種計算資源解決計算問題的過程,是提升計算機系統計算速度和處理能力的一種有效手段。它的基本思想是用多個處理器/進程/線程來協同求解同一問題,即將被求解的問題分解成若干個部分,各部分均由一個獨立的處理機來並行計算。
和MR的區別在於,它是基於問題分解的,而不是基於數據分解。
隨 着平臺併發量的增大,須要擴容節點進行集羣,利用負載均衡設備進行請求的分發;負載均衡設備一般在提供負載均衡的同時,也提供失效檢測功能;同時爲了提升 可用性,須要有容災備份,以防止節點宕機失效帶來的不可用問題;備份有在線的和離線備份,能夠根據失效性要求的不一樣,進行選擇不一樣的備份策略。
讀寫分離是對數據庫來說的,隨着系統併發量的增大,提升數據訪問可用性的一個重要手段就是寫數據和讀數據進行分離;固然在讀寫分離的同時,須要關注數據的一致性問題;對於一致性的問題,在分佈式的系統CAP定量中,更多的關注於可用性。
平臺中各個模塊之間的關係儘可能是低耦合的,能夠經過相關的消息組件進行交互,能異步則異步,分清楚數據流轉的主流程和副流程,主副是異步的,好比記錄日誌能夠是異步操做的,增長整個系統的可用性。
固然在異步處理中,爲了確保數據獲得接收或者處理,每每須要確認機制(confirm、ack)。
可是有些場景中,雖然請求已經獲得處理,可是因其餘緣由(好比網絡不穩定),確認消息沒有返回,那麼這種狀況下須要進行請求的重發,對請求的處理設計因重發因素須要考慮冪等性。
監控也是提升整個平臺可用性的一個重要手段,多平臺進行多個維度的監控;模塊在運行時候是透明的,以達到運行期白盒化。
拆分包括對業務的拆分和對數據庫的拆分。
系統的資源老是有限的,一段比較長的業務執行若是是一竿子執行的方式,在大量併發的操做下,這種阻塞的方式,沒法有效的及時釋放資源給其餘進程執行,這樣系統的吞吐量不高。
須要把業務進行邏輯的分段,採用異步非阻塞的方式,提升系統的吞吐量。
隨着數據量和併發量的增長,讀寫分離不能知足系統併發性能的要求,須要對數據進行切分,包括對數據進行分庫和分表。這種分庫分表的方式,須要增長對數據的路由邏輯支持。
對於系統的伸縮性而言,模塊最好是無狀態的,經過增長節點就能夠提升整個的吞吐量。
系統的容量是有限的,承受的併發量也是有限的,在架構設計時,必定須要考慮流量的控制,防止因意外攻擊或者瞬時併發量的衝擊致使系統崩潰。在設計時增長流控的措施,可考慮對請求進行排隊,超出預期的範圍,能夠進行告警或者丟棄。
對於共享資源的訪問,爲了防止衝突,須要進行併發的控制,同時有些交易須要有事務性來保證交易的一致性,因此在交易系統的設計時,需考慮原子操做和併發控制。
保證併發控制一些經常使用高性能手段有,樂觀鎖、Latch、mutex、寫時複製、CAS等;多版本的併發控制MVCC一般是保證一致性的重要手段,這個在數據庫的設計中常常會用到。
平臺中業務邏輯存在不一樣的類型,有計算複雜型的,有消耗IO型的,同時就同一種類型而言,不一樣的業務邏輯消耗的資源數量也是不同的,這就須要針對不一樣的邏輯採起不一樣的策略。
針對IO型的,能夠採起基於事件驅動的異步非阻塞的方式,單線程方式能夠減小線程的切換引發的開銷,或者在多線程的狀況下采起自旋spin的方式,減小對線程的切換(好比oracle latch設計);對於計算型的,充分利用多線程進行操做。
同一類型的調用方式,不一樣的業務進行合適的資源分配,設置不一樣的計算節點數量或者線程數量,對業務進行分流,優先執行優先級別高的業務。
系統的有些業務模塊在出現錯誤時,爲了減小併發下對正常請求的處理的影響,有時候須要考慮對這些異常狀態的請求進行單獨渠道的處理,甚至暫時自動禁止這些異常的業務模塊。
有些請求的失敗多是偶然的暫時的失敗(好比網絡不穩定),須要進行請求重試的考慮。
系統的資源是有限的,在使用資源時,必定要在最後釋放資源,不管是請求走的是正常路徑仍是異常的路徑,以便於資源的及時回收,供其餘請求使用。
在設計通訊的架構時,每每須要考慮超時的控制。
整個架構是分層的分佈式的架構,縱向包括CDN,負載均衡/反向代理,web應用,業務層,基礎服務層,數據存儲層。水平方向包括對整個平臺的配置管理部署和監控。
CDN系統可以實時地根據網絡流量和各節點的鏈接、負載情況以及到用戶的距離和響應時間等綜合信息將用戶的請求從新導向離用戶最近的服務節點上。其目的是使用戶可就近取得所需內容,解決 Internet網絡擁擠的情況,提升用戶訪問網站的響應速度。
對於大規模電子商務平臺通常須要建CDN作網絡加速,大型平臺如淘寶、京東都採用自建CDN,中小型的企業能夠採用第三方CDN廠商合做,如藍汛、網宿、快網等。
固然在選擇CDN廠商時,須要考慮經營時間長短,是否有可擴充的帶寬資源、靈活的流量和帶寬選擇、穩定的節點、性價比。
一個大型的平臺包括不少個業務域,不一樣的業務域有不一樣的集羣,能夠用DNS作域名解析的分發或輪詢,DNS方式實現簡單,可是因存在cache而缺少靈活性;通常基於商用的硬件F五、NetScaler或者開源的軟負載lvs在4層作分發,固然會採用作冗餘(好比lvs+keepalived)的考慮,採起主備方式。
4層分發到業務集羣上後,會通過web服務器如nginx或者HAProxy在7層作負載均衡或者反向代理分發到集羣中的應用節點。
選擇哪一種負載,須要綜合考慮各類因素(是否知足高併發高性能,Session保持如何解決,負載均衡的算法如何,支持壓縮,緩存的內存消耗);下面基於幾種經常使用的負載均衡軟件作個介紹。
LVS,工做在4層,Linux實現的高性能高併發、可伸縮性、可靠的的負載均衡器,支持多種轉發方式(NAT、DR、IP Tunneling),其中DR模式支持經過廣域網進行負載均衡。支持雙機熱備(Keepalived或者Heartbeat)。對網絡環境的依賴性比較高。
Nginx工做在7層,事件驅動的、異步非阻塞的架構、支持多進程的高併發的負載均衡器/反向代理軟件。能夠針對域名、目錄結構、正則規則針對http作一些分流。經過端口檢測到服務器內部的故障,好比根據服務器處理網頁返回的狀態碼、超時等等,而且會把返回錯誤的請求從新提交到另外一個節點,不過其中缺點就是不支持url來檢測。對於session sticky,能夠基於ip hash的算法來實現,經過基於cookie的擴展nginx-sticky-module支持session sticky。
HAProxy支持4層和7層作負載均衡,支持session的會話保持,cookie的引導;支持後端url方式的檢測;負載均衡的算法比較豐富,有RR、權重等。
對於圖片,須要有單獨的域名,獨立或者分佈式的圖片服務器或者如mogileFS,能夠圖片服務器之上加varnish作圖片緩存。
應用層運行在jboss或者tomcat容器中,表明獨立的系統,好比前端購物、用戶自主服務、後端系統等
協議接口,HTTP、JSON
能夠採用servlet3.0,異步化servlet,提升整個系統的吞吐量
http請求通過Nginx,經過負載均衡算法分到到App的某一節點,這一層層擴容起來比較簡單。
除了利用cookie保存少許用戶部分信息外(cookie通常不能超過4K的大小),對於App接入層,保存有用戶相關的session數據,可是有些反向代理或者負載均衡不支持對session sticky支持不是很好或者對接入的可用性要求比較高(app接入節點宕機,session隨之丟失),這就須要考慮session的集中式存儲,使得App接入層無狀態化,同時系統用戶變多的時候,就能夠經過增長更多的應用節點來達到水平擴展的目的。
Session的集中式存儲,須要知足如下幾點要求:
a、高效的通信協議
b、session的分佈式緩存,支持節點的伸縮,數據的冗餘備份以及數據的遷移
c、session過時的管理
表明某一領域的業務提供的服務,對於電商而言,領域有用戶、商品、訂單、紅包、支付業務等等,不一樣的領域提供不一樣的服務,
這些不一樣的領域構成一個個模塊,良好的模塊劃分和接口設計很是重要,通常是參考高內聚、接口收斂的原則,
這樣能夠提升整個系統的可用性。固然能夠根據應用規模的大小,模塊能夠部署在一塊兒,對於大規模的應用,通常是獨立部署的。
高併發:
業務層對外協議以NIO的RPC方式暴露,能夠採用比較成熟的NIO通信框架,如netty、mina
可用性:
爲了提升模塊服務的可用性,一個模塊部署在多個節點作冗餘,並自動進行負載轉發和失效轉移;
最初能夠利用VIP+heartbeat方式,目前系統有一個單獨的組件HA,利用zookeeper實現(比原來方案的優勢)
一致性、事務:
對於分佈式系統的一致性,儘可能知足可用性,一致性能夠經過校對來達到最終一致的狀態。
通訊組件用於業務系統內部服務之間的調用,在大併發的電商平臺中,須要知足高併發高吞吐量的要求。
整個通訊組件包括客戶端和服務端兩部分。
客戶端和服務器端維護的是長鏈接,能夠減小每次請求創建鏈接的開銷,在客戶端對於每一個服務器定義一個鏈接池,初始化鏈接後,能夠併發鏈接服務端進行rpc操做,鏈接池中的長鏈接須要心跳維護,設置請求超時時間。
對於長鏈接的維護過程能夠分兩個階段,一個是發送請求過程,另一個是接收響應過程。在發送請求過程當中,若發生IOException,則把該鏈接標記失效。接收響應時,服務端返回SocketTimeoutException,若是設置了超時時間,那麼就直接返回異常,清除當前鏈接中那些超時的請求。不然繼續發送心跳包(由於多是丟包,超過pingInterval間隔時間就發送ping操做),若ping不通(發送IOException),則說明當前鏈接是有問題的,那麼就把當前鏈接標記成已經失效;若ping通,則說明當前鏈接是可靠的,繼續進行讀操做。失效的鏈接會從鏈接池中清除掉。
每一個鏈接對於接收響應來講都以單獨的線程運行,客戶端能夠經過同步(wait,notify)方式或者異步進行rpc調用,
序列化採用更高效的hession序列化方式。
服務端採用事件驅動的NIO的MINA框架,支撐高併發高吞吐量的請求。
在大多數的數據庫切分解決方案中,爲了提升數據庫的吞吐量,首先是對不一樣的表進行垂直切分到不一樣的數據庫中,
而後當數據庫中一個表超過必定大小時,須要對該表進行水平切分,這裏也是同樣,這裏以用戶表爲例;
對於訪問數據庫客戶端來說,須要根據用戶的ID,定位到須要訪問的數據;
數據切分算法,
根據用戶的ID作hash操做,一致性Hash,這種方式存在失效數據的遷移問題,遷移時間內服務不可用
維護路由表,路由表中存儲用戶和sharding的映射關係,sharding分爲leader和replica,分別負責寫和讀
這樣每一個biz客戶端都須要保持全部sharding的鏈接池,這樣有個缺點是會產生全鏈接的問題;
一種解決方法是sharding的切分提到業務服務層進行,每一個業務節點只維護一個shard的鏈接便可。
見圖(router)
路由組件的實現是這樣的(可用性、高性能、高併發)
基於性能方面的考慮,採用mongodb中維護用戶id和shard的關係,爲了保證可用性,搭建replicatset集羣。
biz的sharding和數據庫的sharding是一一對應的,只訪問一個數據庫sharding.
biz業務註冊節點到zookeeper上/bizs/shard/下。
router監聽zookeeper上/bizs/下節點狀態,緩存在線biz在router中。
client請求router獲取biz時,router首先從mongodb中獲取用戶對應的shard,router根據緩存的內容經過RR算法獲取biz節點。
爲了解決router的可用性和併發吞吐量問題,對router進行冗餘,同時client監聽zookeeper的/routers節點並緩存在線router節點列表。
傳統實現HA的作法通常是採用虛擬IP漂移,結合Heartbeat、keepalived等實現HA,
Keepalived使用vrrp方式進行數據包的轉發,提供4層的負載均衡,經過檢測vrrp數據包來切換,作冗餘熱備更加適合與LVS搭配。Linux Heartbeat是基於網絡或者主機的服務的高可用,HAProxy或者Nginx能夠基於7層進行數據包的轉發,所以Heatbeat更加適合作HAProxy、Nginx,包括業務的高可用。
在分佈式的集羣中,能夠用zookeeper作分佈式的協調,實現集羣的列表維護和失效通知,客戶端能夠選擇hash算法或者roudrobin實現負載均衡;對於master-master模式、master-slave模式,能夠經過zookeeper分佈式鎖的機制來支持。
對於平臺各個系統之間的異步交互,是經過MQ組件進行的。
在設計消息服務組件時,須要考慮消息一致性、持久化、可用性、以及完善的監控體系。
業界開源的消息中間件主要RabbitMQ、kafka有兩種,
RabbitMQ,遵循AMQP協議,由內在高併發的erlanng語言開發;kafka是Linkedin於2010年12月份開源的消息發佈訂閱系統,它主要用於處理活躍的流式數據,大數據量的數據處理上。
對消息一致性要求比較高的場合須要有應答確認機制,包括生產消息和消費消息的過程;不過因網絡等原理致使的應答缺失,可能會致使消息的重複,這個能夠在業務層次根據冪等性進行判斷過濾;RabbitMQ採用的是這種方式。還有一種機制是消費端從broker拉取消息時帶上LSN號,從broker中某個LSN點批量拉取消息,這樣無須應答機制,kafka分佈式消息中間件就是這種方式。
消息的在broker中的存儲,根據消息的可靠性的要求以及性能方面的綜合衡量,能夠在內存中,能夠持久化到存儲上。
對於可用性和高吞吐量的要求,集羣和主備模式均可以在實際的場景應用的到。RabbitMQ解決方案中有普通的集羣和可用性更高的mirror queue方式。 kafka採用zookeeper對集羣中的broker、consumer進行管理,能夠註冊topic到zookeeper上;經過zookeeper的協調機制,producer保存對應topic的broker信息,能夠隨機或者輪詢發送到broker上;而且producer能夠基於語義指定分片,消息發送到broker的某分片上。
整體來說,RabbitMQ用在實時的對可靠性要求比較高的消息傳遞上。kafka主要用於處理活躍的流式數據,大數據量的數據處理上。
Cache系統
在一些高併發高性能的場景中,使用cache能夠減小對後端系統的負載,承擔可大部分讀的壓力,能夠大大提升系統的吞吐量,好比一般在數據庫存儲以前增長cache緩存。
可是引入cache架構不可避免的帶來一些問題,cache命中率的問題, cache失效引發的抖動,cache和存儲的一致性。
Cache中的數據相對於存儲來說,畢竟是有限的,比較理想的狀況是存儲系統的熱點數據,這裏能夠用一些常見的算法LRU等等淘汰老的數據;隨着系統規模的增長,單個節點cache不能知足要求,就須要搭建分佈式Cache;爲了解決單個節點失效引發的抖動 ,分佈式cache通常採用一致性hash的解決方案,大大減小因單個節點失效引發的抖動範圍;而對於可用性要求比較高的場景,每一個節點都是須要有備份的。數據在cache和存儲上都存有同一份備份,必然有一致性的問題,一致性比較強的,在更新數據庫的同時,更新數據庫cache。對於一致性要求不高的,能夠去設置緩存失效時間的策略。
Memcached做爲高速的分佈式緩存服務器,協議比較簡單,基於libevent的事件處理機制。
Cache系統在平臺中用在router系統的客戶端中,熱點的數據會緩存在客戶端,當數據訪問失效時,纔去訪問router系統。
固然目前更多的利用內存型的數據庫作cache,好比redis、mongodb;redis比memcache有豐富的數據操做的API;redis和mongodb都對數據進行了持久化,而memcache沒有這個功能,所以memcache更加適合在關係型數據庫之上的數據的緩存。
Buffer系統
用在高速的寫操做的場景中,平臺中有些數據須要寫入數據庫,而且數據是分庫分表的,但對數據的可靠性不是那麼高,爲了減小對數據庫的寫壓力,能夠採起批量寫操做的方式。
開闢一個內存區域,當數據到達區域的必定閥值時如80%時,在內存中作分庫梳理工做(內存速度仍是比較快的),後分庫批量flush。
在電子商務平臺中搜索是一個很是的重要功能,主要有搜索詞類目導航、自動提示和搜索排序功能。
開源的企業級搜索引擎主要有lucene, sphinx,這裏不去論述哪一種搜索引擎更好一些,不過選擇搜索引擎除了基本的功能須要支持外,非功能方面須要考慮如下兩點:
a、 搜索引擎是否支持分佈式的索引和搜索,來應對海量的數據,支持讀寫分離,提升可用性
b、 索引的實時性
c、 性能
Solr是基於lucene的高性能的全文搜索服務器,提供了比lucene更爲豐富的查詢語言,可配置可擴展,對外提供基於http協議的XML/JSON格式的接口。
從Solr4版本開始提供了SolrCloud方式來支持分佈式的索引,自動進行sharding數據切分;經過每一個sharding的master-slave(leader、replica)模式提升搜索的性能;利用zookeeper對集羣進行管理,包括leader選舉等等,保障集羣的可用性。
Lucene索引的Reader是基於索引的snapshot的,因此必須在索引commit的後,從新打開一個新的snapshot,才能搜索到新添加的內容;而索引的commit是很是耗性能的,這樣達到實時索引搜索效率就比較低下。
對於索引搜索實時性,Solr4的以前解決方案是結合文件全量索引和內存增量索引合併的方式,參見下圖。
Solr4提供了NRT softcommit的解決方案,softcommit無需進行提交索引操做,就能夠搜素到最新對索引的變動,不過對索引的變動並無sync commit到硬盤存儲上,若發生意外致使程序非正常結束,未commit的數據會丟失,所以須要定時的進行commit操做。
平臺中對數據的索引和存儲操做是異步的,能夠大大提升可用性和吞吐量;只對某些屬性字段作索引操做,存儲數據的標識key,減小索引的大小;數據是存儲在分佈式存儲HBase 中的,HBase對二級索引搜索支持的很差,然而能夠結合Solr搜索功能進行多維度的檢索統計。
索引數據和HBase數據存儲的一致性,也就是如何保障HBase存儲的數據都被索引過,能夠採用confirm確認機制,經過在索引前創建待索引數據隊列,在數據存儲並索引完成後,從待索引數據隊列中刪除數據。
在整個交易過程當中,會產生大量的日誌,這些日誌須要收集到分佈式存儲系統中存儲起來,以便於集中式的查詢和分析處理。
日誌系統需具有三個基本組件,分別爲agent(封裝數據源,將數據源中的數據發送給collector),collector(接收多個agent的數據,並進行彙總後導入後端的store中),store(中央存儲系統,應該具備可擴展性和可靠性,應該支持當前很是流行的HDFS)。
開源的日誌收集系統業界使用的比較多的是cloudera的Flume和facebook的Scribe,其中Flume目前的版本FlumeNG對Flume從架構上作了較大的改動。
在設計或者對日誌收集系統作技術選型時,一般須要具備如下特徵:
a、 應用系統和分析系統之間的橋樑,將他們之間的關係解耦
b、 分佈式可擴展,具備高的擴展性,當數據量增長時,能夠經過增長節點水平擴展
日誌收集系統是能夠伸縮的,在系統的各個層次均可伸縮,對數據的處理不須要帶狀態,伸縮性方面也比較容易實現。
c、 近實時性
在一些時效性要求比較高的場景中,須要能夠及時的收集日誌,進行數據分析;
通常的日誌文件都會定時或者定量的進行rolling,因此實時檢測日誌文件的生成,及時對日誌文件進行相似的tail操做,並支持批量發送提升傳輸效率;批量發送的時機須要知足消息數量和時間間隔的要求。
d、 容錯性
Scribe在容錯方面的考慮是,當後端的存儲系統crash時,scribe會將數據寫到本地磁盤上,當存儲系統恢復正常後,scribe將日誌從新加載到存儲系統中。
FlumeNG經過Sink Processor實現負載均衡和故障轉移。多個Sink能夠構成一個Sink Group。一個Sink Processor負責從一個指定的Sink Group中激活一個Sink。Sink Processor能夠經過組中全部Sink實現負載均衡;也能夠在一個Sink失敗時轉移到另外一個。
e、 事務支持
Scribe沒有考慮事務的支持。
Flume經過應答確認機制實現事務的支持,參見下圖,
一般提取發送消息都是批量操做的,消息的確認是對一批數據的確認,這樣能夠大大提升數據發送的效率。
f、 可恢復性
FlumeNG的channel根據可靠性的要求的不一樣,能夠基於內存和文件持久化機制,基於內存的數據傳輸的銷量比較高,可是在節點宕機後,數據丟失,不可恢復;而文件持久化宕機是能夠恢復的。
g、 數據的定時定量歸檔
數據通過日誌收集系統歸集後,通常存儲在分佈式文件系統如Hadoop,爲了便於對數據進行後續的處理分析,須要定時(TimeTrigger)或者定量(SizeTrigger的rolling分佈式系統的文件。
在 交易系統中,一般須要進行異構數據源的同步,一般有數據文件到關係型數據庫,數據文件到分佈式數據庫,關係型數據庫到分佈式數據庫等。數據在異構源之間的 同步通常是基於性能和業務的需求,數據存儲在本地文件中通常是基於性能的考慮,文件是順序存儲的,效率仍是比較高的;數據同步到關係型數據通常是基於查詢 的需求;而分佈式數據庫是存儲愈來愈多的海量數據的,而關係型數據庫沒法知足大數據量的存儲和查詢請求。
在數據同步的設計中須要綜合考慮吞吐量、容錯性、可靠性、一致性的問題
同步有實時增量數據同步和離線全量數據區分,下面從這兩個維度來介紹一下,
實時增量通常是Tail文件來實時跟蹤文件變化,批量或者多線程往數據庫導出,這種方式的架構相似於日誌收集框架。這種方式須要有確認機制,包括兩個方面。
一個方面是Channel須要給agent確認已經批量收到數據記錄了,發送LSN號給agent,這樣在agent失效恢復時,能夠從這個LSN點開始tail;固然對於容許少許的重複記錄的問題(發生在channel給agent確認的時,agent宕機並未受到確認消息),須要在業務場景中判斷。
另一個方面是sync給channel確認已經批量完成寫入到數據庫的操做,這樣channel能夠刪除這部分已經confirm的消息。
基於可靠性的要求,channel能夠採用文件持久化的方式。
參見下圖
離線全量遵循空間間換取時間,分而治之的原則,儘可能的縮短數據同步的時間,提升同步的效率。
須要對源數據好比MySQL進行切分,多線程併發讀源數據,多線程併發批量寫入分佈式數據庫好比HBase,利用channel做爲讀寫之間的緩衝,實現更好的解耦,channel能夠基於文件存儲或者內存。參見下圖:
對於源數據的切分,若是是文件能夠根據文件名稱設置塊大小來切分。
對於關係型數據庫,因爲通常的需求是隻離線同步一段時間的數據(好比凌晨把當天的訂單數據同步到HBase),因此須要在數據切分時(按照行數切分),會多線程掃描整個表(及時建索引,也要回表),對於表中包含大量的數據來說,IO很高,效率很是低;這裏解決的方法是對數據庫按照時間字段(按照時間同步的)創建分區,每次按照分區進行導出。
從傳統的基於關係型數據庫並行處理集羣、用於內存計算近實時的,到目前的基於hadoop的海量數據的分析,數據的分析在大型電子商務網站中應用很是普遍,包括流量統計、推薦引擎、趨勢分析、用戶行爲分析、數據挖掘分類器、分佈式索引等等。
並行處理集羣有商業的EMC Greenplum,Greenplum的架構採用了MPP(大規模並行處理),基於postgresql的大數據量存儲的分佈式數據庫。
內存計算方面有SAP的HANA,開源的nosql內存型的數據庫mongodb也支持mapreduce進行數據的分析。
海量數據的離線分析目前互聯網公司大量的使用Hadoop,Hadoop在可伸縮性、健壯性、計算性能和成本上具備無可替代的優點,事實上已成爲當前互聯網企業主流的大數據分析平臺
Hadoop經過MapReuce的分佈式處理框架,用於處理大規模的數據,伸縮性也很是好;可是MapReduce最大的不足是不能知足實時性的場景,主要用於離線的分析。
基於MapRduce模型編程作數據的分析,開發上效率不高,位於hadoop之上Hive的出現使得數據的分析能夠相似編寫sql的方式進行,sql通過語法分析、生成執行計劃後最終生成MapReduce任務進行執行,這樣大大提升了開發的效率,作到以ad-hoc(計算在query發生時)方式進行的分析。
基於MapReduce模型的分佈式數據的分析都是離線的分析,執行上都是暴力掃描,沒法利用相似索引的機制;開源的Cloudera Impala是基於MPP的並行編程模型的,底層是Hadoop存儲的高性能的實時分析平臺,能夠大大下降數據分析的延遲。
目前Hadoop使用的版本是Hadoop1.0,一方面原有的MapReduce框架存在JobTracker單點的問題,另一方面JobTracker在作資源管理的同時又作任務的調度工做,隨着數據量的增大和Job任務的增多,明顯存在可擴展性、內存消耗、線程模型、可靠性和性能上的缺陷瓶頸;Hadoop2.0 yarn對整個框架進行了重構,分離了資源管理和任務調度,從架構設計上解決了這個問題。
參考Yarn的架構
在互聯網領域,實時計算被普遍實時監控分析、流控、風險控制等領域。電商平臺系統或者應用對平常產生的大量日誌和異常信息,須要通過實時過濾、分析,以斷定是否須要預警;
同時須要對系統作自我保護機制,好比對模塊作流量的控制,以防止非預期的對系統壓力過大而引發的系統癱瘓,流量過大時,能夠採起拒絕或者引流等機制;有些業務須要進行風險的控制,好比彩票中有些業務須要根據系統的實時銷售狀況進行限號與放號。
原始基於單節點的計算,隨着系統信息量爆炸式產生以及計算的複雜度的增長,單個節點的計算已不能知足實時計算的要求,須要進行多節點的分佈式的計算,分佈式實時計算平臺就出現了。
這裏所說的實時計算,實際上是流式計算,概念前身實際上是CEP復瑣事件處理,相關的開源產品如Esper,業界分佈式的流計算產品Yahoo S4,Twitter storm等,以storm開源產品使用最爲普遍。
對於實時計算平臺,從架構設計上須要考慮如下幾個因素:
一、 伸縮性
隨着業務量的增長,計算量的增長,經過增長節點處理,就能夠處理。
二、 高性能、低延遲
從數據流入計算平臺數據,到計算輸出結果,須要性能高效且低延遲,保證消息獲得快速的處理,作到實時計算。
三、 可靠性
保證每一個數據消息獲得一次完整處理。
四、 容錯性
系統能夠自動管理節點的宕機失效,對應用來講,是透明的。
Twitter的Storm在以上這幾個方面作的比較好,下面簡介一下Storm的架構。
整個集羣的管理是經過zookeeper來進行的。
客戶端提交拓撲到nimbus。
Nimbus針對該拓撲創建本地的目錄根據topology的配置計算task,分配task,在zookeeper上創建assignments節點存儲task和supervisor機器節點中woker的對應關係。
在zookeeper上建立taskbeats節點來監控task的心跳;啓動topology。
Supervisor去zookeeper上獲取分配的tasks,啓動多個woker進行,每一個woker生成task,一個task一個線程;根據topology信息初始化創建task之間的鏈接;Task和Task之間是經過zeroMQ管理的;以後整個拓撲運行起來。
Tuple是流的基本處理單元,也就是一個消息,Tuple在task中流轉,Tuple的發送和接收過程以下:
發送Tuple,Worker提供了一個transfer的功能,用於當前task把tuple發到到其餘的task中。以目的taskid和tuple參數,序列化tuple數據並放到transfer queue中。
在0.8版本以前,這個queue是LinkedBlockingQueue,0.8以後是DisruptorQueue。
在0.8版本以後,每個woker綁定一個inbound transfer queue和outbond queue,inbound queue用於接收message,outbond queue用於發送消息。
發送消息時,由單個線程從transferqueue中拉取數據,把這個tuple經過zeroMQ發送到其餘的woker中。
接收Tuple,每一個woker都會監聽zeroMQ的tcp端口來接收消息,消息放到DisruptorQueue中後,後從queue中獲取message(taskid,tuple),根據目的taskid,tuple的值路由到task中執行。每一個tuple能夠emit到direct steam中,也能夠發送到regular stream中,在Reglular方式下,由Stream Group(stream id-->component id -->outbond tasks)功能完成當前tuple將要發送的Tuple的目的地。
經過以上分析能夠看到,Storm在伸縮性、容錯性、高性能方面的從架構設計的角度得以支撐;同時在可靠性方面,Storm的ack組件利用異或xor算法在不失性能的同時,保證每個消息獲得完整處理的同時。
實時推送的應用場景很是多,好比系統的監控動態的實時曲線繪製,手機消息的推送,web實時聊天等。
實時推送有不少技術能夠實現,有Comet方式,有websocket方式等。
Comet基於服務器長鏈接的「服務器推」技術,包含兩種:
Long Polling:服務器端在接到請求後掛起,有更新時返回鏈接即斷掉,而後客戶端再發起新的鏈接
Stream方式: 每次服務端數據傳送不會關閉鏈接,鏈接只會在通訊出現錯誤時,或是鏈接重建時關閉(一些防火牆常被設置爲丟棄過長的鏈接, 服務器端能夠設置一個超時時間, 超時後通知客戶端從新創建鏈接,並關閉原來的鏈接)。
Websocket:長鏈接,全雙工通訊
是 Html5 的一種新的協議。它實現了瀏覽器與服務器的雙向通信。webSocket API 中,瀏覽器和服務器端只須要經過一個握手的動做,便能造成瀏覽器與客戶端之間的快速雙向通道,使得數據能夠快速的雙向傳播。
Socket.io是一個NodeJS websocket庫,包括客戶端的JS和服務端的的nodejs,用於快速構建實時的web應用。