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