如何在200个以上的请求/秒中扩展php5 + MySQL?

我正在调整我的主页的性能,目前它处理大约200个请求/秒3.14.by其中的3个SQL查询,并在3.14.by /论坛这是phpBB论坛20个请求/秒。

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

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

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

这看起来像是有一个瓶颈,不允许我走高,有什么build议吗? (即,我知道less于6个SQL会使速度更快,但这看起来不是一个限制因素,因为由于caching查询,sqld最多不超过百分之几)

有没有人testing踢预先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. 

更新:看起来瓶颈是MySQLcaching数据的性能。 具有单个SQL的页面显示为354req /秒,具有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/ 

显然,有很多你可以尝试。 您最好的办法是追逐您的日志查询不使用索引(启用这些日志)和其他非优化查询的查询。 我已经编写了一个多年来与性能相关的选项列表,所以我在这里包含了一小部分的信息 – 希望它有帮助。 下面是一些你可以尝试的一般注意事项(如果你还没有的话):

MySQL的

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

阿帕奇

  • 改变产卵方法(以mpm为例)
  • 禁用日志如果可能
  • AllowOverride None – 只要有可能,禁用.htaccess。 如果没有使用它,停止apache查找.htaccess文件,所以它保存了一个文件查找请求
  • SendBufferSize – 设置为OS默认值。 在拥塞的networking上,您应该将此参数设置为接近正常下载的最大文件的大小
  • 保持closures(默认打开) – 并安装徘徊以正确closuresnetworking连接,速度更快
  • DirectoryIndex index.php – 保持文件列表尽可能简短和绝对。
  • 选项FollowSymLinks – 简化Apache中的文件访问过程
  • 避免使用mod_rewrite或至less复杂的正则expression式
  • ServerToken = PROD

PHP

  • variables_order =“GPCS”(如果你不需要环境variables)
  • register_globals =closures – 除了存在安全风险外,还会对性能产生影响
  • 保持include_path尽可能小(避免额外的文件系统查找)
  • display_errors =closures – 禁止显示错误。 强烈build议所有生产服务器(如果出现问题,不会显示丑陋的错误消息)。
  • magic_quotes_gpc的=closures
  • magic_quotes的_ * =closures
  • output_buffering =开
  • 如果可能的话禁用日志
  • expose_php =closures
  • register_argc_argv =closures
  • always_populate_raw_post_data =closures
  • 将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

如果瓶颈不是CPU,那么它的IO–无论是networking还是光盘。 所以..你需要看看有多lessIO进行。 我不会想到它的networking(除非你是在一个10Mbps的半双工链路,但它的价值检查交换机的情况下,自动检测是不正确的工作)。

这留下了磁盘IO,这可能是VPS上的一个重要因素。 使用sar或iostat查看磁盘,然后谷歌如何查找更多的细节,如果您的磁盘正在使用大量。

我会考虑与Nginx ( memcached )或Varnish caching 。

至less你应该用Nginx服务器来保存静态文件,就像SaveTheRbtz所说的那样。

由于服务器似乎没有问题,也许是负载生成器。 尝试在几台机器上运行它。

这听起来像你可能会达到Apache允许的最大连接数。看看你的Apacheconfiguration。 如果您还没有受到I / O或内存等其他限制的约束,那么增加服务器限制和最大客户端应该会有所帮助。 查看mpm_prefork_module或mpm_worker_module的值,并相应地进行调整以满足您的需求。

 ServerLimit 512
 MaxClients 512

这个负载是由一个工具或真实世界负载产生的吗?

你可能想检查memcached。 我看到它的连接速度很高,导致应用程序延迟。

如果使用负载生成器,当点击一个小的静态页面时会得到什么?

在加载期间,您可能需要检查networking堆栈的TIME_WAIT条件。 也许你正在填充你的连接队列。

大约还有100多个理由和项目你可以看,但没有更多的信息,我只是在这一点上抛出猜测。

99%的时间问题会追溯到数据库。 确保你的命中首先。 如果这不起作用,请开始caching所有可能的内容。

我build议您使用(如果可能的话)连接池来保持数据库连接到您的Web应用程序(无需在每个请求重新连接)。 这可以造成速度的巨大差异。

另外,尝试用EXPLAIN分析所有查询(为什么不用SHOW PROFILE来查询查询?)。