首頁  >  文章  >  後端開發  >  php如何將session保存到memcached中?如何分散式保存php session

php如何將session保存到memcached中?如何分散式保存php session

伊谢尔伦
伊谢尔伦原創
2016-11-26 14:52:491148瀏覽

session_set_save_handler無關的memcached保存session的方法

在memcached伺服器上

1)下載memcached

#wget http://memcached.code.com/files/meach由於memcached依賴libevent需要先安裝libevent庫,這裡直接yum安裝

#yum install *libevent*

3)安裝memcached

#./configure --prefix=/usr/local/memcached

#./configure --prefix=/usr/local/memcached# make install


4)啟動memcached

#/usr/local/memcached/bin/memcached -d -m 4096 -p 11211 -u root

-d daemon ?-p port -p 11211 -u root

-d daemon ?-p port -u web server伺服器上


5)在web server上安裝php的memcache模組

#/usr/local/php/bin/pecl install memcache

Enable memcache session handler support? [

6)在php.ini加入以下內容:

extension=/usr/local/php/lib/php/extensions/no-debug-non-zts-20090626/memcache.so

7)修改php. ini中的session.save_handler及session.save_path為以下內容:

session.save_handler = memcache

session.save_path = "tcp://memcached伺服器ip:11211set

= "tcp://memcached伺服器ip:11211」 session.save_handler', 'memcache');

ini_set('session.save_path', 'tcp://memcached伺服器ip:11211');

注意:這個使用meached安裝完memcached之後

在php.ini中

將session.save_handler 修改為memcache,並修改save_path指向memcached的地址和端口即可

session.save_handler = memcache

session.save_path = tcp://127.0 .0.1:11211memcache的PECL這個擴充非常強大,可以支援failover以及分散式儲存。

使用方法很簡單,只需要在session.save_path的參數清單中,使用逗號分隔各個memcached伺服器,如:

session.save_path = "tcp://172.16.8.81:11211,tc = "tcp://172.16.8.81:11211,tcp://172.16. 8.82:11211,tcp://172.16.8.83:11211"

則保存的session會經過hash之後保存到各個memcached伺服器中,而hash的演算法memcache支援兩種,crc32以及fnv:

)演算法. {crc32,fnv}

文檔中很少有提到fnv演算法的,據說其散列要比crc32更好,但是我透過以下小小的程式實驗之後,發現仍舊是crc32的雜湊演算法分佈的更加平均。

<?php
ini_set("memcache.hash_function", "crc32");
$memcache = new Memcache;
$memcache1 = new Memcache;
$memcache2 = new Memcache;
$memcache->addServer(&#39;localhost&#39;, 11211);
$memcache->addServer(&#39;localhost&#39;, 11212);
$memcache->flush();
$memcache1->connect(&#39;localhost&#39;, 11211);
$memcache2->connect(&#39;localhost&#39;, 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的保存進行了測試

我開了3個memcached進程進行測試

<?php
ini_set("memcache.hash_function", "fnv");
ini_set("error_reporting", "E_CORE_ERROR");
$memcache1 = new Memcache;
$memcache1->connect(&#39;localhost&#39;, 11211);
$memcache1->flush();
$memcache2 = new Memcache;
$memcache2->connect(&#39;localhost&#39;, 11212);
$memcache2->flush();
$memcache3 = new Memcache;
$memcache3->connect(&#39;localhost&#39;, 11213);
$memcache3->flush();
$fp1 = fopen(&#39;mem1.txt&#39;, &#39;w&#39;);
$fp2 = fopen(&#39;mem2.txt&#39;, &#39;w&#39;);
$fp3 = fopen(&#39;mem3.txt&#39;, &#39;w&#39;);
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) . &#39; &#39;);
fwrite($fp2, $memcache2->get($ssid) . &#39; &#39;);
fwrite($fp3, $memcache3->get($ssid) . &#39; &#39;);
//session_destroy();
}
fclose($fp1);
fclose($fp2);
fclose($fp3);

比較奇怪的是 memcached2一般都會不被選中,

而1,3的內容是一致的。可能是為了failover,

而當我把1,3關閉後,2中將會出現內容,說明memcached2是正常工作的。

而不論我的雜湊演算法使用crc32還是fnv,這種現像都存在,

最後我發現:這個測試程式有問題。

因為在session_write_close之後,整個程式的session都是唯一的了。

也就是雖然循環了這麼多次,裡麵包含了session_destroy調用,但是返回的session id都是一樣的。

這就導致了兩個文件中的內容一致而另一個文件中沒有內容,

基於此點,

我只能分次調用腳本,腳本修改如下:

<?php
ini_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(&#39;localhost&#39;, 10001);
$memcache1->flush();
$memcache2 = new Memcache;
$memcache2->connect(&#39;localhost&#39;, 10002);
$memcache2->flush();
$memcache3 = new Memcache;
$memcache3->connect(&#39;localhost&#39;, 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中重複運行多次,返回的ID不同了。

再開啟mem*.txt檔案查看,

發現3個檔案中,每個session會儲存在其中兩個文件,然後分佈不同。

這證明了使用memcache來保存session,一個是做到了failover,第二會按照session id來做hash分佈保存。

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn