您好,登錄后才能下訂單哦!
如何解決session的復制與共享以及分布式緩存的設計問題,針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。
1. session的復制與共享
在web應用中,為了應對大規(guī)模訪問,必須實現(xiàn)應用的集群部署.要實現(xiàn)集群部署主要需要實現(xiàn)session共享機制,使得多臺應用服務器之間會話統(tǒng)一, tomcat等多數(shù)主流web服務器都采用了session復制以及實現(xiàn)session的共享. 但問題還是很明顯的:
在節(jié)點持續(xù)增多的情況下,session復制帶來的性能損失會快速增加.特別是當session中保存了較大的對象,而且對象變化較快時,性能下降更加顯著.這種特性使得web應用的水平擴展受到了限制.
session共享的另一種思路就是把session集中起來管理,首先想到的是采用數(shù)據(jù)庫來集中存儲session,但數(shù)據(jù)庫是文件存儲相對內(nèi)存慢了一個數(shù)量級,同時這勢必加大數(shù)據(jù)庫系統(tǒng)的負擔.所以需要一種既速度快又能遠程集中存儲的服務:memcached
使用memcached來存儲session有兩種方案:
(1)直接通過tomcat6的擴展機制實現(xiàn).
(2)通過自己編寫filter實現(xiàn).
考慮到系統(tǒng)的擴展,我們采用這種方案.這樣可以使session共享機制和中間件脫鉤.
主要思路:
1)繼承重構HttpServletRequestWrapper,HttpSessionWrapper類,覆蓋原來和session存取相關的方法呢,都通過SessionService類來實現(xiàn).
2)使用filter攔截cookie中的sessionId,通過sessionId構造新的HttpServletRequestWrapper對象,傳給后面的應用.
3)SessionService連接memcached服務,以sessionId作為key,存取的對象是一個map.map的內(nèi)容即為session的內(nèi)容.
使用過程注意幾個問題和改進思路:
1、memcache的內(nèi)存應該足夠大,這樣不會出現(xiàn)用戶session從Cache中被清除的問題(可以關閉memcached的對象退出機制)。
2、如果session的讀取比寫入要多很多,可以在memcache前再加一個Oscache等本地緩存,減少對memcache的讀操作,從而減小網(wǎng)絡開銷,提高性能。
3、如果用戶非常多,可以使用memcached組,通過set方法中帶hashCode,插入到某個memcached服務器
(3)使用memcached-session-manager管理session
對于session的清除有幾種方案:
(1)可以在凌晨人最少的時候,對memcached做一次清空。
(2)保存在緩存中的對象設置一個失效時間,通過過濾器獲取sessionId的值,定期刷新memcached中的對象.長時間沒有被刷新的對象自動被清除.(相對復雜,消耗資源)
2. 分布式緩存的設計:在多臺Node的環(huán)境下,產(chǎn)生的緩存以及緩存的變化,如何處理?
To be continued...
3. 數(shù)據(jù)庫的sharing, 當數(shù)據(jù)量越來越大,數(shù)據(jù)需要遷移時,對不同的分庫,分表(區(qū)),業(yè)務數(shù)據(jù)處理層如何能夠適應底層的變化?
使用DDL:Sharding擴容方案-全局增量+局部hash散列
一個大型的互聯(lián)網(wǎng) 應用必然會經(jīng)過一個從單一DB server,到Master/salve,再到垂直分區(qū)(分 庫),然后再到水平分區(qū)(分表,sharding)的過程(隨著用戶量的不斷增加,你會發(fā)現(xiàn)系統(tǒng)中的某些表會變的異常龐大,比如好友關系表,店鋪的參數(shù)配置表等,這個時候 無論是寫入還是讀取這些表的數(shù)據(jù),對數(shù)據(jù)庫來說都是一個很耗費精力的事情),而在這個過程中,Master/salve 以 及垂直分區(qū)相對比較容易,對應用的影響也不是很大,但是分表會引起一些棘手的問題,比如不能跨越多個分區(qū)join查 詢數(shù)據(jù),如何平衡各個shards的 負載等等,這個時候就需要一個通用的DAL框架來屏蔽底層數(shù)據(jù)存儲對應用邏輯的影響,使得底層數(shù)據(jù)的訪問對應用透明化。
拿淘寶目前的情況來說,淘寶目前也正在從昂貴的高端存儲(小型機+ORACLE)切換到MYSQL,切 換到MYSQL以 后,勢必會遇到垂直分區(qū)(分庫)以及水平分區(qū)(Sharding)的問題,因此目前淘寶根據(jù)自 己的業(yè)務特點也開發(fā)了自己的TDDL(Taobao Distributed Data Layer)框架,此框架主要解決了分庫分表對應用的透明化以及異構數(shù)據(jù)庫之間的數(shù)據(jù)復制。
淘寶網(wǎng)采用什么技術架構來實現(xiàn)網(wǎng)站高負載的呢?淘寶的整體架構使用了如下措施來應對:
一應用無狀態(tài)(淘寶session框架);
二有效使用緩存(Tair);
三應用拆分(HSF);
四數(shù)據(jù)庫拆分(TDDL);
五異步通信(Notify);
六非結構化數(shù)據(jù)存儲(TFS,NOSQL);
七監(jiān)控、預警系統(tǒng);
八配置統(tǒng)一管理。
4. 鐵道部網(wǎng)站為何登錄會掛,進入之后就不會。
登錄的時候,因為沒有足夠的服務相應用戶的查詢請求,負載均衡不夠,服務器非常繁忙,導致無法登錄。登錄進入的人少了,那登錄進去的用戶基本上在網(wǎng)站的承載范圍內(nèi),所以登錄之后只會慢,不會掛掉。
使用CDN, 足夠的服務器集群,負載均衡,緩存存取用戶信息,通過測試讓系統(tǒng)容量能夠達到2kw級別,即可讓更多的用戶登錄進系統(tǒng)。真正的問題不在登錄,而在登錄之后的對ticket的查詢與巧奪。查詢可以通過單獨的查詢集群服務來解決。最困難的是最有限的資源的爭奪(1.火車ticket的狀態(tài)是實時計算,實時更新的;2.火車ticket資源稀缺,需要同線下數(shù)以萬計的購ticket點、電話訂ticket等進行互斥。每張火車ticket都是獨一無二的,網(wǎng)絡售ticket只是數(shù)以萬計的購ticket終端的一個終端而已,需要跟其他售ticket系統(tǒng)保持數(shù)據(jù)一致性)。
solution 1: 設定容忍度: 絕對不能兩個人訂到同一張ticket,而看到有ticket,而點擊了下訂單又說沒ticket了這種失誤是可以容忍的。
solution 2: 排隊,異步告知前面多少人,輪到之后,規(guī)定時間下單(查詢需要的ticket,下單到的ticket鎖住,timeout則踢出)
solution3: 100w有效點擊的用戶,隨機搖出能否負載的用戶數(shù)(10w)
點擊訂ticket之后,進入前置分析機,分析機負責計算背后的機器能負載多少用戶下訂單。比如目前有1百萬人同時點擊了訂ticket,而背后只能負載10萬人,那么出現(xiàn)一個隨機搖號程序,搖出10萬人,其他人返回 “系統(tǒng)繁忙,稍后重試”的提示。這10萬人被負載在10臺機器上,可以進行查詢,當點擊指定車ticket(標記為ClickSelectedTicket)后,根據(jù)車ticket被分散到不同的機器上(其實是MapReduce的思想)。比如有1萬人被定位到要訂ticketT1,系統(tǒng)扔出900張T1ticket,留100張容錯(隨著系統(tǒng)逐步穩(wěn)定,可減少容錯ticket數(shù)),然后大家搶鎖,采用樂觀離線鎖。在最終提交訂單時檢測。
關于如何解決session的復制與共享以及分布式緩存的設計問題問題的解答就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業(yè)資訊頻道了解更多相關知識。
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。