多服務器之間Session共享


原理:多個服務器間想共享session,就相當於共享取多台主機上的一個變量,所以共享的思路就是讓大家都能讀取變量,實現的方法可以通過將session保存到專門的一個服務器上,所有服務器都去請求數據,也memcache實現session共享將這些服務器都配置成使用同一組Memcached服務器就可以,
 
一、提出問題:
 
為了滿足足夠大的應用,滿足更多的客戶,於是我們架設了N台Web服務器(N>=2),在多台Web服務器的情況下,我們會涉及到一個問題:用戶登陸一台服務器以后,如果在跨越到另一台服務器的時候能夠繼續使用客戶的Session?
 
二、解決方案:
 
1. 寫客戶端Cookie的方式
       當用戶登陸成功以后,把網站域名、用戶名、密碼、token、 session有效時間全部采用cookie的形式寫入到客戶端的cookie里面,如果用戶從一台Web服務器跨越到另一台服務器的時候,我們的程序主動去檢測客戶端的cookie信息,進行判斷,然后提供對應的服務,當然,如果cookie過期,或者無效,自然就不讓用戶繼續服務了。當然,這種方法的弊端就不言而喻了,比如客戶端禁用了cookie或者cookie被黑客竊取了呢?這些都可以解決,目前淘寶session框架就是基於client cookie做開發,不見得他們就出了很大的問題?也許是最可行的方式,可以配合memcached來實現。
 
2. 服務器之間Session數據同步的方式
       假設Web服務器A是所有用戶登陸的服務器,那么當用戶驗證登陸一下,session數據就會寫到A服務器里,那么就可以自己寫腳本或者守護進程來自動把session數據同步到其他Web服務器,那么當用戶跳轉到其他服務器的時候,那么session數據是一致的,自然就能夠直接進行服務無須再次登陸了。缺點是,可能會速度慢,不穩定,如果是單向同步的話,登陸服務器出現問題,那么其他服務器也無法服務,當然也可以考慮雙向同步的問題。這個方案都可以解決,目前zookeeper可以實現。
 
3. 利用NFS共享Session數據的方式
       其實這個方案和下面的Mysql方案類似,只是存儲方式不一 樣。大致就是有一台公共的NFS服務器(Network File Server)做共享服務器,所有的Web服務器登陸的時候把session數據寫到這台服務器上,那么所有的session數據其實都是保存在這台 NFS服務器上的,不論用戶訪問哪台Web服務器,都要來這台服務器獲取session數據,那么就能夠實現共享session數據了。缺點是依賴性太強,如果NFS服務器down掉了,那么大家都無法工作了,當然,可以考慮多台NFS服務器同步的形式。這個方案都可以解決,目前zookeeper可以實現,當然memcached也可以實現session共享。
 
4. 利用Mysql數據庫共享Session數據的方式
       這個方式與NFS的方式類似,也是采用一台Mysql服務器做共享服務器,把所有的session的數據保存到Mysql服務器上,所有Web服務器都來這台Mysql服務器來獲取Session 數據。缺點也是依賴性太強,Mysql無法工作了影響所有的Web服務器,當然,可以考慮多太Mysql數據庫來共享session,使用同步Mysql 數據的方式。這種方式跟方式3類似,同樣可以采用memcached來做,nosql也可以實現,這些都不是問題。
 
5. 使用硬件設備
       這個算是比較成熟的解決方案了,使用類似BIG-IP的負載設備來實現資源共享,那么就能夠又穩定又合理的的共享Session了。目前很多門戶網站采用這種方式。缺點很明顯了,就是要收費了,硬件設備肯定需要購買成本的,不過對於專業或者大型應用來講,是比較合理並且值得的,這種方式可以放到最后面考慮。
 
 

使用Memcached實現Session共享

由於Cookie是保存的用戶客戶端的,安全性存在問題,為保證用戶數據的安全性,我們必須使用Session機制來保存用戶登錄后的一些信息。 
如果我們使用LVS對Apache實現負載均衡,就無法保證用戶每次都能被分配到同一台Apache Server上,以取到自己的Session,雖然LVS可以加-p參數來保證客戶端每次都被分配到同一台Apache Server上,但這種方式存在一些弊端,比如必須設置一個保持時間,如果時間太長了,LVS就需要緩存大量信息,時間太短了,又不能保證用戶每次被分配到同一台Server上,而且這種方式也不易實現Session的冗余備份。 
因此,我們需要Session共享,也就是說每台Apache都可以訪問到所有的Session,這樣用戶被分配到哪台Server就不重要了。 
Session共享主要有多種實現方式: 
 Session復制。Apache可以實現把Session同步到其他Server上去,但這種技術太復雜,而且影響性能,占用內存,所以不推薦使用。 
 Session集中存儲。存儲介質可以是NFS文件系統、數據庫、Memcached,從性能上考慮,當然是Memcached最好,推薦使用。
