熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> PHP編程 >> 正文

基於php使用memcache存儲session的詳解

2013-11-15 12:25:56  來源: PHP編程 

  web服務器的php session都給memcached 這樣你不管分發器把 ip連接分給哪個web服務器都不會有問題了配置方法很簡單就在php的配置文件內
增加一條語句就可以了不過前提你需要裝好memcache模塊

  設置session用memcache來存儲
方法I: 在 phpini 中全局設置
sessionsave_handler = memcache
sessionsave_path = "tcp://:"
方法II 某個目錄下的 htaccess
php_value sessionsave_handler "memcache"
php_value sessionsave_path "tcp://:"
方法III 再或者在某個一個應用中
ini_set("sessionsave_handler" "memcache");
ini_set("sessionsave_path" "tcp://:");
使 用多個 memcached server 時用逗號""隔開並且和 Memcache::addServer() 文檔中說明的一樣可以帶額外的參數"persistent""weight""timeout""retry_interval" 等等類似這樣的"tcp://host:port?persistent=&weight=tcp://host:port"
如果安裝的PECL是memcached(使用libmemcache庫的那個)則配置應為
ini_set("sessionsave_handler" "memcached"); // 是memcached不是memcache
ini_set("sessionsave_path" ":"); // 不要tcp:

   啟動 memcached
memcached d l p m
或 啟動Memcache的服務器端
memcached d m u root l p c P /tmp/memcachedpid
# /usr/local/bin/memcached d m u root l p c P /tmp/memcachedpid
引用
d選項是啟動一個守護進程
m是分配給Memcache使用的內存數量單位是MB我這裡是MB
u是運行Memcache的用戶我這裡是root
l是監聽的服務器IP地址如果有多個地址的話我這裡指定了服務器的IP地址
p是設置Memcache監聽的端口我這裡設置了最好是以上的端口我們這裡統一使用
c選項是最大運行的並發連接數默認是我這裡設置了按照你服務器的負載量來設定
P是設置保存Memcache的pid文件我這裡是保存在/tmp/memcachedpid

   在程序中使用 memcache 來作 session 存儲
用例子測試一下

復制代碼 代碼如下:
<?php
session_start();
if (!isset($_SESSION[TEST])) {
$_SESSION[TEST] = time();
}

$_SESSION[TEST] = time();

print $_SESSION[TEST];
print "<br><br>";
print $_SESSION[TEST];
print "<br><br>";
print session_id();
?>

  
用 sessionid 去 memcached 裡查詢一下

復制代碼 代碼如下:
<?php
$memcache = memcache_connect(localhost );
var_dump($memcache>get(ccedecbceebe));
$memcache>set(aaaa hello everyone);
var_dump($memcache>get(aaaa));
?>

  
會看到
string() "TEST|i:;TEST|i:;"
這樣的輸出證明 session 正常工作
用 memcache 來存儲 session 在讀寫速度上會比 files 時快很多而且在多個服務器需要共用 session 時會比較方便將這些服務器都配置成使用同一組 memcached 服務器就可以減少了額外的工作量缺點是 session 數據都保存在 memory 中持久化方面有所欠缺但對 session 數據來說也不是很大的問題
===================================
一 般地 Session 是以文本文件形式存儲在服務器端的如果使用 Seesion或者該 PHP 文件要調用 Session 變量那麼就必須在調用 Session 之前啟動它使用 session_start() 函數其它都不需要你設置了PHP 自動完成 Session 文件的創建其默認 Session 的存放路徑是服務器的系統臨時文件夾
但是如果碰到大數據量的Sesstion的時候 使用基於文件的Session存取瓶頸可能都是在磁盤IO操作上現在利用Memcached來保存Session數據直接通過內存的方式效率自然能 夠提高不少 在讀寫速度上會比 files 時快很多而且在多個服務器需要共用 session 時會比較方便將這些服務器都配置成使用同一組 memcached 服務器就可以減少了額外的工作量

其缺點是 session 數據都保存在 memory 中一旦宕機數據將會丟失但對 session 數據來說並不是嚴重的問題
如何用 memcached 來存儲 session呢?以下是基本的配置步驟
安裝 memcached
在 phpinfo 輸出中的 “Registered save handlers” 會有 “files user sqlite”

   修改配置文件
a 在 phpini 中全局設置(* 需要重啟服務器)
sessionsave_handler = memcache
sessionsave_path = "tcp://:"
b 或者某個目錄下的 htaccess :
php_value sessionsave_handler "memcache"
php_value sessionsave_path "tcp://:"
c 也可以在某個一個應用中
ini_set("sessionsave_handler" "memcache");
ini_set("sessionsave_path" "tcp://:");
使 用多個 memcached server 時用逗號””隔開並且和 Memcache::addServer() 文檔中說明的一樣可以帶額外的參數”persistent””weight””timeout””retry_interval” 等等類似這樣的”tcp://host:port?persistent=&weight=tcp://host :port

   啟動 memcached
memcached d m u root l p c P /tmp/memcachedpid

  測試 創建一個 session

復制代碼 代碼如下:
<?php
//set_sessionphp
session_start();
if (!isset($_SESSION[admin])) {
$_SESSION[TEST] = wan;
}
print $_SESSION[admin];
print "n";
print session_id();
?>

  
用 sessionid 去 memcached 裡查詢一下

復制代碼 代碼如下:
<?php
//get_sessionphp
$mem = new Memcache;
$mem>connect("" );
var_dump($mem>get(dbcddfefbaffa ));
?> 復制代碼 代碼如下:
[root@localhost html]# /usr/local/webserver/php/bin/php f get_sessionphp

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

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

保存在Memcached中的數據最長不會超過這個時間是以操作Memcached的時間為基准的 也就是說只要key還是原來的key如果你重新對此key進行了相關的操作(如set操作)且重新設置了有效期則此時此key對應的數據的有效期 會重新計算的php手冊中有說明

Expiration time of the item If its 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 ( days)

Memcached主要的cache機制是LRU(最近最少用)算法+超時失效當您存數據到memcached中可以指定該數據在緩存中可以呆多久如果memcached的內存不夠用了過期的slabs會優先被替換接著就輪到最老的未被使用的slabs
===========================
為了使web應用能使用saas模式的大規模訪問必須實現應用的集群部署要實現集群部署主要需要實現session共享機制使得多台應用服務器之間會話統一 tomcat等多數服務都采用了session復制技術實現session的共享
session復制技術的問題:
()技術復雜必須在同一種中間件之間完成(如:tomcattomcat之間)
()在節點持續增多的情況下session復制帶來的性能損失會快速增加特別是當session中保存了較大的對象而且對象變化較快時性能下降更加顯著這種特性使得web應用的水平擴展受到了限制

session 共享的另一種思路就是把session集中起來管理首先想到的是采用數據庫來集中存儲session但數據庫是文件存儲相對內存慢了一個數量級同時 這勢必加大數據庫系統的負擔所以需要一種既速度快又能遠程集中存儲的服務所以就想到了memcached

  memcached能緩存什麼?
通過在內存裡維護一個統一的巨大的hash表Memcached能夠用來存儲各種格式的數據包括圖像視頻文件以及數據庫檢索的結果等

  memcached快麼?
非 常快memcached使用了libevent(如果可以的話在linux下使用epoll)來均衡任何數量的打開鏈接使用非阻塞的網絡I/O對 內部對象實現引用計數(因此針對多樣的客戶端對象可以處在多樣的狀態) 使用自己的頁塊分配器和哈希表 因此虛擬內存不會產生碎片並且虛擬內存分配的時間復雜度可以保證為O()
使用過程注意幾個問題和改進思路
memcache的內存應該足夠大這樣不會出現用戶session從Cache中被清除的問題(可以關閉memcached的對象退出機制)
如果session的讀取比寫入要多很多可以在memcache前再加一個Oscache等本地緩存減少對memcache的讀操作從而減小網絡開銷提高性能
如果用戶非常多可以使用memcached組通過set方法中帶hashCode插入到某個memcached服務器
對於session的清除有幾種方案:
()可以在凌晨人最少的時候對memcached做一次清空(簡單)
()保存在緩存中的對象設置一個失效時間通過過濾器獲取sessionId的值定期刷新memcached中的對象長時間沒有被刷新的對象自動被清除(相對復雜消耗資源)


From:http://tw.wingwit.com/Article/program/PHP/201311/20946.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.