【发布时间】:2014-06-16 21:09:51
【问题描述】:
我有一个简单的 PHP 脚本,可以对 Mongo 数据库进行一些更新:
$properties = db()->properties->find([], ['_id' => true]);
foreach($properties as $property) {
db()->properties->update(
['_id' => $property['_id']],
['$set' => ['random' => [lcg_value(), lcg_value()]]],
['w' => 0]
);
}
我基本上按照here 的建议为“属性”集合中的每个记录分配一个随机点,以查询随机记录。对于我正在操作的数据集(大约 200,000 个文档),此脚本在我的本地系统上运行大约一分半钟。
我考虑使用 JavaScript 并在服务器端运行更新,但从驱动程序运行服务器端代码需要过于宽松的特殊权限。我不喜欢我必须拉下所有数据并为每条记录发送更新但我想不出在 Mongo 中作为批处理操作的方法。
无论网络流量过多,它都相当快,因为我只是拉下 ID,而我对数据库的写回没有启用写一致性。
在生产机器上运行此脚本时,脚本突然需要更长的时间。大约 30 分钟后,我终止了这项工作。出于各种其他原因,生产站点使用自定义编译的 PHP 安装。我认为自定义编译是原因,但我不确定如何追踪减速的确切原因。
到目前为止我的想法:
- 可能在我的机器上启用的生产机器上没有启用某些优化模块?我假设像 opcache 这样的东西不会影响这一点,因为我们只执行一次 CLI 脚本,而不是向同一个脚本发出一堆请求。
- 也许某些编译时选项可以使 gcc 生成更优化的二进制文件?
- 或者 Mongo 模块的通信速度较慢,因为它缺少一些更快的网络库,必须退回到较慢的库?
自定义编译的 PHP 使用以下选项和模块进行编译:
./configure --enable-static --enable-cli --disable-all --with-curl \
--enable-mongo --enable-json --enable-hash --enable-libxml \
--enable-simplexml --enable-filter --enable-dom --enable-ftp \
--enable-pcntl --enable-posix --enable-xmlwriter
如果我在本地系统模块和这个自定义编译版本之间进行比较,我会得到以下模块,这些模块在我的本地系统上,但不在生产机器上:
bz2
calendar
ctype
exif
fileinfo
gettext
iconv
mhash
mysql
mysqli
mysqlnd
openssl
PDO
pdo_mysql
pdo_sqlite
Phar
readline
session
shmop
sockets
sqlite3
sysvmsg
sysvsem
sysvshm
tokenizer
wddx
xdebug
xml
xmlreader
xsl
zip
zlib
这些看起来都不会影响性能。
比较版本你可以看到我正在运行类似的版本。自定义版本:
PHP 5.5.13 (cli) (built: Jun 11 2014 17:00:10)
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.5.0, Copyright (c) 1998-2014 Zend Technologies
我的本地机器:
PHP 5.5.12 (cli) (built: May 3 2014 07:09:53)
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.5.0, Copyright (c) 1998-2014 Zend Technologies
with Xdebug v2.2.5, Copyright (c) 2002-2014, by Derick Rethans
我假设缓慢是由于 IO 而不是 CPU,因为脚本主要是关于与 Mongo 数据库通信。它确实计算了一个随机数,但这并没有考虑在内,因为我自定义编译的 PHP 实际上更快地生成了随机数。在我的本地 php 上使用 lcg_value 生成一百万个随机数:
real 0m0.420s
user 0m0.411s
sys 0m0.008s
但是使用我自定义编译的 PHP:
real 0m0.081s
user 0m0.076s
sys 0m0.005s
问题不是由于生产环境的网络或 CPU 能力。我在本地机器上运行了自定义编译的 PHP 二进制文件,它的速度也明显变慢了。所以我很确定这与它的编译方式、使用的模块或配置有关。
有人知道下一步要去哪里吗?
【问题讨论】:
-
告诉我们有关磁盘驱动器以及 prod 系统上正在运行的其他内容。是否有其他东西同时运行?它是否被用于其他任何事情? prod 和您的测试/开发机器之间还有什么不同?
-
您是否对代码进行了概要分析,以便更好地了解您将时间花在哪里?我认为这将是下一个合乎逻辑的步骤。
-
@AlisterBulman - 与生产系统无关。注意我的最后一段。如果我在本地系统(而不是系统范围的 PHP)上使用相同的 PHP 二进制文件,它也会运行缓慢。因此,自定义 PHP 在我的系统和服务器上运行缓慢。我的本地系统范围的二进制文件运行速度并不慢。
标签: php performance mongodb gcc compiler-optimization