ホームページ  >  記事  >  バックエンド開発  >  PHPでセッションをmemcachedに保存するにはどうすればよいですか? PHPセッションを分散保存する方法

PHPでセッションをmemcachedに保存するにはどうすればよいですか? PHPセッションを分散保存する方法

伊谢尔伦
伊谢尔伦オリジナル
2016-11-26 14:52:491141ブラウズ

session_set_save_handler は、memcached のセッション保存方法とは何の関係もありません

memcached サーバー上で

1) memcached をダウンロードします

#wget http://memcached.googlecode.com/files/memcached-1.4.15.tar.gz

2) memcached は libevent に依存しているため、最初に libevent ライブラリをインストールする必要があります。これが直接 yum インストールです

#yum install *libevent*

3) memcached をインストールします

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

4) memcached

#/usr/local/memcached/bin/memcached -d -m 4096 -p 11211 -u root
-d daemon ?-p port - を起動します。 u ?user -mmemory

in Webサーバーserver上

5) Webサーバーにphp memcacheモジュールをインストールします

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

memcacheセッションハンドラーサポートを有効にしますか? [はい] : はい (ここで [はい] を選択します)

6) 次の内容を php.ini に追加します:

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

7) ini の session.save_handler と session.save_path を次のように変更します。 PHP プログラムでも使用できます

ini_set(' session.save_handler', 'memcache');
ini_set('session.save_path', 'tcp://memcached server ip:11211');

注: この方法memcached を使用してセッションを保存することは、session_set_save_handler とは何の関係もありません


memcached をインストールした後、php.ini で session.save_handler を memcache に変更し、memcached のアドレスとポートを指すように save_path を変更します

session.save_handler = memcache

session.save_path = tcp://127.0 .0.1:11211

memcache の PECL 拡張機能は非常に強力で、フェイルオーバーと分散ストレージをサポートできます。

使用方法は非常に簡単です。次のように、session.save_path のパラメーター リストで各 memcached サーバーを区切るためにカンマを使用するだけです:

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

保存されたセッションはハッシュされて、各 memcached サーバーに保存されます。Memcache は 2 つのハッシュ アルゴリズム、crc32 と fnv をサポートしています:


memcache.hash_function= { 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);

それからセッションの保存をテストしました

テストのためにmemcachedプロセスを3つ開いてみました

<?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の内容は一致しています。フェイルオーバーのためかもしれません

そして 1 と 3 をオフにすると、2 にコンテンツが表示され、memcached2 が正常に動作していることがわかります。

この現象は、ハッシュ アルゴリズムが crc32 を使用しているか fnv を使用しているかに関係なく存在します。

最終的に、このテスト プログラムには問題があることがわかりました。

session_write_close の後、プログラム全体のセッションは一意になるためです。

つまり、session_destroy 呼び出しを含め、ループが何度もループされているにもかかわらず、返されるセッション ID は同じです。

これにより、2 つのファイルの内容は一致しますが、もう 1 つのファイルには内容がありません。

これに基づいて、スクリプトは次のように変更されます。

<?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);

その後、実行します。シェル内で何度も繰り返し実行すると、返される ID は異なります。

mem*.txt ファイルを再度開いて表示すると、

3 つのファイルのうち、各セッションが 2 つのファイルに保存され、配布が異なることがわかりました。

これは、memcache がセッションの保存に使用されることを証明します。1 つはフェイルオーバーを実現するため、もう 1 つはセッション ID に従ってハッシュ分散を実行して保存するためです。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。