字體:  

如何在多台Web Server 下...用 Memcached 存儲 Session

ppstream 發表於: 2013-8-11 10:25 來源: ADJ網路控股集團




php中的Session默認是用文件的方式存儲的,如果用多臺WEB服務器,Session共享可能就會成爲一個大的問題,可以用NFS共享的方式來存儲,但是對於併發請求更多的站點來說,用NFS也會出現問題,下面就說說用Memcached來保存Session的問題。

vi memcached_session.php,輸入如下的代碼
<?php
$ip = '192.168.1.111';
$port = 11211;
ini_set("session.save_handler", "memcache");
ini_set("session.save_path", "tcp://$ip:$port");

session_start();
$_SESSION['time'] = time();
 
print 'time:' . $_SESSION['time'];
print "<br>";
$key = session_id();
print 'session_id:' . $key;
print "<br>";

$memcache = new Memcache;
$memcache->addServer($ip, $port);
echo "ke: $key value:" . $memcache -> get($key);
?>
程序的輸出結果如下:
time:1251362605
session_id:7c694d1c2fea5dd3c56f7a19d2f925c9
ke: 7c694d1c2fea5dd3c56f7a19d2f925c9 value:time|i:1251362604;

從上圖可以看出,保存在Memcached中的Session數據,key爲客戶端生成的SessionID,也就是名爲PHPSESSID的cookie保存的值,值爲Session的值($_SESSION['time'] = time();)

上述結果可以說明Session數據已經成功保存到Memcached中了

當然也可以直接在php.ini中修改全局配置,這樣,不需要在每個與session有關的程序都需要調用ini_set了
session.save_handler = memcache
session.save_path = "tcp://192.168.1.111:11211"

使用多個memcached server 時用逗號","隔開,並且和 Memcache::addServer() 文檔中說明的一樣,可以帶額外的參數"persistent"、"weight"、"timeout"、"retry_interval" 等等,類似這樣的:"tcp://host1:port1?persistent=1&weight=2,tcp://host2:port2" 。

也可以直接telnet到Memcached中用get session_id來查找Session數據
[root@CentOS_Test_Server ~]# telnet 192.168.1.111 11211
Trying 192.168.1.111...
Connected to 192.168.1.111 (192.168.1.111).
Escape character is '^]'.
get 7c694d1c2fea5dd3c56f7a19d2f925c9
VALUE 7c694d1c2fea5dd3c56f7a19d2f925c9 0 18
time|i:1251362209;
END
set name 0 0 10
caihuafeng
STORED
get name
VALUE name 0 10
caihuafeng
END

用 memcache 來存儲 session 在讀寫速度上應該會比文件快很多,而且在多個服務器需要共用 session 時會比較方便,將這些服務器都配置成使用同一組 memcached 服務器就可以,減少了額外的工作量。缺點是 session 數據都保存在內存中,不能持久化存儲,如果想持久化存儲,可以考慮使用Memcachedb來存儲,或用Tokyo Tyrant+Tokyo Cabinet來進行存儲。

怎樣判斷session失效了呢?在php.ini中有個Session.cookie_lifetime的選項,這個代表SessionID在客戶端Cookie儲存的時間,默認值是“0”,代表瀏覽器一關閉,SessionID就作廢,這樣不管保存在Memcached中的Session是否還有效(保存在Memcached中的session會利用Memcached的內部機制進行處理,即使session數據沒有失效,而由於客戶端的SessionID已經失效,所以這個key基本上不會有機會使用了,利用Memcached的LRU原則,如果Memcached的內存不夠用了,新的數據就會取代過期以及最老的未被使用的數據),因爲SessionID已經失效了,所以在客戶端會重新生成一個新的SessionID。

保存在Memcached中的數據最長不會超過30天,這個時間是以操作Memcached的時間爲基準的,也就是說,只要key還是原來的key,如果你重新對此key進行了相關的操作(如set操作),且重新設置了有效期,則此時此key對應的數據的有效期會重新計算的,php手冊中有說明
Expiration time of the item. If it's equal to zero, the item will never expire. You can also use Unix timestamp or a number of seconds starting from current time, but in the latter case the number of seconds may not exceed 2592000 (30 days).

Memcached主要的cache機制是LRU(最近最少用)算法+超時失效。當您存數據到memcached中,可以指定該數據在緩存中可以呆多久。如果memcached的內存不夠用了,過期的slabs會優先被替換,接着就輪到最老的未被使用的slabs。

From: http://tc.itkee.com/database/detail-ef0.html