2

同時にアクセスできるユーザーを 100 人に制限したい Web ページがあるため、memcached を使用してグローバル カウンターを実装します。

使用しているのhttp://www.php.net/manual/en/class.memcache.phpでありませんがcas、現在のコードは次のようなものです

$count = $memcache_obj->get('count');
if ($count < 100) {
   $memcache_obj->set('count', $count+1);
   echo "Welcome";
} else {
   echo "No luck";
}

ご覧のとおり、上記のコードには競合状態がありますが、memcachedサポートする拡張機能を置き換えない場合cas、PHP コードのみを使用してサポートすることができますか?

4

4 に答える 4

8

「emcconville」への回答として。これは、CAS がなくてもノンブロッキングです。

競合状態が懸念され、カウント値が完全に任意である場合はMemcache::increment、ビジネス ロジックの直前に使用できます。

インクリメントメソッドは、インクリメントが行われた後に現在の値を返します。そのうち、結果を比較できます。キーがまだ設定されていない場合、Increment もfalseを返します。アプリケーションが必要に応じて処理できるようにします。

$current = $memcache_obj->increment('count');

if($current === false) {

  // NOT_FOUND, so let's create it
  // Will return false if has just been created by someone else.
  $memcache_obj->add('count',0); // <-- no risk of race-condition

  // At this point 'count' key is created by us or someone else (other server/process).
  // "increment" will update 0 or whatever it is at the moment by 1.
  $current = $memcache_obj->increment('count')
  echo "You are the $current!";

} 
if ($current < 100) {

  echo "Hazah! You are under the limit. Congrats!";

} else {

  echo "Ah Snap! No Luck - you reached the limit.";
  // If your worried about the value growing _too_ big, just drop the value down.
  // $memcache_obj->decrement('count');

}
于 2013-08-29T22:05:33.067 に答える
6

競合状態が懸念され、カウント値が完全に任意である場合はMemcache::increment、ビジネス ロジックの直前に使用できます。

インクリメントメソッドは、インクリメントが行われた後に現在の値を返します。そのうち、結果を比較できます。キーがまだ設定されていない場合、Increment もfalseを返します。アプリケーションが必要に応じて処理できるようにします。

$current = $memcache_obj->increment('count');

if($current === false) {

  // NOT_FOUND, so let's create it
  $memcache_obj->set('count',1); // <-- still risk of race-condition
  echo "Your the first!";

} else if ($current < 100) {

  echo "Hazah! Your under the limit.";

} else {

  echo "Ah Snap! No Luck";
  // If your worried about the value growing _too_ big, just drop the value down.
  // $memcache_obj->decrement('count');

}
于 2012-10-30T14:22:30.667 に答える
2
function memcache_atomic_increment($counter_name, $delta = 1) {

    $mc = new Memcache;
    $mc->connect('localhost', 11211) or die("Could not connect");

    while (($mc->increment($counter_name, $delta) === false) &&
           ($mc->add($counter_name, ($delta<0)?0:$delta, 0, 0) === false)) {
        // loop until one of them succeeds
    }

    return intval($mc->get($counter_name));
}
于 2014-11-21T10:41:21.983 に答える
-1

のコメントにはロック機能Memcache::addの例が含まれています。試してみましたか?

于 2012-10-30T04:41:37.733 に答える