PHP如何將session保存到memcached中?如何分布式保存PHP session
在memcached服務(wù)器上
1)下載memcached
#wget http://memcached.googlecode.com/files/memcached-1.4.15.tar.gz2)由于memcached依賴libevent所以需要先安裝libevent庫(kù),這里直接yum安裝
#yum install *libevent*3)安裝memcached
#./configure --prefix=/usr/local/memcached#make#make install4)啟動(dòng)memcached
#/usr/local/memcached/bin/memcached -d -m 4096 -p 11211 -u root-d daemon ?-p port -u ?user -m memory在web server服務(wù)器上
5)在web server上安裝php的memcache模塊
#/usr/local/php/bin/pecl install memcacheEnable memcache session handler support? [yes] : yes(這里選擇yes)6)在php.ini中加入如下內(nèi)容:
extension=/usr/local/php/lib/php/extensions/no-debug-non-zts-20090626/memcache.so7)修改php.ini中的session.save_handler及session.save_path為如下內(nèi)容:
session.save_handler = memcachesession.save_path = 'tcp://memcached服務(wù)器ip:11211'亦可在PHP程序中
ini_set(’session.save_handler’, ’memcache’);ini_set(’session.save_path’, ’tcp://memcached服務(wù)器ip:11211’);注意:這種使用memcached保存session的方式與session_set_save_handler無(wú)關(guān)
安裝完memcached之后
在php.ini中
將session.save_handler 修改為memcache,并修改save_path指向memcached的地址和端口即可
session.save_handler = memcachesession.save_path = tcp://127.0.0.1:11211
memcache的PECL這個(gè)擴(kuò)展非常強(qiáng)大,可以支持failover以及分布存儲(chǔ)。
使用方法很簡(jiǎn)單,只需要在session.save_path的參數(shù)列表中,使用逗號(hào)分隔各個(gè)memcached服務(wù)器,如:
session.save_path = 'tcp://172.16.8.81:11211,tcp://172.16.8.82:11211,tcp://172.16.8.83:11211'
則保存的session會(huì)經(jīng)過(guò)hash之后保存到各個(gè)memcached服務(wù)器中,而hash的算法memcache支持兩種,crc32以及fnv:
memcache.hash_function= {crc32,fnv}
文檔中很少有提到fnv算法的,據(jù)說(shuō)其散列要比crc32更好,但是我通過(guò)以下小小的程序?qū)嶒?yàn)之后,發(fā)現(xiàn)仍舊是crc32的散列算法分布的更加平均。
<?phpini_set('memcache.hash_function', 'crc32');$memcache = new Memcache;$memcache1 = new Memcache;$memcache2 = new Memcache;$memcache->addServer(’localhost’, 11211);$memcache->addServer(’localhost’, 11212);$memcache->flush();$memcache1->connect(’localhost’, 11211);$memcache2->connect(’localhost’, 11212);$fp1 = fopen('mem1.txt', 'w');$fp2 = fopen('mem2.txt', 'w');for ($i = 0; $i < 1000; $i++){$memcache->set($i, $i, 0, 1000);fwrite($fp1, $memcache1->get($i) . ' ');fwrite($fp2, $memcache2->get($i) . ' ');}fclose($fp1);fclose($fp2);
接著我就session的保存進(jìn)行了測(cè)試
我開(kāi)了3個(gè)memcached進(jìn)程進(jìn)行測(cè)試
<?phpini_set('memcache.hash_function', 'fnv');ini_set('error_reporting', 'E_CORE_ERROR');$memcache1 = new Memcache;$memcache1->connect(’localhost’, 11211);$memcache1->flush();$memcache2 = new Memcache;$memcache2->connect(’localhost’, 11212);$memcache2->flush();$memcache3 = new Memcache;$memcache3->connect(’localhost’, 11213);$memcache3->flush();$fp1 = fopen(’mem1.txt’, ’w’);$fp2 = fopen(’mem2.txt’, ’w’);$fp3 = fopen(’mem3.txt’, ’w’);for ($i = 0; $i < 1000; $i++){session_start();$ssid = session_id();echo $ssid;session_register('id');$_SESSION['id'] = $ssid;session_write_close();fwrite($fp1, $memcache1->get($ssid) . ’ ’);fwrite($fp2, $memcache2->get($ssid) . ’ ’);fwrite($fp3, $memcache3->get($ssid) . ’ ’);//session_destroy();}fclose($fp1);fclose($fp2);fclose($fp3);
比較奇怪的是 memcached2一般都會(huì)不被選中,
而1,3的內(nèi)容是一致的??赡苁菫榱薴ailover,
而當(dāng)我把1,3關(guān)閉后,2中將會(huì)出現(xiàn)內(nèi)容,說(shuō)明memcached2是正常工作的。
而不論我的散列算法使用crc32還是fnv,這種現(xiàn)象都存在,
最后我發(fā)現(xiàn):這個(gè)測(cè)試程序存在問(wèn)題。
因?yàn)樵趕ession_write_close之后,整個(gè)程序的session都是唯一的了。
也就是雖然循環(huán)了這么多次,里面包含了session_destroy調(diào)用,但是返回的session id都是同樣的。
這就導(dǎo)致了兩個(gè)文件中的內(nèi)容一致而另一個(gè)文件中沒(méi)有內(nèi)容,
基于此點(diǎn),
我只能分次調(diào)用腳本,腳本修改如下:
<?phpini_set('memcache.hash_strategy', 'consistent');ini_set('memcache.hash_function', 'crc32');ini_set('error_reporting', 'E_CORE_ERROR');ini_set('memcache.allow_failover', '0');$memcache1 = new Memcache;$memcache1->connect(’localhost’, 10001);$memcache1->flush();$memcache2 = new Memcache;$memcache2->connect(’localhost’, 10002);$memcache2->flush();$memcache3 = new Memcache;$memcache3->connect(’localhost’, 10003);$memcache3->flush();$fp1 = fopen('mem1.txt', 'a+');$fp2 = fopen('mem2.txt', 'a+');$fp3 = fopen('mem3.txt', 'a+');session_start();$ssid = session_id();echo $ssid . 'n';session_register('id');$_SESSION['id'] = $ssid;//session_destroy();session_write_close();fwrite($fp1, $memcache1->get($ssid) . ' ');fwrite($fp2, $memcache2->get($ssid) . ' ');fwrite($fp3, $memcache3->get($ssid) . ' ');session_destroy();fclose($fp1);fclose($fp2);fclose($fp3);
然后再shell中重復(fù)運(yùn)行多次,返回的ID不同了。
再打開(kāi)mem*.txt文件查看,
發(fā)現(xiàn)3個(gè)文件中,每個(gè)session會(huì)保存在其中兩個(gè)文件,然后分布不同。
這證明了使用memcache來(lái)保存session,一個(gè)是做到了failover,第二會(huì)按照session id來(lái)做hash分布保存。
相關(guān)文章:
1. ASP刪除img標(biāo)簽的style屬性只保留src的正則函數(shù)2. 低版本IE正常運(yùn)行HTML5+CSS3網(wǎng)站的3種解決方案3. HTML5 Canvas繪制圖形從入門到精通4. 讀大數(shù)據(jù)量的XML文件的讀取問(wèn)題5. css代碼優(yōu)化的12個(gè)技巧6. jsp+servlet實(shí)現(xiàn)猜數(shù)字游戲7. asp批量添加修改刪除操作示例代碼8. PHP循環(huán)與分支知識(shí)點(diǎn)梳理9. ASP.NET MVC使用異步Action的方法10. ASP實(shí)現(xiàn)加法驗(yàn)證碼
