基于php使用memcache存儲(chǔ)session的詳解
web服務(wù)器的php session都給memcached ,這樣你不管分發(fā)器把 ip連接分給哪個(gè)web服務(wù)器都不會(huì)有問題了,配置方法很簡(jiǎn)單,就在php的配置文件內(nèi)
增加一條語(yǔ)句就可以了,不過前提你需要裝好memcache模塊
1.設(shè)置session用memcache來(lái)存儲(chǔ)
方法I: 在 php.ini 中全局設(shè)置
session.save_handler = memcache
session.save_path = "tcp://127.0.0.1:11211"
方法II: 某個(gè)目錄下的 .htaccess :
php_value session.save_handler "memcache"
php_value session.save_path "tcp://127.0.0.1:11211"
方法III: 再或者在某個(gè)一個(gè)應(yīng)用中:
ini_set("session.save_handler", "memcache");
ini_set("session.save_path", "tcp://127.0.0.1:11211");
使用多個(gè) memcached server 時(shí)用逗號(hào)","隔開,并且和 Memcache::addServer() 文檔中說明的一樣,可以帶額外的參數(shù)"persistent"、"weight"、"timeout"、"retry_interval" 等等,類似這樣的:"tcp://host1:port1?persistent=1&weight=2,tcp://host2:port2" 。
如果安裝的PECL是memcached(使用libmemcache庫(kù)的那個(gè)),則配置應(yīng)為
ini_set("session.save_handler", "memcached"); // 是memcached不是memcache
ini_set("session.save_path", "127.0.0.1:11211"); // 不要tcp:
2. 啟動(dòng) memcached:
memcached -d -l 127.0.0.1 -p 11212 -m 128
或 啟動(dòng)Memcache的服務(wù)器端:
memcached -d -m 100 -u root -l 192.168.36.200 -p 11211 -c 256 -P /tmp/memcached.pid
# /usr/local/bin/memcached -d -m 10 -u root -l 192.168.0.200 -p 12000 -c 256 -P /tmp/memcached.pid
引用
-d選項(xiàng)是啟動(dòng)一個(gè)守護(hù)進(jìn)程,
-m是分配給Memcache使用的內(nèi)存數(shù)量,單位是MB,我這里是100MB,
-u是運(yùn)行Memcache的用戶,我這里是root,
-l是監(jiān)聽的服務(wù)器IP地址,如果有多個(gè)地址的話,我這里指定了服務(wù)器的IP地址192.168.36.200,
-p是設(shè)置Memcache監(jiān)聽的端口,我這里設(shè)置了11211,最好是1024以上的端口,我們這里統(tǒng)一使用11211
-c選項(xiàng)是最大運(yùn)行的并發(fā)連接數(shù),默認(rèn)是1024,我這里設(shè)置了256,按照你服務(wù)器的負(fù)載量來(lái)設(shè)定。
-P是設(shè)置保存Memcache的pid文件,我這里是保存在/tmp/memcached.pid,
3. 在程序中使用 memcache 來(lái)作 session 存儲(chǔ)
用例子測(cè)試一下:
<?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();
?>
4. 用 sessionid 去 memcached 里查詢一下:
<?php
$memcache = memcache_connect('localhost', 11211);
var_dump($memcache->get('19216821213c65cedec65b0883238c278eeb573e077'));
$memcache->set('aaaa', 'hello everyone');
var_dump($memcache->get('aaaa'));
?>
會(huì)看到
string(37) "TEST|i:1177556731;TEST3|i:1177556881;"
這樣的輸出,證明 session 正常工作。
用 memcache 來(lái)存儲(chǔ) session 在讀寫速度上會(huì)比 files 時(shí)快很多,而且在多個(gè)服務(wù)器需要共用 session 時(shí)會(huì)比較方便,將這些服務(wù)器都配置成使用同一組 memcached 服務(wù)器就可以,減少了額外的工作量。缺點(diǎn)是 session 數(shù)據(jù)都保存在 memory 中,持久化方面有所欠缺,但對(duì) session 數(shù)據(jù)來(lái)說也不是很大的問題。
===================================
一般地, Session 是以文本文件形式存儲(chǔ)在服務(wù)器端的。如果使用 Seesion,或者該 PHP 文件要調(diào)用 Session 變量,那么就必須在調(diào)用 Session 之前啟動(dòng)它,使用 session_start() 函數(shù)。其它都不需要你設(shè)置了,PHP 自動(dòng)完成 Session 文件的創(chuàng)建。其默認(rèn) Session 的存放路徑是服務(wù)器的系統(tǒng)臨時(shí)文件夾。
但是如果碰到大數(shù)據(jù)量的Sesstion的時(shí)候, 使用基于文件的Session存取瓶頸可能都是在磁盤IO操作上,現(xiàn)在利用Memcached來(lái)保存Session數(shù)據(jù),直接通過內(nèi)存的方式,效率自然能夠提高不少。 在讀寫速度上會(huì)比 files 時(shí)快很多,而且在多個(gè)服務(wù)器需要共用 session 時(shí)會(huì)比較方便,將這些服務(wù)器都配置成使用同一組 memcached 服務(wù)器就可以,減少了額外的工作量。
其缺點(diǎn)是 session 數(shù)據(jù)都保存在 memory 中,一旦宕機(jī),數(shù)據(jù)將會(huì)丟失。但對(duì) session 數(shù)據(jù)來(lái)說并不是嚴(yán)重的問題。
如何用 memcached 來(lái)存儲(chǔ) session呢?以下是基本的配置步驟:
1. 安裝 memcached
在 phpinfo 輸出中的 “Registered save handlers” 會(huì)有 “files user sqlite”。
2. 修改配置文件,
a. 在 php.ini 中全局設(shè)置(* 需要重啟服務(wù)器)
session.save_handler = memcache
session.save_path = "tcp://127.0.0.1:11211"
b. 或者某個(gè)目錄下的 .htaccess :
php_value session.save_handler "memcache"
php_value session.save_path "tcp://127.0.0.1:11211"
c. 也可以在某個(gè)一個(gè)應(yīng)用中:
ini_set("session.save_handler", "memcache");
ini_set("session.save_path", "tcp://127.0.0.1:11211");
注:使用多個(gè) memcached server 時(shí)用逗號(hào)”,”隔開,并且和 Memcache::addServer() 文檔中說明的一樣,可以帶額外的參數(shù)”persistent”、”weight”、”timeout”、”retry_interval” 等等,類似這樣的:”tcp://host:port?persistent=1&weight=2,tcp://host2 :port2″ 。
3. 啟動(dòng) memcached
memcached -d -m 10 -u root -l 127.0.0.1 -p 11211 -c 256 -P /tmp/memcached.pid
4.測(cè)試 創(chuàng)建一個(gè) session
<?php
//set_session.php
session_start();
if (!isset($_SESSION['admin'])) {
$_SESSION['TEST'] = 'wan';
}
print $_SESSION['admin'];
print "\n";
print session_id();
?>
5. 用 sessionid 去 memcached 里查詢一下
<?php
//get_session.php
$mem = new Memcache;
$mem->connect("127.0.0.1", 11211);
var_dump($mem->get('0935216dbc0d721d629f89efb89affa 6'));
?>
[root@localhost html]# /usr/local/webserver/php/bin/php -f get_session.php
輸出結(jié)果:
string(16)
"admin|s:3:"wan";"
證明 session 正常工作。
===========================
用 memcache 來(lái)存儲(chǔ) session 在讀寫速度上應(yīng)該會(huì)比文件快很多,而且在多個(gè)服務(wù)器需要共用 session 時(shí)會(huì)比較方便,將這些服務(wù)器都配置成使用同一組 memcached 服務(wù)器就可以,減少了額外的工作量。缺點(diǎn)是 session 數(shù)據(jù)都保存在內(nèi)存中,不能持久化存儲(chǔ),如果想持久化存儲(chǔ),可以考慮使用Memcachedb來(lái)存儲(chǔ),或用Tokyo Tyrant+Tokyo Cabinet來(lái)進(jìn)行存儲(chǔ)。
怎樣判斷session失效了呢?在php.ini中有個(gè)Session.cookie_lifetime的選項(xiàng),這個(gè)代表SessionID在客戶端Cookie儲(chǔ)存的時(shí)間,默認(rèn)值是“0”,代表瀏覽器一關(guān)閉,SessionID就作廢,這樣不管保存在Memcached中的Session是否還有效(保存在Memcached中的session會(huì)利用Memcached的內(nèi)部機(jī)制進(jìn)行處理,即使session數(shù)據(jù)沒有失效,而由于客戶端的SessionID已經(jīng)失效,所以這個(gè)key基本上不會(huì)有機(jī)會(huì)使用了,利用Memcached的LRU原則,如果Memcached的內(nèi)存不夠用了,新的數(shù)據(jù)就會(huì)取代過期以及最老的未被使用的數(shù)據(jù)),因?yàn)镾essionID已經(jīng)失效了,所以在客戶端會(huì)重新生成一個(gè)新的SessionID。
保存在Memcached中的數(shù)據(jù)最長(zhǎng)不會(huì)超過30天,這個(gè)時(shí)間是以操作Memcached的時(shí)間為基準(zhǔn)的,也就是說,只要key還是原來(lái)的key,如果你重新對(duì)此key進(jìn)行了相關(guān)的操作(如set操作),且重新設(shè)置了有效期,則此時(shí)此key對(duì)應(yīng)的數(shù)據(jù)的有效期會(huì)重新計(jì)算的,php手冊(cè)中有說明
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機(jī)制是LRU(最近最少用)算法+超時(shí)失效。當(dāng)您存數(shù)據(jù)到memcached中,可以指定該數(shù)據(jù)在緩存中可以呆多久。如果memcached的內(nèi)存不夠用了,過期的slabs會(huì)優(yōu)先被替換,接著就輪到最老的未被使用的slabs。
===========================
為了使web應(yīng)用能使用saas模式的大規(guī)模訪問,必須實(shí)現(xiàn)應(yīng)用的集群部署.要實(shí)現(xiàn)集群部署主要需要實(shí)現(xiàn)session共享機(jī)制,使得多臺(tái)應(yīng)用服務(wù)器之間會(huì)話統(tǒng)一, tomcat等多數(shù)服務(wù)都采用了session復(fù)制技術(shù)實(shí)現(xiàn)session的共享.
session復(fù)制技術(shù)的問題:
(1)技術(shù)復(fù)雜,必須在同一種中間件之間完成(如:tomcat-tomcat之間).
(2)在節(jié)點(diǎn)持續(xù)增多的情況下,session復(fù)制帶來(lái)的性能損失會(huì)快速增加.特別是當(dāng)session中保存了較大的對(duì)象,而且對(duì)象變化較快時(shí),性能下降更加顯著.這種特性使得web應(yīng)用的水平擴(kuò)展受到了限制.
session共享的另一種思路就是把session集中起來(lái)管理,首先想到的是采用數(shù)據(jù)庫(kù)來(lái)集中存儲(chǔ)session,但數(shù)據(jù)庫(kù)是文件存儲(chǔ)相對(duì)內(nèi)存慢了一個(gè)數(shù)量級(jí),同時(shí)這勢(shì)必加大數(shù)據(jù)庫(kù)系統(tǒng)的負(fù)擔(dān).所以需要一種既速度快又能遠(yuǎn)程集中存儲(chǔ)的服務(wù),所以就想到了memcached.
memcached能緩存什么?
通過在內(nèi)存里維護(hù)一個(gè)統(tǒng)一的巨大的hash表,Memcached能夠用來(lái)存儲(chǔ)各種格式的數(shù)據(jù),包括圖像、視頻、文件以及數(shù)據(jù)庫(kù)檢索的結(jié)果等。
memcached快么?
非常快。memcached使用了libevent(如果可以的話,在linux下使用epoll)來(lái)均衡任何數(shù)量的打開鏈接,使用非阻塞的網(wǎng)絡(luò)I/O,對(duì)內(nèi)部對(duì)象實(shí)現(xiàn)引用計(jì)數(shù)(因此,針對(duì)多樣的客戶端,對(duì)象可以處在多樣的狀態(tài)), 使用自己的頁(yè)塊分配器和哈希表, 因此虛擬內(nèi)存不會(huì)產(chǎn)生碎片并且虛擬內(nèi)存分配的時(shí)間復(fù)雜度可以保證為O(1).。
使用過程注意幾個(gè)問題和改進(jìn)思路:
1、memcache的內(nèi)存應(yīng)該足夠大,這樣不會(huì)出現(xiàn)用戶session從Cache中被清除的問題(可以關(guān)閉memcached的對(duì)象退出機(jī)制)。
2、如果session的讀取比寫入要多很多,可以在memcache前再加一個(gè)Oscache等本地緩存,減少對(duì)memcache的讀操作,從而減小網(wǎng)絡(luò)開銷,提高性能。
3、如果用戶非常多,可以使用memcached組,通過set方法中帶hashCode,插入到某個(gè)memcached服務(wù)器
對(duì)于session的清除有幾種方案:
(1)可以在凌晨人最少的時(shí)候,對(duì)memcached做一次清空。(簡(jiǎn)單)
(2)保存在緩存中的對(duì)象設(shè)置一個(gè)失效時(shí)間,通過過濾器獲取sessionId的值,定期刷新memcached中的對(duì)象.長(zhǎng)時(shí)間沒有被刷新的對(duì)象自動(dòng)被清除.(相對(duì)復(fù)雜,消耗資源)
- PHP開發(fā)負(fù)載均衡指南
- Nginx 安裝筆記(含PHP支持、虛擬主機(jī)、反向代理負(fù)載均衡)
- PHP中使用memcache存儲(chǔ)session的三種配置方法
- 利用Memcached在php下實(shí)現(xiàn)session機(jī)制 替換PHP的原生session支持
- php將session放入memcached的設(shè)置方法
- 在php中設(shè)置session用memcache來(lái)存儲(chǔ)的方法總結(jié)
- thinkPHP多域名情況下使用memcache方式共享session數(shù)據(jù)的實(shí)現(xiàn)方法
- PHP保存session到memcache服務(wù)器的方法
- Ubuntu server 11.04安裝memcache及php使用memcache來(lái)存儲(chǔ)session的方法
- PHP實(shí)現(xiàn)分布式memcache設(shè)置web集群session同步的方法
- PHP實(shí)現(xiàn)負(fù)載均衡下的session共用功能
相關(guān)文章
php簡(jiǎn)單實(shí)現(xiàn)多語(yǔ)言切換的方法
這篇文章主要介紹了php簡(jiǎn)單實(shí)現(xiàn)多語(yǔ)言切換的方法,涉及php字符串、數(shù)組結(jié)合session操作實(shí)現(xiàn)多語(yǔ)言切換的相關(guān)技巧,需要的朋友可以參考下2016-05-05php超快高效率統(tǒng)計(jì)大文件行數(shù)
這篇文章主要介紹了php超快高效率統(tǒng)計(jì)大文件行數(shù)的相關(guān)資料,需要的朋友可以參考下2015-07-07php使用file函數(shù)、fseek函數(shù)讀取大文件效率對(duì)比分析
這篇文章主要對(duì)比分析了php使用file函數(shù)、fseek函數(shù)讀取大文件的效率,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-11-11PHP實(shí)現(xiàn)的隨機(jī)IP函數(shù)【國(guó)內(nèi)IP段】
這篇文章主要介紹了PHP實(shí)現(xiàn)的隨機(jī)IP函數(shù),可實(shí)現(xiàn)輸出國(guó)內(nèi)IP段的功能,涉及php字符串與數(shù)組的計(jì)算操作相關(guān)技巧,需要的朋友可以參考下2016-07-07Linux平臺(tái)php命令行程序處理管道數(shù)據(jù)的方法
這篇文章主要介紹了Linux平臺(tái)php命令行程序處理管道數(shù)據(jù)的方法,結(jié)合實(shí)例形式分析了Linux平臺(tái)管道提示符的功能及php使用命令行處理管道數(shù)據(jù)的相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2016-11-11Thinkphp框架開發(fā)移動(dòng)端接口(1)
這篇文章主要為大家詳細(xì)介紹了Thinkphp框架開發(fā)移動(dòng)端接口,具有一定的實(shí)用性,感興趣的小伙伴們可以參考一下2016-08-08