我正在调整我的主页以提高性能,目前它在 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
答案4
在我看来,您可能已经达到了 Apache 允许的最大连接数。请查看您的 Apache 配置。如果您尚未受到 I/O 或内存等其他限制的约束,则增加服务器限制和最大客户端数应该会有所帮助。查看 mpm_prefork_module 或 mpm_worker_module 的现有值并进行相应调整以满足您的需求。
服务器限制 512 最大客户数 512