如何将 php5+MySQL 扩展至每秒 200 个请求以上?

如何将 php5+MySQL 扩展至每秒 200 个请求以上?

我正在调整我的主页以提高性能,目前它在 3.14.by 上每秒处理大约 200 个请求,这需要 6 个 SQL 查询,在 3.14.by/forum(即 phpBB 论坛)上每秒处理 20 个请求。

奇怪的是,一些 VPS 和专用 Atom 330 服务器上的数字大致相同。

服务器软件如下:Apache2 + mod_php prefork 4 childs(这里尝试了不同的数字)、php5、APC、nginx、memcached 用于 PHP 会话存储。

MySQL 配置为占用大约 30% 的可用 RAM(VPS 上约 150Mb,专用服务器上约 700Mb)

这看起来好像某个地方存在瓶颈,不允许我提高速度,有什么建议吗?(即,我知道执行少于 6 条 SQL 会使速度更快,但这看起来不像是一个限制因素,因为由于缓存查询,sqld 在 top 中占用的量不会超过百分之几)

有没有人测试过,踢掉预先分叉的 apache2 并只留下 nginx+php 会更快?

更多基准测试

Small 40-byte static file: 1484 r/s via nginx+apache2, 2452 if we talk to apache2 directly. 
Small "Hello world" php script: 458 r/s via ngin+apache2.

更新: 看来瓶颈是 MySQL 在缓存数据上的性能。单个 SQL 的页面显示 354 个请求/秒,6 个 SQL 的页面显示 180 个请求/秒。您认为我可以在这里调整什么?(我可以为 MySQL 分配 100-200Mb)

[client]
port        = 3306
socket      = /var/run/mysqld/mysqld.sock

[mysqld_safe]
socket      = /var/run/mysqld/mysqld.sock
nice        = 0

[mysqld]
default-character-set=cp1251
collation-server=cp1251_general_cs

skip-character-set-client-handshake

user        = mysql
pid-file    = /var/run/mysqld/mysqld.pid
socket      = /var/run/mysqld/mysqld.sock
port        = 3306
basedir     = /usr
datadir     = /var/lib/mysql
tmpdir      = /tmp
skip-external-locking

bind-address        = 127.0.0.1

key_buffer      = 16M
max_allowed_packet  = 8M
thread_stack        = 64K
thread_cache_size   = 16
sort_buffer_size    = 8M
read_buffer_size    = 1M

myisam-recover      = BACKUP
max_connections        = 650
table_cache            = 256
thread_concurrency     = 10

query_cache_limit       = 1M
query_cache_size        = 16M

expire_logs_days    = 10
max_binlog_size         = 100M

[mysqldump]
quick
quote-names
max_allowed_packet  = 8M

[mysql]
[isamchk]
key_buffer      = 8M

!includedir /etc/mysql/conf.d/

答案1

显然,您可以尝试很多方法。最好的办法是追踪不使用索引的查询(为这些查询启用日志)和其他未优化的查询的日志。多年来,我已经编制了一份与性能相关的选项的庞大列表,因此我在这里列出了一小部分供您参考 - 希望对您有所帮助。以下是您可以尝试的一些一般说明(如果您还没有尝试过):

