前言:本書是對分佈式系統架構涉及到的相關技術的一本科普書籍。因爲很難做爲開發參考,只能但求瞭解。因此通篇淺讀,對分佈式系統進行大體的瞭解。由於寫的很是好,感受很是有意思,本身也作不出總結。所謂的讀書筆記也就演變成了摘抄。前端
一個大型、穩健、成熟的分佈式系統的背後,每每會設計衆多的支撐系統,咱們將這些支撐系統成爲分佈式系統的基礎設施。除了前面所介紹的分佈式協做及配置管理系統ZooKeeper,咱們進行系統架構設計所依賴的基礎設施,還包括分佈式緩存系統、持久化存儲、分佈式消息系統、搜索引擎、以及CDN系統、負載均衡系統、運維自動化系統等,還有實時計算系統、離線計算系統、分佈式文件系統、日誌收集系統、監控系統、數據倉庫等。node
在高併發環境下,大量的讀、寫請求涌向數據庫,磁盤的處理速度與內存顯然不在一個量級,從減輕數據庫的壓力和提供系統響應速度兩個角度來考慮,通常都會在數據庫以前加一層緩存。因爲單臺機器的內存資源和承載能力有限,而且若是大量使用本地緩存,也會使相同的數據被不一樣的節點存儲多份,對內存資源形成較大的浪費,所以才催生出了分佈式緩存。
接下來將介紹分佈式緩存的典型表明memcache,以及分佈式緩存的應用場景。最爲典型的場景莫過於分佈式session。算法
memcache是一款開源的高性能的分佈式內容對象緩存系統,被許多大型網站所採用,用於在應用中減小對數據庫的訪問,提升應用的訪問速度,並下降數據庫的負載。爲了在內存中提供數據的高速查找能力,memcache使用key-value形式存儲和訪問數據,在內存中維護一張巨大的HashTable,使得對數據查詢的時間複雜度下降到O(1),保證了對數據的高性能訪問。內存的空間老是有限的,當內存沒有更多的空間來存儲新的數據時,memcache就會使用LRU(Least Recently Used)算法,將最近不常訪問的數據淘汰掉,以騰出空間來存放新的數據。memcache存儲支持的數據格式也是靈活多樣的,經過對象的序列化機制,能夠將更高層的對象轉換成爲二進制數據,存儲在緩存服務器中,當前端應用須要時,又能夠經過二進制內容反序列化,將數據還原成原有對象。數據庫
memcache客戶端與服務端經過構建在TCP協議之上的memcache協議來進行通訊,協議支持兩種數據的傳遞,這兩種數據分別爲文本行和非結構化數據。文本行主要用來承載客戶端的命令及服務端的響應,而非結構化數據則主要用於客戶端和服務端數據的傳遞。因爲非結構化數據採用字節流的形式在客戶端和服務端之間進行傳輸和存儲,所以使用方式很是靈活,緩存數據存儲幾乎沒有任何限制,而且服務端也不須要關心存儲的具體內容及字節序。後端
memcache自己並非一種分佈式的緩存系統,它的分佈式是由訪問它的客戶端來實現的。一種比較簡單的實現方式是根據緩存的key來進行Hash,當後端有N臺緩存服務器時,訪問的服務器爲hash(key)%N,這樣能夠將前端的請求均衡地映射到後端的緩存服務器。但這樣也會致使一個問題,一旦後端某臺緩存服務器宕機,或者是因爲集羣壓力過大,須要新增緩存服務器時,大部分的key將會從新分佈。對於高併發系統來講,這可能會演變成一場災難,全部的請求將如洪水般瘋狂地涌向後端的數據庫服務器,而數據庫服務器的不可用,將會致使整個應用的不可用,造成所謂的「雪崩效應」。緩存
使用consistent Hash算法可以在必定程度上改善上述問題。該算法早在1997年就在論文Consistent hashing and random trees中被提出,它可以在移除/添加一臺緩存服務器時,儘量小地改變已存在的key映射關係,避免大量key的從新映射。安全
consistent Hash的原理是這樣的,它將Hash函數的值域空間組織成一個圓環,假設Hash函數的值域空間爲0~(2的32次方-1),也就是Hash值是一個32位的無符號整型,整個空間按照順時針的方向進行組織,而後對相應的服務器節點進行Hash,將他們映射到Hash環上,假設有4臺服務器分別爲node1,node2,node3,node4,它們在環上的位置如圖所示。
接下來使用相同的Hash函數,計算出對應的key的Hash值在環上對應的位置。根據consistent Hash算法,按照順時針方向,分佈在node1與node2之間的key,它們的訪問請求會被定位到node2,而node2與node4之間的key,訪問請求會被定位到node4,以此類推。
假設有新的節點node5增長進來時,假設它被Hash到node2與node4之間,那麼受影響的只有node2和node5之間的key,它們將被從新映射到node5,而其餘key的映射關係將不會發生改變,這樣避免了大量key的從新映射。
固然上面描繪的知識一種理想的狀況,各個節點在環上分佈得十分均勻。正常狀況下,當節點數據較少時,節點的分佈可能十分不均勻,從而致使數據訪問的傾斜,大量的key被映射到同一臺服務器上。爲了不這種狀況的出現,能夠引入虛擬節點的機制,對每個服務器節點都計算多個Hash值,每個Hash值都對應環上一個節點的位置,該節點稱爲虛擬節點,而key的映射方式不變,只是多了一步從虛擬節點再映射到真實節點的過程。這樣,若是虛擬節點的數量足夠多,即便只有不多的實際節點,也可以使key分佈得相對均衡。服務器
對於大型分佈式網站來講,支撐其業務的遠遠不止一臺服務器,而是一個分佈式集羣,請求在不一樣服務器之間跳轉。那麼如何保持服務器之間的session同步呢?傳統網站通常經過將一部分數據存儲在cookie中,來規避分佈式環境下session的操做。這樣作的弊端不少,一方面cookie的安全性一直廣爲詬病,另外一方面cookie存儲數據的大小是有限制的。隨着移動互聯網的發展,不少狀況下還得兼顧移動端的session需求,使得采用cookie來進行session同步的方式的弊端更爲凸顯。分佈式session正是在這種狀況下應運而生的。
對於系統可靠性要求較高的用戶,能夠將session持久化到DB中,這樣能夠保證宕機時會話不易丟失,但缺點也是顯而易見的,系統的總體吞吐將受到很大的影響。另外一種解決方案即是將session統一存儲到緩存集羣上,如memcache,這樣能夠保證較高的讀、寫性能,這一點對於併發量大的系統來講很是重要;而且從安全性考慮,session比較是有有效期的,使用緩存存儲,也便於利用緩存的失效機制。使用緩存的缺點是,一旦緩存重啓,裏面保存的會話也就丟失了,須要從新創建會話。cookie