1. 程式人生 > >分散式系統開發常見問題-1. session的複製與共享 2. 分散式快取的設計

分散式系統開發常見問題-1. session的複製與共享 2. 分散式快取的設計

1. session的複製與共享

在web應用中,為了應對大規模訪問,必須實現應用的叢集部署.要實現叢集部署主要需要實現session共享機制,使得多臺應用伺服器之間會話統一, tomcat等多數主流web伺服器都採用了session複製以及實現session的共享. 但問題還是很明顯的:

在節點持續增多的情況下,session複製帶來的效能損失會快速增加.特別是當session中儲存了較大的物件,而且物件變化較快時,效能下降更加顯著.這種特性使得web應用的水平擴充套件受到了限制.

session共享的另一種思路就是把session集中起來管理,首先想到的是採用資料庫來集中儲存session,但資料庫是檔案儲存相對記憶體慢了一個數量級,同時這勢必加大資料庫系統的負擔.所以需要一種既速度快又能遠端集中儲存的服務:memcached

使用memcached來儲存session有兩種方案:

(1)直接通過tomcat6的擴充套件機制實現.

(2)通過自己編寫filter實現.

考慮到系統的擴充套件,我們採用這種方案.這樣可以使session共享機制和中介軟體脫鉤.

主要思路:

1)繼承重構HttpServletRequestWrapper,HttpSessionWrapper類,覆蓋原來和session存取相關的方法呢,都通過SessionService類來實現.

2)使用filter攔截cookie中的sessionId,通過sessionId構造新的HttpServletRequestWrapper物件,傳給後面的應用.

3)SessionService連線memcached服務,以sessionId作為key,存取的物件是一個map.map的內容即為session的內容.

使用過程注意幾個問題和改進思路: 
1、memcache的記憶體應該足夠大,這樣不會出現使用者session從Cache中被清除的問題(可以關閉memcached的物件退出機制)。 
2、如果session的讀取比寫入要多很多,可以在memcache前再加一個Oscache等本地快取,減少對memcache的讀操作,從而減小網路開銷,提高效能。 
3、如果使用者非常多,可以使用memcached組,通過set方法中帶hashCode,插入到某個memcached伺服器

(3)使用memcached-session-manager管理session

對於session的清除有幾種方案:

(1)可以在凌晨人最少的時候,對memcached做一次清空。

(2)儲存在快取中的物件設定一個失效時間,通過過濾器獲取sessionId的值,定期重新整理memcached中的物件.長時間沒有被重新整理的物件自動被清除.(相對複雜,消耗資源)

2. 分散式快取的設計:在多臺Node的環境下,產生的快取以及快取的變化,如何處理?

To be continued...

3. 資料庫的sharing, 當資料量越來越大,資料需要遷移時,對不同的分庫,分表(區),業務資料處理層如何能夠適應底層的變化?

一個大型的網際網路 應用必然會經過一個從單一DB server,到Master/salve,再到垂直分割槽(分 庫),然後再到水平分割槽(分表,sharding)的過程(隨著使用者量的不斷增加,你會發現系統中的某些表會變的異常龐大,比如好友關係表,店鋪的引數配置表等,這個時候 無論是寫入還是讀取這些表的資料,對資料庫來說都是一個很耗費精力的事情),而在這個過程中,Master/salve 以 及垂直分割槽相對比較容易,對應用的影響也不是很大,但是分表會引起一些棘手的問題,比如不能跨越多個分割槽join查 詢資料,如何平衡各個shards的 負載等等,這個時候就需要一個通用的DAL框架來遮蔽底層資料儲存對應用邏輯的影響,使得底層資料的訪問對應用透明化。


拿淘寶目前的情況來說,淘寶目前也正在從昂貴的高階儲存(小型機+ORACLE)切換到MYSQL,切 換到MYSQL以 後,勢必會遇到垂直分割槽(分庫)以及水平分割槽(Sharding)的問題,因此目前淘寶根據自 己的業務特點也開發了自己的TDDL(Taobao Distributed Data Layer)框架,此框架主要解決了分庫分表對應用的透明化以及異構資料庫之間的資料複製。

淘寶網採用什麼技術架構來實現網站高負載的呢?淘寶的整體架構使用瞭如下措施來應對:一應用無狀態(淘寶session框架);二有效使用快取(Tair);三應用拆分(HSF);四資料庫拆分(TDDL);五非同步通訊(Notify);六非結構化資料儲存(TFS,NOSQL);七監控、預警系統;八配置統一管理。

4.  鐵道部網站為何登入會掛,進入之後就不會。

登入的時候,因為沒有足夠的服務相應使用者的查詢請求,負載均衡不夠,伺服器非常繁忙,導致無法登入。登入進入的人少了,那登入進去的使用者基本上在網站的承載範圍內,所以登入之後只會慢,不會掛掉。

使用CDN, 足夠的伺服器叢集,負載均衡,快取存取使用者資訊,通過測試讓系統容量能夠達到2kw級別,即可讓更多的使用者登入進系統。真正的問題不在登入,而在登入之後的對票的查詢與巧奪。查詢可以通過單獨的查詢叢集服務來解決。最困難的是最有限的資源的爭奪(1.火車票的狀態是實時計算,實時更新的;2.火車票資源稀缺,需要同線下數以萬計的購票點、電話訂票等進行互斥。每張火車票都是獨一無二的,網路售票只是數以萬計的購票終端的一個終端而已,需要跟其他售票系統保持資料一致性)。

solution 1: 設定容忍度: 絕對不能兩個人訂到同一張票,而看到有票,而點選了下訂單又說沒票了這種失誤是可以容忍的。

solution 2: 排隊,非同步告知前面多少人,輪到之後,規定時間下單(查詢需要的票,下單到的票鎖住,timeout則踢出)

solution3: 100w有效點選的使用者,隨機搖出能否負載的使用者數(10w)

點選訂票之後,進入前置分析機,分析機負責計算背後的機器能負載多少使用者下訂單。比如目前有1百萬人同時點選了訂票,而背後只能負載10萬人,那麼出現一個隨機搖號程式,搖出10萬人,其他人返回 “系統繁忙,稍後重試”的提示。這10萬人被負載在10臺機器上,可以進行查詢,當點選指定車票(標記為ClickSelectedTicket)後,根據車票被分散到不同的機器上(其實是MapReduce的思想)。比如有1萬人被定位到要訂票T1,系統扔出900張T1票,留100張容錯(隨著系統逐步穩定,可減少容錯票數),然後大家搶鎖,採用樂觀離線鎖。在最終提交訂單時檢測。

轉載:”當前 12306 系統一個很受人詬病的實現就是無法登入。使用者開啟登入頁,輸入了使用者名稱密碼,還耐心的填好了驗證碼,點選提交,再耐心的等了 30 秒,結果,彈出一個無比醜陋的對話方塊,說“當前訪問使用者過多,請稍後嘗試”。讓使用者登入進來,給他們能買到票的希望,是減少投訴的一個很重要的方面。這個其實一點也不難:將使用者資訊都載入到 Redis 記憶體,簡單點,key 就是 email,value 就是密碼加密串,用 cookie 而不是 session 進行身份驗證,用 ajax 而不是重新整理頁面的方式提交資料和返回應答,這麼一來,即使 2 kw 使用者同時都登入進來,也只需要三五臺 tomcat ,20分鐘就搞定了。