為了使web應用能使用saas模式的大規模訪問,必須實現應用的集群部署.要實現集群部署主要需要實現session共享機制,使得多臺應用服務器之間會話統一, tomcat等多數服務都采用了session復制技術實現session的共享.
session復制技術的問題:
(1)技術復雜,必須在同一種中間件之間完成(如:tomcat-tomcat之間).
(2)在節點持續增多的情況下,session復制帶來的性能損失會快速增加.特別是當session中保存了較大的對象,而且對象變化較快時,性能下降更加顯著.這種特性使得web應用的水平擴展受到了限制.
session共享的另一種思路就是把session集中起來管理,首先想到的是采用數據庫來集中存儲session,但數據庫是文件存儲相對內存慢了一個數量級,同時這勢必加大數據庫系統的負擔.所以需要一種既速度快又能遠程集中存儲的服務,所以就想到了memcached.
memcached是什么?
memcached是由Danga Interactive開發的,高性能的,分布式的內存對象緩存系統,用于在動態應用中減少數據庫負載,提升訪問速度。
memcached能緩存什么?
通過在內存里維護一個統一的巨大的hash表,Memcached能夠用來存儲各種格式的數據,包括圖像、視頻、文件以及數據庫檢索的結果等。
memcached快么?
非常快。memcached使用了libevent(如果可以的話,在linux下使用epoll)來均衡任何數量的打開鏈接,使用非阻塞的網絡I/O,對內部對象實現引用計數(因此,針對多樣的客戶端,對象可以處在多樣的狀態), 使用自己的頁塊分配器和哈希表, 因此虛擬內存不會產生碎片并且虛擬內存分配的時間復雜度可以保證為O(1).。
Danga Interactive為提升Danga Interactive的速度研發了memcached。目前,LiveJournal.com每天已經在向一百萬用戶提供多達兩千萬次的頁面訪問。而這些,是由一個由web服務器和數據庫服務器組成的集群完成的。memcached幾乎完全放棄了任何數據都從數據庫讀取的方式,同時,它還縮短了用戶查看頁面的速度、更好的資源分配方式,以及memcache失效時對數據庫的訪問速度。
memcached的特點
memcached的緩存是一種分布式的,可以讓不同主機上的多個用戶同時訪問, 因此解決了共享內存只能單機應用的局限,更不會出現使用數據庫做類似事情的時候,磁盤開銷和阻塞的發生。
使用memcached來存儲session有兩種方案:
(1)直接通過tomcat6的擴展機制實現.
參考: http://www.javaeye.com/topic/81641
(2)通過自己編寫filter實現.
考慮到系統的擴展,我們采用這種方案.這樣可以使session共享機制和中間件脫鉤.
參考: http://www.javaeye.com/topic/82565
主要思路:
(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服務器
對于session的清除有幾種方案:
(1)可以在凌晨人最少的時候,對memcached做一次清空。(簡單)
(2)保存在緩存中的對象設置一個失效時間,通過過濾器獲取sessionId的值,定期刷新memcached中的對象.長時間沒有被刷新的對象自動被清除.(相對復雜,消耗資源)