Memcached 响应时间过长
Memcached get taking too long to respond
我对 memcached 有一个奇怪的问题。我搜索了 here, here, here, here and few other places 关于我的查询。所以我有两个页面 index.php
和 index2.php
(请不要介意文件命名)。
index.php
包含以下代码:
<?php
$data = file_get_contents('test.txt');
echo "done";
并且index2.php
包含以下代码:
<?php
function file_get_contents_new($filename, $memcache){
$time = filemtime($filename);
$hash = md5($filename.$time);
$content = $memcache->get($hash);
if($content){
return $content;
}
$content = file_get_contents($filename);
$memcache->set($hash, $content, 10000);
return $content;
}
$memcache = new Memcached;
$memcache->addServer('localhost', 11211);
file_get_contents_new('test.txt', $memcache);
echo "done";
还有一个文件 test.txt
,其中 html 来源来自一个随机站点,大约 58967
个字符,大约 57.6kb
.
现在,当我尝试分析 index.php
时,我得到了以下分析结果(我使用 xdebug 进行分析,使用 phpstorm 查看数据):
现在,当我尝试分析 index2.php
时,我得到以下快照:
我们可以清楚地看到 $memcache->get()
花费了很长时间,这没有多大意义,因为我在本地计算机上 运行 Memcached。
然后我想也许这只是一些错误并尝试了 apache 的基准测试工具 ab
。我执行的确切命令是 ab -n 10000 -c 100 http://localhost/index.php
这非常快,结果是:
Server Software: Apache/2.4.20
Server Hostname: localhost
Server Port: 80
Document Path: /index.php
Document Length: 4 bytes
Concurrency Level: 100
Time taken for tests: 0.555 seconds
Complete requests: 10000
Failed requests: 0
Total transferred: 2030000 bytes
HTML transferred: 40000 bytes
Requests per second: 18025.33 [#/sec] (mean)
Time per request: 5.548 [ms] (mean)
Time per request: 0.055 [ms] (mean, across all concurrent requests)
Transfer rate: 3573.38 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.1 0 1
Processing: 1 5 0.8 5 19
Waiting: 1 5 0.7 5 19
Total: 2 5 0.7 5 19
Percentage of the requests served within a certain time (ms)
50% 5
66% 6
75% 6
80% 6
90% 6
95% 7
98% 7
99% 8
100% 19 (longest request)
然后我做了下面的测试ab -n 10000 -c 100 http://localhost/index2.php
Server Software: Apache/2.4.20
Server Hostname: localhost
Server Port: 80
Document Path: /index2.php
Document Length: 4 bytes
Concurrency Level: 100
Time taken for tests: 9.044 seconds
Complete requests: 10000
Failed requests: 0
Total transferred: 2030000 bytes
HTML transferred: 40000 bytes
Requests per second: 1105.72 [#/sec] (mean)
Time per request: 90.439 [ms] (mean)
Time per request: 0.904 [ms] (mean, across all concurrent requests)
Transfer rate: 219.20 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.1 0 1
Processing: 6 79 71.1 76 5090
Waiting: 6 79 71.1 76 5090
Total: 7 79 71.1 76 5090
Percentage of the requests served within a certain time (ms)
50% 76
66% 78
75% 79
80% 81
90% 85
95% 89
98% 93
99% 107
100% 5090 (longest request)
这很慢而且很奇怪。为什么从内存读取比从辅助存储读取慢。或者他们是否在 file_get_contents
上实现了一些缓存
我正在使用的计算机非常强大,配置如下:
- MANJARO OS(Linux 内核 4.1.26-1)
- 16GB 主内存
- 256GB 固态硬盘
- 英特尔酷睿 i7 处理器
编辑:正如@ShiraNai7 评论的那样,我尝试将我的服务器 URL 更改为 127.0.0.1,以下是 apache 基准测试工具的结果
Server Software: Apache/2.4.20
Server Hostname: localhost
Server Port: 80
Document Path: /index2.php
Document Length: 4 bytes
Concurrency Level: 100
Time taken for tests: 11.611 seconds
Complete requests: 10000
Failed requests: 0
Total transferred: 2030000 bytes
HTML transferred: 40000 bytes
Requests per second: 861.25 [#/sec] (mean)
Time per request: 116.111 [ms] (mean)
Time per request: 1.161 [ms] (mean, across all concurrent requests)
Transfer rate: 170.74 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 3 47.0 0 1009
Processing: 6 113 67.6 105 633
Waiting: 6 111 67.1 103 633
Total: 6 116 82.5 106 1197
Percentage of the requests served within a certain time (ms)
50% 106
66% 135
75% 153
80% 167
90% 204
95% 235
98% 286
99% 334
100% 1197 (longest request)
这是一个改进,但不是很多。而且我不明白为什么 dns 查找需要这么长时间,因为它在 /etc/hosts
上并且它位于我的本地计算机上。
编辑:我还试图查看是否有任何 APC 正在进行,我找不到我确实找到了 Opcache
模块。这就是 file_get_contents 更快的原因吗?
我有 hosted 一个 jsbin,您可以在其中查看我的 phpinfo 在我的机器中的样子。
嗯,我发现了这个问题背后的奥秘。第一条线索是 file_get_contents
非常快。即使我使用的是 SSD,也不应该那么快。于是翻了一晚上,发现了一些有趣的信息。
因为file_get_contents也在返回缓存信息。 PHP 本身不包含缓存,但 linux 系统内置了文件缓存,这使得重复访问数据的速度非常快。
参考:page cache
我对 memcached 有一个奇怪的问题。我搜索了 here, here, here, here and few other places 关于我的查询。所以我有两个页面 index.php
和 index2.php
(请不要介意文件命名)。
index.php
包含以下代码:
<?php
$data = file_get_contents('test.txt');
echo "done";
并且index2.php
包含以下代码:
<?php
function file_get_contents_new($filename, $memcache){
$time = filemtime($filename);
$hash = md5($filename.$time);
$content = $memcache->get($hash);
if($content){
return $content;
}
$content = file_get_contents($filename);
$memcache->set($hash, $content, 10000);
return $content;
}
$memcache = new Memcached;
$memcache->addServer('localhost', 11211);
file_get_contents_new('test.txt', $memcache);
echo "done";
还有一个文件 test.txt
,其中 html 来源来自一个随机站点,大约 58967
个字符,大约 57.6kb
.
现在,当我尝试分析 index.php
时,我得到了以下分析结果(我使用 xdebug 进行分析,使用 phpstorm 查看数据):
现在,当我尝试分析 index2.php
时,我得到以下快照:
我们可以清楚地看到 $memcache->get()
花费了很长时间,这没有多大意义,因为我在本地计算机上 运行 Memcached。
然后我想也许这只是一些错误并尝试了 apache 的基准测试工具 ab
。我执行的确切命令是 ab -n 10000 -c 100 http://localhost/index.php
这非常快,结果是:
Server Software: Apache/2.4.20
Server Hostname: localhost
Server Port: 80
Document Path: /index.php
Document Length: 4 bytes
Concurrency Level: 100
Time taken for tests: 0.555 seconds
Complete requests: 10000
Failed requests: 0
Total transferred: 2030000 bytes
HTML transferred: 40000 bytes
Requests per second: 18025.33 [#/sec] (mean)
Time per request: 5.548 [ms] (mean)
Time per request: 0.055 [ms] (mean, across all concurrent requests)
Transfer rate: 3573.38 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.1 0 1
Processing: 1 5 0.8 5 19
Waiting: 1 5 0.7 5 19
Total: 2 5 0.7 5 19
Percentage of the requests served within a certain time (ms)
50% 5
66% 6
75% 6
80% 6
90% 6
95% 7
98% 7
99% 8
100% 19 (longest request)
然后我做了下面的测试ab -n 10000 -c 100 http://localhost/index2.php
Server Software: Apache/2.4.20
Server Hostname: localhost
Server Port: 80
Document Path: /index2.php
Document Length: 4 bytes
Concurrency Level: 100
Time taken for tests: 9.044 seconds
Complete requests: 10000
Failed requests: 0
Total transferred: 2030000 bytes
HTML transferred: 40000 bytes
Requests per second: 1105.72 [#/sec] (mean)
Time per request: 90.439 [ms] (mean)
Time per request: 0.904 [ms] (mean, across all concurrent requests)
Transfer rate: 219.20 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.1 0 1
Processing: 6 79 71.1 76 5090
Waiting: 6 79 71.1 76 5090
Total: 7 79 71.1 76 5090
Percentage of the requests served within a certain time (ms)
50% 76
66% 78
75% 79
80% 81
90% 85
95% 89
98% 93
99% 107
100% 5090 (longest request)
这很慢而且很奇怪。为什么从内存读取比从辅助存储读取慢。或者他们是否在 file_get_contents
我正在使用的计算机非常强大,配置如下:
- MANJARO OS(Linux 内核 4.1.26-1)
- 16GB 主内存
- 256GB 固态硬盘
- 英特尔酷睿 i7 处理器
编辑:正如@ShiraNai7 评论的那样,我尝试将我的服务器 URL 更改为 127.0.0.1,以下是 apache 基准测试工具的结果
Server Software: Apache/2.4.20
Server Hostname: localhost
Server Port: 80
Document Path: /index2.php
Document Length: 4 bytes
Concurrency Level: 100
Time taken for tests: 11.611 seconds
Complete requests: 10000
Failed requests: 0
Total transferred: 2030000 bytes
HTML transferred: 40000 bytes
Requests per second: 861.25 [#/sec] (mean)
Time per request: 116.111 [ms] (mean)
Time per request: 1.161 [ms] (mean, across all concurrent requests)
Transfer rate: 170.74 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 3 47.0 0 1009
Processing: 6 113 67.6 105 633
Waiting: 6 111 67.1 103 633
Total: 6 116 82.5 106 1197
Percentage of the requests served within a certain time (ms)
50% 106
66% 135
75% 153
80% 167
90% 204
95% 235
98% 286
99% 334
100% 1197 (longest request)
这是一个改进,但不是很多。而且我不明白为什么 dns 查找需要这么长时间,因为它在 /etc/hosts
上并且它位于我的本地计算机上。
编辑:我还试图查看是否有任何 APC 正在进行,我找不到我确实找到了 Opcache
模块。这就是 file_get_contents 更快的原因吗?
我有 hosted 一个 jsbin,您可以在其中查看我的 phpinfo 在我的机器中的样子。
嗯,我发现了这个问题背后的奥秘。第一条线索是 file_get_contents
非常快。即使我使用的是 SSD,也不应该那么快。于是翻了一晚上,发现了一些有趣的信息。
因为file_get_contents也在返回缓存信息。 PHP 本身不包含缓存,但 linux 系统内置了文件缓存,这使得重复访问数据的速度非常快。
参考:page cache