1.3 實現 
1.3.1 安裝Memcached 
Memcached是基於libevent實現的,所以要首先確保已經安裝libevent。 
安裝libevent 
tar zxvf libevent-1.4.13-stable.tar.gz 
cd libevent-1.4.13-stable 
./configure --prefix=/usr 
make && make install 
安裝Memcached 
tar zxvf memcached-1.4.4.tar.gz 
cd memcached-1.4.4 
./configure --prefix=/usr/local/memcached --with-libevent=/usr 
make && make install 
啟動Memcached 

/usr/local/memcached/bin/memcached -d -m 10 -u root -l 192.168.0.9 -p 11211 -c 256 -P /tmp/memcached.pid 
1.3.2 安裝PHP擴展pecl::memcache 
pecl install memcache 
或源碼安裝 
tar zxvf memcache-2.2.5.tgz 
cd memcache-2.2.5 
phpize 
./configure 
make && make install 

將 php.ini 中 extension=memcache.so 打開,重啟一下 apache,查看 phpinfo 中的 "Registered save handlers" 會有"files user memcache" 這3個可用。 

另外,基於libmemached的php擴展在pecl發布了,叫pecl::memcached,性能上可能會更好。 
1.3.3 配置Memcached保存Session 
修改配置文件,在 php.ini 中全局設置 
session.save_handler = memcache 
session.save_path = "tcp://192.168.0.9:11211" 
或者某個目錄下的 .htaccess : 
php_value session.save_handler "memcache" 
php_value session.save_path "tcp://192.168.0.9:11211" 
再或者在某個一個應用中: 
ini_set("session.save_handler", "memcache"); 
ini_set("session.save_path", "tcp://192.168.0.9:11211"); 
使用多個 memcached server 時用逗號","隔開,並且和 Memcache::addServer() 文檔中說明的一樣,可以帶額外的參數"persistent"、"weight"、"timeout"、"retry_interval" 等等,類似這樣的:"tcp://host1:port1?persistent=1&weight=2,tcp://host2:port2" 。 
1.3.4 測試 
<?php 
session_start(); 
if (!isset($_SESSION['TEST'])) { 
$_SESSION['TEST'] = time(); 

$_SESSION['TEST3'] = time(); 
print $_SESSION['TEST']; 
print "<br><br>"; 
print $_SESSION['TEST3']; 
print "<br><br>"; 
print session_id(); 
?> 

可以直接用sessionid 去 memcached 里查詢一下: 
telnet 192.168.0.9 11211 
get 19216821213c65cedec65b0883238c278eeb573e077 
得到 
TEST|i:1177556731;TEST3|i:1177556881; 
這樣的結果,說明session 正常工作 

用Memcached來存儲 session 在讀寫速度上會比文件快很多,而且在多個服務器需要共用session時會比較方便,將這些服務器都配置成使用同一組Memcached服務器就可以,減少了額外的工作量。缺點是 session 數據都保存在 memory 中,持久化方面有所欠缺,但對 session 數據來說也不是很大的問題,如果要持久化數據,也可以使用新浪開發的MemcacheDB或日本人開發的Tokyo tyrant+Tokyo Cabinet。 
另外,如何解決Memcached的單點故障問題,有以下幾個方案: 
 使用上面提到的Memcache::addServer增加多台Memcached,但這樣只能達到一台出故障之后,另外一台可以使用,但每台Memcached的數據是獨立的,不共享,不復制,出故障的數據丟失了。 
 使用Memcached的一個補丁應用repcached,可以實現multi master replication和asynchronous data repliacation,並且支持原來Memcached的所有命令。不過這個應用只支持Memcached1.2.x版本。 
 使用Tokyo tyrant+Tokyo Cabinet(簡稱TT+TC)。TT兼容Memcached協議,可以直接替換使用,TT支持replication,可以實現故障轉移,TC則為TT提供持久化。 
TT+TC是日本最大的社交類網站http://mixi.jp開發的開源應用,並已成功應用在mixi.jp中,值得研究。
 
原文地址:http://www.cnblogs.com/xyxxs/p/4542791.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM