MemCached::increment()不是原子


MemCached::increment() is not atomic?

我的理解是Memcached::increment是原子的。

我有这个代码:

include('../clibootstrap.php');
$key = 'ad_1';
$mc = $app['memcache'];
$mc->setOption(Memcached::OPT_BINARY_PROTOCOL,true);
usleep(10);
$mc->increment($key, 1, 0);
die('OK');

$mc'MemCached 的一个实例

现在我尝试使用ApacheBench:对其进行基准测试

# ab -n2000 -c100 http://somehost.com/foo.php
Benchmarking somehost.com (be patient)
Completed 200 requests
Completed 400 requests
Completed 600 requests
Completed 800 requests
Completed 1000 requests
Completed 1200 requests
Completed 1400 requests
Completed 1600 requests
Completed 1800 requests
Completed 2000 requests
Finished 2000 requests

Server Software:        Apache/2.2.22
Server Hostname:        somehost.com
Server Port:            80
Document Path:          /foo.php
Document Length:        2 bytes
Concurrency Level:      100
Time taken for tests:   4.821 seconds
Complete requests:      2000
Failed requests:        0
Write errors:           0
Total transferred:      352000 bytes
HTML transferred:       4000 bytes
Requests per second:    414.82 [#/sec] (mean)
Time per request:       241.067 [ms] (mean)
Time per request:       2.411 [ms] (mean, across all concurrent requests)
Transfer rate:          71.30 [Kbytes/sec] received
Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   1.0      0       5
Processing:    33  237  34.5    237     323
Waiting:       33  237  34.5    237     323
Total:         38  237  34.0    237     323

Percentage of the requests served within a certain time (ms)
  50%    237
  66%    255
  75%    263
  80%    266
  90%    274
  95%    279
  98%    287
  99%    294
 100%    323 (longest request)

现在我预计"ad_1"密钥的值正好是2000,所以让我们使用telnet:进行检查

# telnet localhost 11211
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
get ad_1
VALUE ad_1 0 4
1997
END
version
VERSION 1.4.13
stats
STAT pid 5527
STAT uptime 248
STAT time 1414164851
STAT version 1.4.13
STAT libevent 2.0.16-stable
STAT pointer_size 64
STAT rusage_user 0.092005
STAT rusage_system 0.268016
STAT curr_connections 5
STAT total_connections 2006
STAT connection_structures 23
STAT reserved_fds 20
STAT cmd_get 1
STAT cmd_set 0
STAT cmd_flush 0
STAT cmd_touch 0
STAT get_hits 1
STAT get_misses 0
STAT delete_misses 0
STAT delete_hits 0
STAT incr_misses 0
STAT incr_hits 1997
STAT decr_misses 0
STAT decr_hits 0
STAT cas_misses 0
STAT cas_hits 0
STAT cas_badval 0
STAT touch_hits 0
STAT touch_misses 0
STAT auth_cmds 0
STAT auth_errors 0
STAT bytes_read 144026
STAT bytes_written 112049
STAT limit_maxbytes 67108864
STAT accepting_conns 1
STAT listen_disabled_num 0
STAT threads 4
STAT conn_yields 0
STAT hash_power_level 16
STAT hash_bytes 524288
STAT hash_is_expanding 0
STAT expired_unfetched 0
STAT evicted_unfetched 0
STAT bytes 73
STAT curr_items 1
STAT total_items 1998
STAT evictions 0
STAT reclaimed 0
END

我使用的是PHP memcached版本2.2

关于ad_1值为什么不是2000,有什么想法吗?

我怎样才能确保MemCached::increment()变成原子呢?

此外,在VALUE ad_1 0 4行中,4是什么意思?

我使用了一个信号量,将代码更改为

include('../clibootstrap.php');
$key = 'ad_1';
$mc = $app['memcache'];
$mc->setOption(Memcached::OPT_BINARY_PROTOCOL,true);
$sem = sem_get(1234, 1);
if (sem_acquire($sem)) {
        $mc->increment($key, 1, 1);
        sem_release($sem);
}
usleep(10);
die('OK');

现在它起作用了。