2

私の質問は、PHP Memcache 拡張機能の addServer 関数の「重み」パラメーターに関連しています。
ここ数か月、すべてのサーバーで「重み = 1」を使用しています。現在、以下の構成を適用して、最終的に「10.10.10.3」をローテーションから削除し、データ損失を最小限に抑えようとしています。
新しい重み値が設定されているため、PHP クライアントは、以前はフェッチできたキーの値を取得できません。「重み = 1」に戻すと、問題なくすべてのキーをフェッチできます。

「Memcache::addServer」で「weight」オプションを正しく使用するために不足している構成や何かがありますか?

ご協力ありがとうございました。

 $hosts = array(
      array('ip' => '10.10.10.1', 'port' => 11211, 'weight' => 100),
      array('ip' => '10.10.10.2', 'port' => 11211, 'weight' => 100),
      array('ip' => '10.10.10.3', 'port' => 11211, 'weight' => 1),
      array('ip' => '10.10.10.4', 'port' => 11211, 'weight' => 100),
 );

 $memcache = new Memcache();
 foreach($hosts as $host) {
    $host['port'] = isset($host['port']) ? (int) $host['port'] : 11211;
    $host['weight'] = isset($host['weight']) ? (int) $host['weight'] : 1;
    $memcache->addserver($host['ip'], $host['port'], false, $host['weight'], 1, 15);
 }

PHP バージョン= 5.3.10

Memcache PHP 変数
- memcache サポート => 有効
- memcache.allow_failover => 1 => 1
- memcache.chunk_size => 32768 => 32768
- memcache.compress_threshold => 20000 => 20000
- memcache.default_port => 11211 => 11211
- memcache.hash_function => crc32 => crc32
- memcache.hash_strategy => 一致 => 一致
- memcache.lock_timeout => 15 => 15
- memcache.max_failover_attempts => 20 => 20
- memcache.protocol => ascii => ascii
- memcache.redundancy => 1 => 1
- memcache.session_redundancy => 2 => 2

Memcached バージョン
10.10.10.1 / 10.10.10.2 / 10.10.10.3 は 1.4.5 を実行しています
10.10.10.4 は 1.4.4 を実行しています

4

2 に答える 2

11

重みパラメーターは、どのサーバーからキーを読み書きするかを決定するために使用される一貫したハッシュに影響を与えます。プール内の任意の 1 つのサーバーの重みを変更すると、キャッシュ ミスが発生します。プール内のサーバーの数と重みをどれだけ変更するかによって、発生する可能性のあるミスの数が決まります。

理解する必要があるのは、memcached が分散されていることです。つまり、4 つのサーバーがあるため、それらのサーバーのそれぞれにキーが分散されます (できるだけ均等に [重みは均等な分散に影響します])。1 つのサーバーがダウンすると、そのサーバーに保存されているデータにアクセスできなくなり、他のサーバーでは使用できないため、データベースから取得する必要があります。*PHP 拡張機能memcachememcachedは、クラスターにアクセスする単なるクライアントであることに注意してくださいmemcached(memcached は 2 つのうちの新しい方であり、より多くの機能をサポートしていましたが、どちらも memcached クラスター内のサーバーと通信します)。

キャッシュから値を保存または取得する場合、クラスター内のどこにデータを配置または読み取る必要があるかを決定するハッシュが計算されます。これを説明する一般的な方法は、以下に示すように 360 度の円です。ハッシュを計算し、サークル内で「最も近い」場所にあるノードを使用します。サーバーを追加または削除したり、1 つのサーバーの重みを変更したりすると、ハッシュの結果が影響を受け、ミスが発生します。

ここに画像の説明を入力
出典:http ://alpha.mixi.co.jp/blog/?p=158

サーバーを段階的にクラスターから徐々に除外したい場合は、重みが 0 になるまで徐々に減らすことをお勧めします。その後、サーバーをリストから完全に削除できます。重みを少し変更すると、キャッシュ ミスが発生する可能性がありますが、重みがどの程度変化するか (およびサーバーの数) が、発生するミスの数に影響することに注意してください。

以下は、Memcached のチュートリアル ストーリーの一部であり、これについても説明するのに役立ちます。

序文は、2 人のシステム管理者が 3 台のサーバーで memcached クラスターをセットアップし、各サーバーで 1GB を使用するように memcached に指示したことです...

繰り返しになりますが、彼はプログラマーが使用するキーを取得し、memcached サーバーでそれらを探します。'get this_key' 'get that_key' しかし、彼がこれを行うたびに、1 つの memcached で各キーしか見つかりません! なぜあなたはこれをするのですか?そして彼は一晩中困惑します。それはばかげている !キーをすべての memcached に置きたくないですか?

「でも待ってください」と彼は考えます。「これで大金を節約できます。ブラッド・フィッツパトリック、あなたのお尻が大好きです!」

「しかし、うーん、次の問題です。これはパズルです。この Web サーバーはここにあります。これは memcached を実行しています。古いため、調子が悪く、アップグレードする必要があります。しかし、それを行うには、オフラインにする必要があります。どうなるでしょうか。私の貧弱な memcache クラスターに? ええ、調べてみましょう」と彼は言い、ボックスをシャットダウンしました. 今、彼は自分のグラフを見ています。「ああ、DB の負荷が一気に上がった!負荷は 1 ではなく、2 になった。うーん、まだ許容範囲だ。他のすべての memcached はまだトラフィックを取得している。これはそれほど悪くはない。ちょうどいくつかのキャッシュ ミスがあり、私の仕事はほとんど終わったので、彼はマシンの電源を入れ直し、memcached を再び動作させました.数分後、DB の負荷は再び 1 に戻りました。

「キャッシュは自動的に復元されました。今わかりました。キャッシュが利用できない場合は、リクエストのいくつかが失われることを意味します。しかし、それは私を殺すのに十分ではありません。それはとても素晴らしいことです。」

教訓として、memcached に格納された値は 1 つのサーバーにのみ格納され (つまり、キーはすべてのサーバーに分散されます)、それらのサーバーのいずれかが使用できなくなった場合、データはキャッシュから取得できず、ソースから取得する必要があります。 .

クラスター内の正しいノードからデータを適切に保存および取得するには、キーを一貫してハッシュする必要があります。これにより、クライアントは、その特定のキーに対してプール内のどのサーバーが正しいサーバーであるかを知ることができます。

ご想像のとおり、異なるクライアントは異なるハッシュ手法を使用するため、Perl クライアントと PHP クライアントを使用して値を保存/取得すると、ハッシュが異なるため、意図したとおりに機能しません。これに対する例外は、libmemcachedを使用するすべてのクライアントです。それ以降、それらはすべて同じハッシュ アルゴリズムを使用することになります。PHP のmemcached拡張機能は を使用しますlibmemcachedが、memcacheは使用せず、独自のハッシュ アルゴリズムを使用します (私の知る限り)。

参考文献:
- memcached wikiとmemcachedを学ぶ冒険
- Consistent Hashing
- Distributed Hash Tables

于 2012-06-05T21:10:10.763 に答える
1

問題は、 memcache と memcached を使用していることです。Memcached は分散されています。つまり、プールに追加されたすべてのサーバーが 1 つのキャッシュ サーバーとして機能します。したがって、server1 がダウンしても、キー/値は他の 3 つのサーバーに分散されているため、引き続き取得できます。一方、memcache (no d) では、各サーバーは基本的にサイロです。つまり、server1 に保存されているキー/値が他のキャッシュ サーバーに存在することが保証されていません。

問題のキャッシュ サーバーを非推奨にする場合は、API 呼び出しに追加のロジックを追加して永続ストアから値を取得し、少なくとも 2 つの他の有効なキャッシュ サーバーに格納することをお勧めします。キャッシュ値が 2 つのキャッシュ サーバー間で保存され、一方のサーバーが応答しなくなり、もう一方のサーバーがスラックを拾うことができるようにするプロジェクトを見てきました。

- アップデート -

どの PHP memcache API が使用されているかに関係なく、サーバーがプールから削除されると、現在失われているサーバーに存在するキーのキャッシュ ミスが発生します。が$cache->get()失敗して永続ストアに移動し、$cache->set()呼び出されると、キャッシュは別のアクティブなサーバーに保存されます。これについて説明してくれた Drew010 に感謝します。

キャッシュ ミスが絶対に許されない場合でも、同じキャッシュ値を複数のサーバーに書き込むようにアプリを作成できます。

于 2012-06-05T18:10:05.073 に答える