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

Bar*_*ter 16 php performance nginx apache-2.2

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

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

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

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

看起来某处存在瓶颈,不允许我走得更高,有什么建议吗?(即,我知道执行少于 6 个 SQL 会使其更快,但这看起来不是一个限制因素,因为 sqld 由于缓存查询而在顶部的消耗不超过百分之几)

有没有人测试过踢预分叉的 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.
Run Code Online (Sandbox Code Playgroud)

更新: 似乎瓶颈是 MySQL 在缓存数据上的性能。带有单个 SQL 的页面显示 354req/sec,有 6 个 SQL - 180 req/sec。你认为我可以在这里调整什么?(我可以为 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/
Run Code Online (Sandbox Code Playgroud)

Iva*_*ski 29

显然,您可以尝试很多。最好的办法是为不使用索引的查询(为那些启用日志)和其他非优化查询跟踪日志。多年来,我已经编制了大量与性能相关的选项列表,因此我在此处包含了一小部分供您参考 - 希望它有所帮助。以下是您可以尝试的一些一般注意事项(如果您还没有):

MySQL

  • query_cache_type=1 - 缓存 SQL 查询开启。如果设置为 2,则仅当 SQL_CACHE 提示传递给查询时才会缓存查询。与类型 1 类似,您可以使用 SQL_NO_CACHE 提示禁用特定查询的缓存
  • key_buffer_size=128M (default: 8M) - MyISAM 表索引的内存缓冲区。在专用服务器上,目标是将 key_buffer_size 设置为服务器内存总量的至少四分之一,但不超过一半
  • query_cache_size=64M (default: 0) - 查询缓存的大小
  • back_log=100 (default: 50, max: 65535) - 未完成的连接请求队列。只有在短时间内有大量连接时才重要
  • join_buffer_size=1M (default: 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 (default: 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 (default: 300) - 将密钥缓存保持在热区的时间(在它降级到暖区之前)
  • key_cache_division_limit=50 (default: 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 - 保持文件列表尽可能简短和绝对。
  • 选项 FollowSymLinks - 简化 Apache 中的文件访问过程
  • 避免使用 mod_rewrite 或至少复杂的正则表达式
  • 服务器令牌=产品

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