原文出自:http://blog.csdn.net/yangbutao/article/details/12242441
http://stamen.iteye.com/blog/1525924
我自己的大型B2B和B2C站點原來也是用Hibernate,可是后來不得不換成mybatis,
第一是用Hibernate 因為它封裝得太高了。非常多東西是隱式進行的。常常引起問題,非常難定位。畢竟凡事有利必有弊;
第二大型站點肯定不是一個數據庫。這點Hibernate是非常麻煩的,用Jdbc或Mybatis 能夠輕松應付之。我自己寫的shard分庫框架眼下就是支持mybatis和Jdbc Template。
另,認為割舍不了Hibernate的iteyer,事實上也是建議直接再用Hibernate,待遇到痛苦時。再換,這樣體會會更深些
我的技術選型和onecan的類似,差別在於:
1.緩存:我採用ehcache+memcached結合的方式,ehcache做JVM本地緩存。memcached做進程外全局緩存,即由本地緩存和全局緩存構成系統的二級緩存;
2.數據庫上。你用單數據庫肯定是不行的。
我的平台是划分為100多個庫。早期我採用淘寶的amoeba(陳師儒兄寫的)分庫技術(事實上是一個分庫中間件。通過一台代理amoeba實現對后端mysql集群的透明化代理。
后來發現問題多多,還有一個是中間件方案盡管使用簡單。但不夠靈活,不能做多數據庫事務,所以棄之。不得以自己寫了一個基於Java的分庫框架。即Shard。在應用層直接通過Shard操作數據庫集群;
3.全文索引,我們採用Solr,只是眼下想把它換成ElasticSearch,由於Solr的全文索引同步比較慢,延時是一個非常大的問題,ES做得好些。
4.任務調度你這里沒有講,事實上這塊對於大型站點是非常重要的。我是基於Quautz自己寫了一個全局任務調度框架。相當於任務調度雲的方式。
如每天晚上匯總數據。定期遷移數據等就能夠非常好地使用任務調度來完畢。
5.編碼生成:凡是商城或應用系統,肯定是要有一個編碼生成的框架,如單據號,商品編號等,要求是全局唯一。規則可自己定義。這個我是基於Spring Expression寫了一個全局的編碼框架。稱為codeman,后面我也擬把它開源出來;
6.開放平台:假設你的商城要同意多終端接入,如iphone,android,PCclient,或者第三方。則一定要有一條服務總線,如淘寶的TOP。這個原來是用Spring MVC直接寫的,后來發現新增功能太麻煩。開發效率太低了。因此我就基於Spring MVC框架的設計思路和TOP的應用模型寫了一個Rop框架。這個已經開源的。參見我這個帖子:http://www.iteye.com/topic/1121252
7.NoSQL和mySQL結合。mySQL畢竟是關系型的,對於高並發的數據。我們是放到mogonDB中的,這個數據庫的壓力會小非常多。
8.日志的記錄:大型站點的日志記錄是非常重要的,是審計,問題定位的根據。原來早期,我直接把日志記錄到MySQL中,日志非常大。數據庫壓力大。后來把它直接異步到Elastic Search中,不但能夠全文檢索。並發性大時也沒有問題。
此外。對日志編寫了一些分析引擎,能夠從日志中發現關鍵的問題,即時報警。
9.會話管理的問題:因為應用服務節點非常多,因此棄用Web應用server本身的Session功能,直接自己編寫了一個全局會話管理功能。以實現全局統一的會話管理。
10.圖片server獨立,每張圖片僅僅保存一張物理的,事實上不同規格的圖片動態生成並放到內存中;
11.項目採用敏捷開發。DDT,Maven等。
一、 設計理念
1. 空間換時間
1) 多級緩存,靜態化
client頁面緩存(http header中包括Expires/Cache of Control。last modified(304,server不返回body,client能夠繼續用cache,降低流量),ETag)
反向代理緩存
應用端的緩存(memcache)
內存數據庫
Buffer、cache機制(數據庫,中間件等)
2) 索引
哈希、B樹、倒排、bitmap
哈希索引適合綜合數組的尋址和鏈表的插入特性。能夠實現數據的高速存取。
B樹索引適合於查詢為主導的場景。避免多次的IO。提高查詢的效率。
倒排索引實現單詞到文檔映射關系的最佳實現方式和最有效的索引結構,廣泛用在搜索領域。
Bitmap是一種很簡潔高速的數據結構,他能同一時候使存儲空間和速度最優化(而不必空間換時間),適合於海量數據的的計算場景。
2. 並行與分布式計算
1) 任務切分、分而治之(MR)
在大規模的數據中。數據存在一定的局部性的特征。利用局部性的原理將海量數據計算的問題分而治之。
MR模型是無共享的架構,數據集分布至各個節點。處理時。每一個節點就近讀取本地存儲的數據處理(map),將處理后的數據進行合並(combine)、排序(shuffle and sort)后再分發(至reduce節點),避免了大量數據的傳輸。提高了處理效率。
2) 多進程、多線程並行運行(MPP)
並行計算(Parallel Computing)是指同一時候使用多種計算資源解決計算問題的過程,是提高計算機系統計算速度和處理能力的一種有效手段。它的基本思想是用多個處理器/進程/線程來協同求解同一問題。即將被求解的問題分解成若干個部分,各部分均由一個獨立的處理機來並行計算。
和MR的差別在於,它是基於問題分解的,而不是基於數據分解。
3. 多維度的可用
1) 負載均衡、容災、備份
隨着平台並發量的增大,須要擴容節點進行集群。利用負載均衡設備進行請求的分發;負載均衡設備通常在提供負載均衡的同一時候。也提供失效檢測功能。同一時候為了提高可用性,須要有容災備份。以防止節點宕機失效帶來的不可用問題。備份有在線的和離線備份,能夠依據失效性要求的不同,進行選擇不同的備份策略。
2) 讀寫分離
讀寫分離是對數據庫來講的,隨着系統並發量的增大。提高數據訪問可用性的一個重要手段就是寫數據和讀數據進行分離;當然在讀寫分離的同一時候。須要關注數據的一致性問題;對於一致性的問題,在分布式的系統CAP定量中,很多其它的關注於可用性。
3) 依賴關系
平台中各個模塊之間的關系盡量是低耦合的,能夠通過相關的消息組件進行交互。能異步則異步,分清楚數據流轉的主流程和副流程,主副是異步的,比方記錄日志能夠是異步操作的,添加整個系統的可用性。
當然在異步處理中,為了確保數據得到接收或者處理,往往須要確認機制(confirm、ack)。
可是有些場景中。盡管請求已經得到處理,可是因其它原因(比方網絡不穩定)。確認消息沒有返回。那么這樣的情況下須要進行請求的重發,對請求的處理設計因重發因素須要考慮冪等性。
4) 監控
監控也是提高整個平台可用性的一個重要手段,多平台進行多個維度的監控;模塊在執行時候是透明的,以達到執行期白盒化。
4. 伸縮
1) 拆分
拆分包含對業務的拆分和對數據庫的拆分。
系統的資源總是有限的,一段比較長的業務運行假設是一竿子運行的方式。在大量並發的操作下,這樣的堵塞的方式,無法有效的及時釋放資源給其它進程運行。這樣系統的吞吐量不高。
須要把業務進行邏輯的分段,採用異步非堵塞的方式,提高系統的吞吐量。
隨着數據量和並發量的添加,讀寫分離不能滿足系統並發性能的要求,須要對數據進行切分,包含對數據進行分庫和分表。這樣的分庫分表的方式。須要添加對數據的路由邏輯支持。
2) 無狀態
對於系統的伸縮性而言,模塊最好是無狀態的。通過添加節點就能夠提高整個的吞吐量。
5. 優化資源利用
1) 系統容量有限
系統的容量是有限的,承受的並發量也是有限的,在架構設計時。一定須要考慮流量的控制,防止因意外攻擊或者瞬時並發量的沖擊導致系統崩潰。在設計時添加流控的措施,可考慮對請求進行排隊,超出預期的范圍。能夠進行告警或者丟棄。
2) 原子操作與並發控制
對於共享資源的訪問。為了防止沖突,須要進行並發的控制,同一時候有些交易須要有事務性來保證交易的一致性,所以在交易系統的設計時,需考慮原子操作和並發控制。
保證並發控制一些經常使用高性能手段有,樂觀鎖、Latch、mutex、寫時復制、CAS等。多版本號的並發控制MVCC一般是保證一致性的重要手段,這個在數據庫的設計中經常會用到。
3) 基於邏輯的不同,採取不一樣的策略
平台中業務邏輯存在不同的類型,有計算復雜型的,有消耗IO型的。同一時候就同一種類型而言。不同的業務邏輯消耗的資源數量也是不一樣的,這就須要針對不同的邏輯採取不同的策略。
針對IO型的,能夠採取基於事件驅動的異步非堵塞的方式,單線程方式能夠降低線程的切換引起的開銷。或者在多線程的情況下採取自旋spin的方式,降低對線程的切換(比方oracle latch設計)。對於計算型的,充分利用多線程進行操作。
同一類型的調用方式。不同的業務進行合適的資源分配。設置不同的計算節點數量或者線程數量,對業務進行分流,優先運行優先級別高的業務。
4) 容錯隔離
系統的有些業務模塊在出現錯誤時,為了降低並發下對正常請求的處理的影響,有時候須要考慮對這些異常狀態的請求進行單獨渠道的處理,甚至臨時自己主動禁止這些異常的業務模塊。
有些請求的失敗可能是偶然的臨時的失敗(比方網絡不穩定),須要進行請求重試的考慮。
5) 資源釋放
系統的資源是有限的,在使用資源時。一定要在最后釋放資源。不管是請求走的是正常路徑還是異常的路徑,以便於資源的及時回收,供其它請求使用。
在設計通信的架構時。往往須要考慮超時的控制。
二、 靜態架構藍圖
整個架構是分層的分布式的架構。縱向包含CDN,負載均衡/反向代理。web應用,業務層。基礎服務層,數據存儲層。水平方向包含對整個平台的配置管理部署和監控。
三、 剖析架構
1. CDN
CDN系統可以實時地依據網絡流量和各節點的連接、負載狀況以及到用戶的距離和響應時間等綜合信息將用戶的請求又一次導向離用戶近期的服務節點上。其目的是使用戶可就近取得所需內容。解決 Internet網絡擁擠的狀況。提高用戶訪問站點的響應速度。
對於大規模電子商務平台一般須要建CDN做網絡加速。大型平台如淘寶、京東都採用自建CDN,中小型的企業能夠採用第三方CDN廠商合作,如藍汛、網宿、快網等。
當然在選擇CDN廠商時,須要考慮經營時間長短,是否有可擴充的帶寬資源、靈活的流量和帶寬選擇、穩定的節點、性價比。
2. 負載均衡、反向代理
一個大型的平台包含非常多個業務域。不同的業務域有不同的集群,能夠用DNS做域名解析的分發或輪詢。DNS方式實現簡單,可是因存在cache而缺乏靈活性;一般基於商用的硬件F5、NetScaler或者開源的軟負載lvs在4層做分發,當然會採用做冗余(比方lvs+keepalived)的考慮,採取主備方式。
4層分發到業務集群上后。會經過webserver如nginx或者HAProxy在7層做負載均衡或者反向代理分發到集群中的應用節點。
選擇哪種負載,須要綜合考慮各種因素(是否滿足高並發高性能,Session保持怎樣解決,負載均衡的算法怎樣,支持壓縮。緩存的內存消耗);以下基於幾種經常使用的負載均衡軟件做個介紹。
LVS。工作在4層,Linux實現的高性能高並發、可伸縮性、可靠的的負載均衡器。支持多種轉發方式(NAT、DR、IP Tunneling),當中DR模式支持通過廣域網進行負載均衡。
支持雙機熱備(Keepalived或者Heartbeat)。對網絡環境的依賴性比較高。
Nginx工作在7層。事件驅動的、異步非堵塞的架構、支持多進程的高並發的負載均衡器/反向代理軟件。能夠針對域名、文件夾結構、正則規則針對http做一些分流。通過port檢測到server內部的故障。比方依據server處理網頁返回的狀態碼、超時等等。而且會把返回錯誤的請求又一次提交到還有一個節點,只是當中缺點就是不支持url來檢測。
對於session sticky。能夠基於ip hash的算法來實現,通過基於cookie的擴展nginx-sticky-module支持session sticky。
HAProxy支持4層和7層做負載均衡,支持session的會話保持,cookie的引導;支持后端url方式的檢測。負載均衡的算法比較豐富,有RR、權重等。
對於圖片,須要有單獨的域名。獨立或者分布式的圖片server或者如mogileFS。能夠圖片server之上加varnish做圖片緩存。
3. App接入
應用層執行在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過期的管理
4. 業務服務
代表某一領域的業務提供的服務,對於電商而言,領域實用戶、商品、訂單、紅包、支付業務等等。不同的領域提供不同的服務,
這些不同的領域構成一個個模塊,良好的模塊划分和接口設計很重要。通常是參考高內聚、接口收斂的原則。
這樣能夠提高整個系統的可用性。當然能夠依據應用規模的大小,模塊能夠部署在一起。對於大規模的應用,通常是獨立部署的。
高並發:
業務層對外協議以NIO的RPC方式暴露,能夠採用比較成熟的NIO通訊框架,如netty、mina
可用性:
為了提高模塊服務的可用性。一個模塊部署在多個節點做冗余,並自己主動進行負載轉發和失效轉移;
最初能夠利用VIP+heartbeat方式,眼下系統有一個單獨的組件HA,利用zookeeper實現(比原來方案的長處)
一致性、事務:
對於分布式系統的一致性,盡量滿足可用性,一致性能夠通過校對來達到終於一致的狀態。
5. 基礎服務中間件
1) 通信組件
通信組件用於業務系統內部服務之間的調用,在大並發的電商平台中,須要滿足高並發高吞吐量的要求。
整個通信組件包含client和服務端兩部分。
client和server端維護的是長連接,能夠降低每次請求建立連接的開銷,在client對於每一個server定義一個連接池,初始化連接后。能夠並發連接服務端進行rpc操作,連接池中的長連接須要心跳維護,設置請求超時時間。
對於長連接的維護過程能夠分兩個階段。一個是發送請求過程。另外一個是接收響應過程。在發送請求過程中。若發生IOException,則把該連接標記失效。
接收響應時,服務端返回SocketTimeoutException,假設設置了超時時間,那么就直接返回異常,清除當前連接中那些超時的請求。否則繼續發送心跳包(由於可能是丟包,超過pingInterval間隔時間就發送ping操作),若ping不通(發送IOException)。則說明當前連接是有問題的。那么就把當前連接標記成已經失效;若ping通,則說明當前連接是可靠的,繼續進行讀操作。
失效的連接會從連接池中清除掉。
每一個連接對於接收響應來說都以單獨的線程執行,client能夠通過同步(wait,notify)方式或者異步進行rpc調用,
序列化採用更高效的hession序列化方式。
服務端採用事件驅動的NIO的MINA框架,支撐高並發高吞吐量的請求。
2) 路由Router
在大多數的數據庫切分解決方式中。為了提高數據庫的吞吐量,首先是對不同的表進行垂直切分到不同的數據庫中,
然后當數據庫中一個表超過一定大小時,須要對該表進行水平切分,這里也是一樣,這里以用戶表為例。
對於訪問數據庫client來講,須要依據用戶的ID,定位到須要訪問的數據;
數據切分算法,
依據用戶的ID做hash操作。一致性Hash,這樣的方式存在失效數據的遷移問題。遷移時間內服務不可用
維護路由表,路由表中存儲用戶和sharding的映射關系,sharding分為leader和replica,分別負責寫和讀
這樣每一個bizclient都須要保持全部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節點列表。
3) HA
傳統實現HA的做法通常是採用虛擬IP漂移,結合Heartbeat、keepalived等實現HA。
Keepalived使用vrrp方式進行數據包的轉發。提供4層的負載均衡,通過檢測vrrp數據包來切換,做冗余熱備更加適合與LVS搭配。
Linux Heartbeat是基於網絡或者主機的服務的高可用。HAProxy或者Nginx能夠基於7層進行數據包的轉發。因此Heatbeat更加適合做HAProxy、Nginx,包含業務的高可用。
在分布式的集群中,能夠用zookeeper做分布式的協調,實現集群的列表維護和失效通知,client能夠選擇hash算法或者roudrobin實現負載均衡;對於master-master模式、master-slave模式。能夠通過zookeeper分布式鎖的機制來支持。
4) 消息Message
對於平台各個系統之間的異步交互,是通過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主要用於處理活躍的流式數據,大數據量的數據處理上。
5) Cache&Buffer
Cache系統
在一些高並發高性能的場景中,使用cache能夠降低對后端系統的負載。承擔可大部分讀的壓力,能夠大大提高系統的吞吐量,比方通常在數據庫存儲之前添加cache緩存。
可是引入cache架構不可避免的帶來一些問題,cache命中率的問題, cache失效引起的抖動,cache和存儲的一致性。
Cache中的數據相對於存儲來講,畢竟是有限的,比較理想的情況是存儲系統的熱點數據,這里能夠用一些常見的算法LRU等等淘汰老的數據;隨着系統規模的添加。單個節點cache不能滿足要求,就須要搭建分布式Cache;為了解決單個節點失效引起的抖動 ,分布式cache一般採用一致性hash的解決方式,大大降低因單個節點失效引起的抖動范圍。而對於可用性要求比較高的場景,每一個節點都是須要有備份的。數據在cache和存儲上都存有同一份備份。必定有一致性的問題,一致性比較強的,在更新數據庫的同一時候,更新數據庫cache。
對於一致性要求不高的。能夠去設置緩存失效時間的策略。
Memcached作為快速的分布式緩存server。協議比較簡單。基於libevent的事件處理機制。
Cache系統在平台中用在router系統的client中,熱點的數據會緩存在client,當數據訪問失效時,才去訪問router系統。
當然眼下很多其它的利用內存型的數據庫做cache。比方redis、mongodb。redis比memcache有豐富的數據操作的API;redis和mongodb都對數據進行了持久化,而memcache沒有這個功能。因此memcache更加適合在關系型數據庫之上的數據的緩存。
Buffer系統
用在快速的寫操作的場景中,平台中有些數據須要寫入數據庫。而且數據是分庫分表的,但對數據的可靠性不是那么高,為了降低對數據庫的寫壓力。能夠採取批量寫操作的方式。
開辟一個內存區域,當數據到達區域的一定閥值時如80%時。在內存中做分庫梳理工作(內存速度還是比較快的),后分庫批量flush。
6) 搜索
在電子商務平台中搜索是一個很的重要功能,主要有搜索詞類目導航、自己主動提示和搜索排序功能。
開源的企業級搜索引擎主要有lucene, sphinx,這里不去論述哪種搜索引擎更好一些,只是選擇搜索引擎除了主要的功能須要支持外,非功能方面須要考慮下面兩點:
a、 搜索引擎是否支持分布式的索引和搜索。來應對海量的數據,支持讀寫分離。提高可用性
b、 索引的實時性
c、 性能
Solr是基於lucene的高性能的全文搜索server。提供了比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確認機制。通過在索引前建立待索引數據隊列。在數據存儲並索引完畢后,從待索引數據隊列中刪除數據。
7) 日志收集
在整個交易過程中,會產生大量的日志。這些日志須要收集到分布式存儲系統中存儲起來。以便於集中式的查詢和分析處理。
日志系統需具備三個基本組件。分別為agent(封裝數據源,將數據源中的數據發送給collector)。collector(接收多個agent的數據。並進行匯總后導入后端的store中),store(中央存儲系統,應該具有可擴展性和可靠性,應該支持當前很流行的HDFS)。
開源的日志收集系統業界使用的比較多的是cloudera的Flume和facebook的Scribe,當中Flume眼下的版本號FlumeNG對Flume從架構上做了較大的修改。
在設計或者對日志收集系統做技術選型時,通常須要具有下面特征:
a、 應用系統和分析系統之間的橋梁,將他們之間的關系解耦
b、 分布式可擴展。具有高的擴展性。當數據量添加時。能夠通過添加節點水平擴展
日志收集系統是能夠伸縮的,在系統的各個層次都可伸縮。對數據的處理不須要帶狀態,伸縮性方面也比較easy實現。
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分布式系統的文件。
8) 數據同步
在交易系統中,通常須要進行異構數據源的同步,通常有數據文件到關系型數據庫,數據文件到分布式數據庫。關系型數據庫到分布式數據庫等。數據在異構源之間的同步通常是基於性能和業務的需求,數據存儲在本地文件里通常是基於性能的考慮。文件是順序存儲的,效率還是比較高的;數據同步到關系型數據通常是基於查詢的需求。而分布式數據庫是存儲越來越多的海量數據的。而關系型數據庫無法滿足大數據量的存儲和查詢請求。
在數據同步的設計中須要綜合考慮吞吐量、容錯性、可靠性、一致性的問題
同步有實時增量數據同步和離線全量數據區分,以下從這兩個維度來介紹一下。
實時增量通常是Tail文件來實時跟蹤文件變化。批量或者多線程往數據庫導出,這樣的方式的架構類似於日志收集框架。這樣的方式須要有確認機制,包含兩個方面。
一個方面是Channel須要給agent確認已經批量收到數據記錄了。發送LSN號給agent,這樣在agent失效恢復時,能夠從這個LSN點開始tail;當然對於同意少量的反復記錄的問題(發生在channel給agent確認的時,agent宕機並未受到確認消息),須要在業務場景中推斷。
另外一個方面是sync給channel確認已經批量完畢寫入到數據庫的操作,這樣channel能夠刪除這部分已經confirm的消息。
基於可靠性的要求,channel能夠採用文件持久化的方式。
參見下圖
離線全量遵循空間間換取時間,分而治之的原則,盡量的縮短數據同步的時間,提高同步的效率。
須要對源數據比方mysql進行切分,多線程並發讀源數據,多線程並發批量寫入分布式數據庫比方HBase,利用channel作為讀寫之間的緩沖,實現更好的解耦,channel能夠基於文件存儲或者內存。
參見下圖:
對於源數據的切分,假設是文件能夠依據文件名設置塊大小來切分。
對於關系型數據庫。因為一般的需求是僅僅離線同步一段時間的數據(比方凌晨把當天的訂單數據同步到HBase)。所以須要在數據切分時(依照行數切分)。會多線程掃描整個表(及時建索引,也要回表)。對於表中包括大量的數據來講,IO非常高。效率非常低;這里解決辦法是對數據庫依照時間字段(依照時間同步的)建立分區。每次依照分區進行導出。
9) 數據分析
從傳統的基於關系型數據庫並行處理集群、用於內存計算近實時的,到眼下的基於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的架構
10) 實時計算
在互聯網領域,實時計算被廣泛實時監控分析、流控、風險控制等領域。電商平台系統或者應用對日常產生的大量日志和異常信息。須要經過實時過濾、分析,以判定是否須要預警;
同一時候須要對系統做自我保護機制,比方對模塊做流量的控制,以防止非預期的對系統壓力過大而引起的系統癱瘓,流量過大時,能夠採取拒絕或者引流等機制。有些業務須要進行風險的控制,比方彩票中有些業務須要依據系統的實時銷售情況進行限號與放號。
原始基於單節點的計算。隨着系統信息量爆炸式產生以及計算的復雜度的添加,單個節點的計算已不能滿足實時計算的要求,須要進行多節點的分布式的計算,分布式實時計算平台就出現了。
這里所說的實時計算,事實上是流式計算,概念前身事實上是CEP復雜事件處理,相關的開源產品如Esper,業界分布式的流計算產品Yahoo S4,Twitter storm等,以storm開源產品使用最為廣泛。
對於實時計算平台。從架構設計上須要考慮下面幾個因素:
1、 伸縮性
隨着業務量的添加,計算量的添加,通過添加節點處理,就能夠處理。
2、 高性能、低延遲
從數據流入計算平台數據,到計算輸出結果。須要性能高效且低延遲,保證消息得到高速的處理,做到實時計算。
3、 可靠性
保證每一個數據消息得到一次完整處理。
4、 容錯性
系統能夠自己主動管理節點的宕機失效,相應用來說,是透明的。
Twitter的Storm在以上這幾個方面做的比較好,以下簡單介紹一下Storm的架構。
整個集群的管理是通過zookeeper來進行的。
client提交拓撲到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的tcpport來接收消息,消息放到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算法在不失性能的同一時候。保證每個消息得到完整處理的同一時候。
11) 實時推送
實時推送的應用場景許多。比方系統的監控動態的實時曲線繪制,手機消息的推送,web實時聊天等。
實時推送有非常多技術能夠實現,有Comet方式,有websocket方式等。
Comet基於server長連接的“server推”技術,包括兩種:
Long Polling:server端在接到請求后掛起。有更新時返回連接即斷掉,然后client再發起新的連接
Stream方式: 每次服務端數據傳送不會關閉連接,連接僅僅會在通信出現錯誤時,或是連接重建時關閉(一些防火牆常被設置為丟棄過長的連接, server端能夠設置一個超時時間, 超時后通知client又一次建立連接。並關閉原來的連接)。
Websocket:長連接。全雙工通信
是 Html5 的一種新的協議。它實現了瀏覽器與server的雙向通訊。webSocket API 中。瀏覽器和server端僅僅須要通過一個握手的動作。便能形成瀏覽器與client之間的高速雙向通道,使得數據能夠高速的雙向傳播。
Socket.io是一個NodeJS websocket庫,包含client的JS和服務端的的nodejs,用於高速構建實時的web應用。
12) 推薦引擎
待補充
6. 數據存儲
數據庫存儲大體分為以下幾類。有關系型(事務型)的數據庫。以oracle、mysql為代表,有keyvalue數據庫。以redis和memcached db為代表。有文檔型數據庫如mongodb,有列式分布式數據庫以HBase,cassandra,dynamo為代表。還有其它的圖形數據庫、對象數據 庫、xml數據庫等。
每種類型的數據庫應用的業務領域是不一樣的,以下從內存型、關系型、分布式三個維度針對相關的產品做性能可用性等方面的考量分析。
1) 內存型數據庫
內存型的數據庫,以高並發高性能為目標,在事務性方面沒那么嚴格,以開源nosql數據庫mongodb、redis為例
Ø Mongodb
通信方式
多線程方式,主線程監聽新的連接。連接后,啟動新的線程做數據的操作(IO切換)。
數據結構
數據庫-->collection-->record
MongoDB在數據存儲上按命名空間來划分,一個collection是一個命名空間,一個索引也是一個命名空間。
同一個命名空間的數據被分成非常多個Extent,Extent之間使用雙向鏈表連接。
在每個Extent中,保存了詳細每一行的數據,這些數據也是通過雙向鏈接連接的。
每一行數據存儲空間不僅包括數據占用空間,還可能包括一部分附加空間。這使得在數據update變大后能夠不移動位置。
索引以BTree結構實現。
假設你開啟了jorunaling日志,那么還會有一些文件存儲着你全部的操作記錄。
持久化存儲
MMap方式把文件地址映射到內存的地址空間,直接操作內存地址空間就能夠操作文件,不用再調用write,read操作。性能比較高。
mongodb調用mmap把磁盤中的數據映射到內存中的,所以必須有一個機制時刻的刷數據到硬盤才干保證可靠性。多久刷一次是與syncdelay參數相關的。
journal(進行恢復用)是Mongodb中的redo log。而Oplog則是負責復制的binlog。假設打開journal,那么即使斷電也僅僅會丟失100ms的數據,這對大多數應用來說都能夠容忍了。
從1.9.2+,mongodb都會默認打開journal功能,以確保數據安全。並且journal的刷新時間是能夠改變的,2-300ms的范圍,使用 --journalCommitInterval 命令。Oplog和數據刷新到磁盤的時間是60s,對於復制來說,不用等到oplog刷新磁盤,在內存中就能夠直接拷貝到Sencondary節點。
事務支持
Mongodb僅僅支持對單行記錄的原子操作
HA集群
用的比較多的是Replica Sets,採用選舉算法。自己主動進行leader選舉。在保證可用性的同一時候。能夠做到強一致性要求。
當然對於大量的數據,mongodb也提供了數據的切分架構Sharding。
Ø Redis
豐富的數據結構,快速的響應速度,內存操作
通信方式
因都在內存操作,所以邏輯的操作很快,降低了CPU的切換開銷。所以為單線程的模式(邏輯處理線程和主線程是一個)。
reactor模式。實現自己的多路復用NIO機制(epoll,select,kqueue等)
單線程處理多任務
數據結構
hash+bucket結構,當鏈表的長度過長時,會採取遷移的措施(擴展原來兩倍的hash表,把數據遷移過去,expand+rehash)
持久化存儲
a、全量持久化RDB(遍歷redisDB,讀取bucket中的key,value),save命令堵塞主線程,bgsave開啟子進程進行snapshot持久化操作。生成rdb文件。
在shutdown時。會調用save操作
數據發生變化,在多少秒內觸發一次bgsave
sync。master接受slave發出來的命令
b、增量持久化(aof類似redolog),先寫到日志buffer,再flush到日志文件里(flush的策略能夠配置的。而已單條。也能夠批量),僅僅有flush到文件上的,才真正返回client。
要定時對aof文件和rdb文件做合並操作(在快照過程中,變化的數據先寫到aof buf中等子進程完畢快照<內存snapshot>后。再進行合並aofbuf變化的部分以及全鏡像數據)。
在高並發訪問模式下,RDB模式使服務的性能指標出現明顯的抖動。aof在性能開銷上比RDB好,可是恢復時又一次載入到內存的時間和數據量成正比。
集群HA
通用的解決方式是主從備份切換,採用HA軟件,使得失效的主redis能夠高速的切換到從redis上。主從數據的同步採用復制機制,該場景能夠做讀寫分離。
眼下在復制方面。存在的一個問題是在遇到網絡不穩定的情況下。Slave和Master斷開(包含閃斷)會導致Master須要將內存中的數據所有又一次生成rdb文件(快照文件),然后傳輸給Slave。
Slave接收完Master傳遞過來的rdb文件以后會將自身的內存清空,把rdb文件又一次載入到內存中。這樣的方式效率比較低下,在后面的未來版本號Redis2.8作者已經實現了部分復制的功能。
2) 關系型數據庫
關系型數據庫在滿足並發性能的同一時候。也須要滿足事務性,以mysql數據庫為例。講述架構設計原理,在性能方面的考慮。以及怎樣滿足可用性的需求。
Ø mysql的架構原理(innodb)
在架構上,mysql分為server層和存儲引擎層。
Server層的架構對於不同的存儲引擎來講都是一樣的,包含連接/線程處理、查詢處理(parser、optimizer)以及其它系統任務。
存儲引擎層有非常多種,mysql提供了存儲引擎的插件式結構,支持多種存儲引擎。用的最廣泛的是innodb和myisamin。inodb主要面向OLTP方面的應用,支持事務處理,myisam不支持事務,表鎖,對OLAP操作速度快。
下面主要針對innodb存儲引擎做相關介紹。
在線程處理方面,Mysql是多線程的架構,由一個master線程。一個鎖監控線程,一個錯誤監控線程,和多個IO線程組成。而且對一個連接會開啟一個線程進行服務。
io線程又分為節省隨機IO的insert buffer。用於事務控制的類似於oracle的redo log,以及多個write。多個read的硬盤和內存交換的IO線程。
在內存分配方面,包含innodb buffer pool ,以及log buffer。
當中innodb buffer pool包含insert buffer、datapage、index page、數據字典、自適應hash。Log buffer用於緩存事務日志,提供性能。
在數據結構方面,innodb包含表空間、段、區、頁/塊,行。
索引結構是B+tree結構,包含二級索引和主鍵索引。二級索引的葉子節點是主鍵PK,依據主鍵索引的葉子節點指向存儲的數據塊。這樣的B+樹存儲結構能夠更好的滿足隨機查詢操作IO要求,分為數據頁和二級索引頁,改動二級索引頁面涉及到隨機操作,為了提高寫入時的性能,採用insert buffer做順序的寫入,再由后台線程以一定頻率將多個插入合並到二級索引頁面。
為了保證數據庫的一致性(內存和硬盤數據文件),以及縮短實例恢復的時間,關系型數據庫另一個checkpoint的功能,用於把內存buffer中之前的臟頁依照比例(老的LSN)寫入磁盤,這樣redolog文件的LSN曾經的日志就能夠被覆蓋了,進行循環使用;在失效恢復時,僅僅須要從日志中LSN點進行恢復就可以。
在事務特性支持上。關系型數據庫須要滿足ACID四個特性,須要依據不同的事務並發和數據可見性要求,定義了不同的事務隔離級別,而且離不開對資源爭用的鎖機制。要避免產生死鎖。mysql在Server層和存儲引擎層做並發控制,主要體如今讀寫鎖,依據鎖粒度不同,有各個級別的鎖(表鎖、行鎖、頁鎖、MVCC);基於提高並發性能的考慮,使用多版本號並發控制MVCC來支持事務的隔離。並基於undo來實現,在做事務回滾時。也會用到undo段。
mysql 用redolog來保證數據的寫入的性能和失效恢復。在改動數據時僅僅須要改動內存,再把改動行為記錄到事務日志中(順序IO)。不用每次將數據改動本身持久化到硬盤(隨機IO),大大提高性能。
在可靠性方面。innodb存儲引擎提供了兩次寫機制double writer用於防止在flush頁面到存儲上出現的錯誤。解決磁盤half-writern的問題。
Ø 對於高並發高性能的mysql來講,能夠在多個維度進行性能方面的調優。
a、硬件級別,
日志和數據的存儲,須要分開,日志是順序的寫。須要做raid1+0。而且用buffer-IO。數據是離散的讀寫。走direct IO就可以,避免走文件系統cache帶來的開銷。
存儲能力,SAS盤raid操作(raid卡緩存,關閉讀cache,關閉磁盤cache,關閉預讀,僅僅用writeback buffer,只是須要考慮充放電的問題)。當然假設數據規模不大。數據的存儲能夠用快速的設備,Fusion IO、SSD。
對於數據的寫入,控制臟頁刷新的頻率。對於數據的讀取,控制cache hit率;因此而估算系統須要的IOPS,評估須要的硬盤數量(fusion io上到IOPS 在10w以上,普通的硬盤150)。
Cpu方面,單實例關閉NUMA,mysql對多核的支持不是太好,能夠對多實例進行CPU綁定。
b、操作系統級別,
內核以及socket的優化,網絡優化bond、文件系統、IO調度
innodb主要用在OLTP類應用,一般都是IO密集型的應用。在提高IO能力的基礎上,充分利用cache機制。
須要考慮的內容有。
在保證系統可用內存的基礎上,盡可能的擴大innodb buffer pool,一般設置為物理內存的3/4
文件系統的使用。僅僅在記錄事務日志的時候用文件系統的cache;盡量避免mysql用到swap(能夠將vm.swappiness=0,內存緊張時。釋放文件系統cache)
IO調度優化,降低不必要的堵塞,降低隨機IO訪問的延時(CFQ、Deadline、NOOP)
c、server以及存儲引擎級別(連接管理、網絡管理、table管理、日志)
包含cache/buffer、Connection、IO
d、應用級別(比方索引的考慮,schema的優化適當冗余。優化sql查詢導致的CPU問題和內存問題。降低鎖的范圍,降低回表掃描,覆蓋索引)
Ø 在高可用實踐方面,
支持master-master、master-slave模式。master-master模式是一個作為主負責讀寫,另外一個作為standby提供災備,maser-slave是一個作為主提供寫操作,其它幾個節點作為讀操作,支持讀寫分離。
對於節點主備失效檢測和切換,能夠採用HA軟件,當然也能夠從更細粒度定制的角度,採用zookeeper作為集群的協調服務。
對於分布式的系統來講,數據庫主備切換的一致性始終是一個問題,能夠有下面幾種方式:
a、集群方式,如oracle的rack,缺點是比較復雜
b、共享SAN存儲方式,相關的數據文件和日志文件都放在共享存儲上。長處是主備切換時數據保持一致,不會丟失。但因為備機有一段時間的拉起,會有短暫的不可用狀態
c、主備進行數據同步的方式,常見的是日志的同步,能夠保障熱備,實時性好,可是切換時。可能有部分數據沒有同步過來,帶來了數據的一致性問題。能夠在操作主數據庫的同一時候,記錄操作日志,切換到備時,會和操作日志做個check。補齊未同步過來的數據;
d、另一種做法是備庫切換到主庫的regolog的存儲上。保證數據不丟失。
數據庫主從復制的效率在mysql上不是太高,主要原因是事務是嚴格保持順序的,索引mysql在復制方面包含日志IO和relog log兩個過程都是單線程的串行操作,在數據復制優化方面。盡量降低IO的影響。
只是到了Mysql5.6版本號,能夠支持在不同的庫上的並行復制。
Ø 基於不同業務要求的存取方式
平台業務中。不同的業務有不同的存取要求,比方典型的兩大業務用戶和訂單,用戶一般來講總量是可控的,而訂單是不斷地遞增的,對於用戶表首先採取分庫切分,每一個sharding做一主多讀。相同對於訂單因很多其它需求的是用戶查詢自己的訂單,也須要依照用戶進行切分訂單庫。而且支持一主多讀。
在硬件存儲方面,對於事務日志因是順序寫。閃存的優勢比硬盤高不了多少,所以採取電池保護的寫緩存的raid卡存儲;對於數據文件,不管是對用戶或者訂單都會存在大量的隨機讀寫操作,當然加大內存是一個方面,另外能夠採用快速的IO設備閃存,比方PCIe卡 fusion-io。
使用閃存也適合在單線程的負載中,比方主從復制,能夠對從節點配置fusion-IO卡,減少復制的延遲。
對於訂單業務來講,量是不斷遞增的,PCIe卡存儲容量比較有限。而且訂單業務的熱數據僅僅有近期一段時間的(比方近3個月的)。對此這里列兩種解決方式,一種是flashcache方式,採用基於閃存和硬盤存儲的開源混合存儲方式,在閃存中存儲熱點的數據。第二種是能夠定期把老的數據導出到分布式數據庫HBase中,用戶在查詢訂單列表是近期的數據從mysql中獲取,老的數據能夠從HBase中查詢。當然須要HBase良好的rowkey設計以適應查詢需求。
3) 分布式數據庫
對於數據的高並發的訪問。傳統的關系型數據庫提供讀寫分離的方案,可是帶來的確實數據的一致性問題提供的數據切分的方案;對於越來越多的海量數據。傳統的數據庫採用的是分庫分表,實現起來比較復雜,后期要不斷的進行遷移維護;對於高可用和伸縮方面,傳統數據採用的是主備、主從、多主的方案。可是本身擴展性比較差,添加節點和宕機須要進行數據的遷移。對於以上提出的這些問題。分布式數據庫HBase有一套完好的解決方式,適用於高並發海量數據存取的要求。
Ø HBase
基於列式的高效存儲減少IO
通常的查詢不須要一行的所有字段,大多數僅僅須要幾個字段
對與面向行的存儲系統,每次查詢都會所有數據取出,然后再從中選出須要的字段
面向列的存儲系統能夠單獨查詢某一列。從而大大減少IO
提高壓縮效率
同列數據具有非常高的相似性,會添加壓縮效率
Hbase的非常多特性。都是由列存儲決定的
高性能
LSM Tree
適合快速寫的場景
強一致的數據訪問
MVCC
HBase的一致性數據訪問是通過MVCC來實現的。
HBase在寫數據的過程中,須要經過好幾個階段,寫HLog。寫memstore,更新MVCC;
僅僅有更新了MVCC,才算真正memstore寫成功,當中事務的隔離須要有mvcc的來控制,比方讀數據不能夠獲取別的線程還未提交的數據。
高可靠
HBase的數據存儲基於HDFS。提供了冗余機制。
Region節點的宕機,對於內存中的數據還未flush到文件里,提供了可靠的恢復機制。
可伸縮。自己主動切分。遷移
通過Zookeeper定位目標Region Server,最后定位Region。
Region Server擴容,通過將自身公布到Master,Master均勻分布。
可用性
存在單點故障,Region Server宕機后,短時間內該server維護的region無法訪問。等待failover生效。
通過Master維護各Region Server健康狀況和Region分布。
多個Master。Master宕機有zookeeper的paxos投票機制選取下一任Master。
Master就算全宕機,也不影響Region讀寫。
Master僅充當一個自己主動運維角色。
HDFS為分布式存儲引擎,一備三,高可靠,0數據丟失。
HDFS的namenode是一個SPOF。
為避免單個region訪問過於頻繁,單機壓力過大,提供了split機制
HBase的寫入是LSM-TREE的架構方式,隨着數據的append,HFile越來越多。HBase提供了HFile文件進行compact,對過期數據進行清除。提高查詢的性能。
Schema free
HBase沒有像關系型數據庫那樣的嚴格的schema,能夠自由的添加和刪除schema中的字段。
HBase分布式數據庫。對於二級索引支持的不太好,眼下僅僅支持在rowkey上的索引,所以rowkey的設計對於查詢的性能來講很關鍵。
7. 管理與部署配置
統一的配置庫
部署平台
8. 監控、統計
大型分布式系統涉及各種設備。比方網絡交換機,普通PC機。各種型號的網卡。硬盤,內存等等,還有應用業務層次的監控。數量許多的時候,出現錯誤的概率也會變大,而且有些監控的時效性要求比較高,有些達到秒級別;在大量的數據流中須要過濾異常的數據,有時候也對數據會進行上下文相關的復雜計算,進而決定是否須要告警。因此監控平台的性能、吞吐量、已經可用性就比較重要,須要規划統一的一體化的監控平台對系統進行各個層次的監控。
平台的數據分類
應用業務級別:應用事件、業務日志、審計日志、請求日志、異常、請求業務metrics、性能度量
系統級別:CPU、內存、網絡、IO
時效性要求
閥值。告警:
實時計算:
近實時分鍾計算
按小時、天的離線分析
實時查詢
架構
節點中Agent代理能夠接收日志、應用的事件以及通過探針的方式採集數據,agent採集數據的一個原則是和業務應用的流程是異步隔離的。不影響交易流程。
數據統一通過collector集群進行收集,依照數據的不同類型分發到不同的計算集群進行處理;有些數據時效性不是那么高,比方按小時進行統計,放入hadoop集群;有些數據是請求流轉的跟蹤數據,須要能夠查詢的,那么就能夠放入solr集群進行索引;有些數據須要進行實時計算的進而告警的,須要放到storm集群中進行處理。
數據經過計算集群處理后。結果存儲到Mysql或者HBase中。
監控的web應用能夠把監控的實時結果推送到瀏覽器中,也能夠提供API供結果的展現和搜索。