MySQL

  • query_cache_type=1 - 缓存 SQL 查询已打开。如果设置为 2,则仅当向查询传递 SQL_CACHE 提示时才会缓存查询。与类型 1 类似,您可以使用 SQL_NO_CACHE 提示禁用特定查询的缓存
  • key_buffer_size=128M(默认值:8M)- MyISAM 表索引的内存缓冲区。在专用服务器上,应将 key_buffer_size 设置为服务器总内存量的至少四分之一,但不超过一半
  • query_cache_size=64M(默认值:0)- 查询缓存的大小
  • back_log=100(默认值:50,最大值:65535)- 未完成连接请求的队列。只有在短时间内有大量连接时才重要
  • join_buffer_size=1M(默认值:131072)- 进行全表扫描(无索引)时使用的缓冲区
  • table_cache=2048(默认值:256) - 应为 max_user_connections 乘以最重的 SQL 查询包含的最大 JOIN 数。在高峰时段使用“open_tables”变量作为指导。还要查看“opened_tables”变量 - 它应该接近“open_tables”
  • query_prealloc_size=32K(默认值:8K)- 用于语句解析和执行的持久内存。如果有复杂查询,请增加
  • sort_buffer_size=16M(默认值:2M)- 有助于排序(ORDER BY 和 GROUP BY 操作)
  • read_buffer_size=2M(默认值:128K)- 有助于顺序扫描。如果顺序扫描较多,则增加该值。
  • read_rnd_buffer_size=4M - 帮助 MyISAM 表加速排序后的读取
  • max_length_for_sort_data - 排序文件中要存储的行大小,而不是行指针。可以避免随机表读取
  • key_cache_age_threshold=3000(默认值:300)- 将密钥缓存保留在热区的时间(在降级为热区之前)
  • key_cache_division_limit=50(默认值:100)- 启用更复杂的缓存驱逐机制(两级)。表示要保留的底层百分比。delay_key_write=ALL - 每次更新索引时,不会刷新表的键缓冲区,而只会在关闭表时刷新。这大大加快了键的写入速度,但是如果您使用此功能,则应通过使用 --myisam-recover=BACKUP,FORCE 选项启动服务器来添加对所有 MyISAM 表的自动检查
  • memlock=1-将进程锁定在内存中(以减少交换进/出)

阿帕奇

  • 改变生成方法(例如改为 mpm)
  • 如果可能的话禁用日志
  • AllowOverride None - 尽可能禁用 .htaccess。如果未使用 .htaccess 文件,它将停止 apache 查找这些文件,从而节省文件查找请求
  • SendBufferSize - 设置为操作系统默认值。在拥塞的网络上,您应该将此参数设置为接近通常下载的最大文件的大小
  • KeepAlive Off(默认开启)-并安装 lingerd 以正确关闭网络连接,并且速度更快
  • DirectoryIndex index.php - 保持文件列表尽可能简短且完整。
  • Options FollowSymLinks - 简化 Apache 中的文件访问过程
  • 避免使用 mod_rewrite 或至少复杂的正则表达式
  • 服务器令牌=prod

PHP

  • Variables_order="GPCS"(如果不需要环境变量)
  • register_globals=Off - 除了存在安全风险外,还会影响性能
  • 保持include_path尽可能小(避免额外的文件系统查找)
  • display_errors=Off - 禁用显示错误。强烈建议所有生产服务器都使用(出现问题时不会显示难看的错误消息)。
  • magic_quotes_gpc=关闭
  • magic_quotes_*=关闭
  • 输出缓冲=开启
  • 如果可能,禁用日志记录
  • 暴露_php=关闭
  • register_argc_argv=关闭
  • always_populate_raw_post_data=关闭
  • 将 php.ini 文件放在 php 首先查找的位置。
  • session.gc_divisor=1000 或 10000
  • session.save_path = "N;/path" - 对于大型网站,请考虑使用它。将会话文件拆分到子目录中

操作系统调整

  • 使用 -o noatime 选项(无访问时间)挂载使用的硬盘。同时将此选项添加到 /etc/fstab 文件中。
  • 调整 /proc/sys/vm/swappiness(从 0 到 100)以查看最佳效果
  • 使用 RAM 磁盘 - mount --bind -ttmpfs /tmp /tmp

答案2

如果瓶颈不是 CPU,那么就是 IO - 网络或磁盘。所以...您需要查看 IO 数量。我不会认为是网络问题(除非您使用的是 10mbps 半双工链路,但值得检查交换机,以防自动检测无法正常工作)。

剩下的就是磁盘 IO,这可能是一个重要因素,尤其是在 VPS 上。使用 sar 或 iostat 查看磁盘,然后使用 Google 查找有关磁盘使用率过高的详细信息。

答案3

我会研究使用以下任一方法进行缓存Nginxmemcached) 或者

至少你应该像 SaveTheRbtz 所说的那样使用 Nginx 来提供静态文件服务。

答案4

在我看来,您可能已经达到了 Apache 允许的最大连接数。请查看您的 Apache 配置。如果您尚未受到 I/O 或内存等其他限制的约束,则增加服务器限制和最大客户端数应该会有所帮助。查看 mpm_prefork_module 或 mpm_worker_module 的现有值并进行相应调整以满足您的需求。

服务器限制 512
最大客户数 512

相关内容