構建一個高效無單點故障的分布式session服務
本文來自:http://www.cellphp.com/article-read-opensource-32-php-session-distributed-redis.html
自從PHP問世以來,以其簡單的語法豐富的函數和擴展風靡WEB開發界。但是其簡單的功能也是PHP致命點。現在的高訪問量高并發量使單機PHP項 目無法承受了。所以也出現各種各樣的分布式存儲。今兒咱講講怎么構建一個高效的無單點故障的分布式session服務。 咱可不是標題黨,內容和標題絕對吻合。
現在PHP項目分布式session 一般都是 memcached+ client consistent hash。這個解決方案優點是簡單。缺點也是N多的。 具體的缺點,可參見 Timyang的 文章
http://timyang.net/architecture/consistent-hashing-practice/
現在咱來說說咱的分布式session 架構,上面這個圖這個架構的示意圖, 下面是該架構重要的三個部分的說明.
1. 為Web Server集群。 每臺機器由Nginx+PHP+eAccelerator組成
nginx 和PHP 是什么我就不多說了。
eAccelerator 是本session架構的點睛之處, eAccelerator不僅是個opcode緩存器.也提供基于共享內存的key-value的存儲。共享內存方式的數據存取比socket的 memcached 快多了。 在這里eAccelerator作為 遠程session服務的一個本地緩存區。大量減少直接從 session 集群讀取數據的壓力
2. session proxy
session proxy是基于linux + C + epoll實現的session代理服務器,具有連接池和后端服務器健康監控等功能。 session data 采用我自己研究的session hash法分布數據。 session hash是擴展于傳統的 hash() mod n的方式。hash() mod n優點是直接定位快。缺點就是增減服務器的時候,產生的災難性的數據變動。
session hash 還是采用最快的"hash() mod n"的方式來快速進行數據分布。 但是服務器動態增減或者服務器故障采用新的處理方式。 下面具體講解一下以上這些情況怎么解決。
服務器故障:比如 有 A、B、C三臺session服務器。C 服務器掛了。 就會根據A、B服務器的權重選出一臺服務器,充當C服務器。還是組成虛擬的三臺服務器(就是無論幾臺服務器掛了。邏輯上都還有三臺服務器的)。 然后由session proxy告知PHP 應用按需重建session數據。 因為前端的eAccelerator已經擋住大多數的session數據請求。所以這個session data 重建并不會帶來太大的session集群震蕩
服務器的動態 增減:這個情景是容易碰到的事情。在這里引用了個動態cursor和timeout的概念。動態游標簡單的來說就是我原先有三臺服務器,現在加兩臺服務 器。那就是五臺服務器了。 我取session數據的時候。先"hash mod 3",取不到數據,我再"hash mod 5"的方式去讀取。 看到這里有人就會說了。你這樣一次操作得讀取兩次效率不行啊。所以timeout的概念出現了。因為session 數據是暫時的。比如我登錄一個論壇,我看幾個帖子覺的沒意思。我就把瀏覽器關了。這樣就代表著一個session數據銷毀。所以說我們設置個20分鐘的 timeout。在這20分鐘內都是使用兩次mod的方式去讀取。超過20分鐘的session data。就要對該session data進行重建(使用"hash mod 5"的方式服務器定位)。而且只mod 一次讀取。
3. session data store
session data store實際上是采用redis來當session 數據存儲。
總結
剛才也說過eAccelerator 是本session架構的點睛之處.確實也是,eAccelerator 的session緩存已經承擔了相當一部分的session數據訪問。所以當后端session掛了話。也能夠快速的按需重建session數據。還有一 個點睛之處就是優化的hash算法。在傳統的"Hash mod n"基礎上, 引用了虛擬服務器和動態cursor的概念。研究出適合分布式session服務器的一種高效hash分布算法,實際上session proxy沒有session位置存儲,所以session proxy可以是多臺。此文的不成熟之處,望請大家多多提出來,我好改正。謝謝大家