我有一台服务器(2x Hexa-Core Xeon E5649 2.53GHz w/HT,32GB RAM 和 20000 GB 带宽),运行 Ubuntu Server 12.04 LTS。该服务器运行 LAMP 并仅服务于一个网站,估计同时用户数量约为 15,000。
目前,我大约有 2000 个在线用户,他们每个人从会话开始到结束都运行 50 个 MySQL 查询(小值,主要是选择和插入)。在这种连接数下,服务器 CPU 负载很高,而 RAM 使用量几乎是 32GB 中的 1GB,值得一提的是,服务器运行非常快,没有任何问题,但我担心平均负载。http://s12.postimage.org/z7hi6mz3h/photo.png
top - 03:02:43 up 9 min, 2 users, load average: 50.83, 30.14, 12.83
Tasks: 432 total, 1 running, 430 sleeping, 0 stopped, 1 zombie
Cpu(s): 0.1%us, 0.2%sy, 0.0%ni, 66.5%id, 33.1%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 32939992k total, 3111604k used, 29828388k free, 84108k buffers
Swap: 2048280k total, 0k used, 2048280k free, 1621640k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
2860 root 20 0 25820 2288 1420 S 3 0.0 0:11.18 htop
1182 root 20 0 0 0 0 D 2 0.0 0:01.46 kjournald
1935 mysql 20 0 12.3g 161m 7924 S 1 0.5 102:31.45 mysqld
11 root 20 0 0 0 0 S 0 0.0 0:00.38 kworker/0:1
1822 www-data 20 0 247m 25m 4188 D 0 0.1 0:01.81 apache2
2920 www-data 20 0 0 0 0 Z 0 0.0 0:01.20 apache2 <defunct>
2942 www-data 20 0 247m 23m 3056 D 0 0.1 0:00.20 apache2
3516 www-data 20 0 247m 23m 3028 D 0 0.1 0:00.06 apache2
3521 www-data 20 0 247m 23m 3020 D 0 0.1 0:00.09 apache2
3664 www-data 20 0 247m 23m 3132 D 0 0.1 0:00.09 apache2
3674 www-data 20 0 247m 23m 3252 D 0 0.1 0:00.06 apache2
3713 www-data 20 0 247m 23m 3040 D 0 0.1 0:00.09 apache2
1 root 20 0 24328 2284 1344 S 0 0.0 0:03.09 init
2 root 20 0 0 0 0 S 0 0.0 0:00.00 kthreadd
3 root 20 0 0 0 0 S 0 0.0 0:00.01 ksoftirqd/0
6 root RT 0 0 0 0 S 0 0.0 0:00.00 migration/0
7 root RT 0 0 0 0 S 0 0.0 0:00.00 watchdog/0
8 root RT 0 0 0 0 S 0 0.0 0:00.00 migration/1
9 root 20 0 0 0 0 S 0 0.0 0:00.00 kworker/1:0
root@server:~/codes# vmstat 1
procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----
r b swpd free buff cache si so bi bo in cs us sy id wa
19 0 0 29684012 86112 1689844 0 0 19 590 254 231 48 0 47 5
23 0 0 29704812 86128 1697672 0 0 4 320 11100 8121 77 1 22 0
33 0 0 29671044 86156 1705308 0 0 0 5440 13190 9140 95 1 4 0
33 3 0 29670088 86160 1706288 0 0 0 32932 12275 7297 99 0 1 0
35 0 0 29693456 86188 1710724 0 0 4 676 12701 7867 98 1 1 0
^C
我没有更改 Ubuntu 的任何默认配置。对于如此强大的服务器,这种负载正常吗?我可以对 Apache/MySQL 进行任何优化以最大限度地减少负载吗?你有什么建议?
编辑:平均负载为 52!!!!!!! http://zertux.com/IMG_0117.PNG
****更新**** 事实证明,DBA 没有在表中添加索引,添加索引后,平均负载急剧从 93 下降到 1.2 :) 一切都非常棒,谢谢大家的帮助!
答案1
我觉得还不错。
您有 12 个核心,分布在 2 个 6 核 CPU 上。因此,在 100% 性能下,您的平均负载应为 12。
平均负载很有趣。我不认为它的意思和你想象的一样。
平均负载实际上表示了在任意时刻有多少个进程在运行,以 1、5 和 15 分钟的时间窗口为平均值。
在我看来,你的承诺有点过多,但也不是太过分。
也许使用http://mysqltuner.pl/mysqltuner.pl了解你的 mysqld 设置如何等同于实际使用量。
下一步当然是将 MySQL 和 Apache 分离到不同的机器上。我不确定你是否已经达到这个水平,因为你仍然有一个满载MySQL 可以使用的内存空间。您可能会发现将查询缓存和键缓冲区增大会带来一些好处,并且可能会更深入地了解MySQL 的慢查询日志,看看是否可以优化表格。
关于如何读取平均负载的信息有很多,实际上,将平均负载数除以核心数更为合理,这样您就可以了解服务器的实际利用率。
我现在可以看到您的 iowait 为 33%。我怀疑……您的数据库写入操作相当繁重,这导致您在写入时表被锁定,这意味着无法进行并发写入。
拥有闻了一下在 my.cnf 中,max_connections 似乎相当高,但这不是什么大问题,但这确实意味着如果您使用所有这些连接,您将需要 27GB 的 RAM 来实现这一点。这虽然很多,但也不是大问题。
**编辑**
现在看过查询日志后,我倾向于认为有一些事情可能对服务器有益。
- PHP APC Opcode 缓存(使 apache 通常更高效)
- 将所有表转换为 InnoDB,除非你有一个真的理由很充分。如果原因是全文搜索,那么请找到更好的方法,然后转向 InnoDB。
- 购买另一台服务器,并将其设为专用的 DB 主机。为其安装 SAS 磁盘,并将其分成多个分区,以便日志记录和数据位于不同的主轴上(或者更确切地说,RAID 阵列)。
如果不深入研究到底发生了什么,就很难说。
值得尝试一下新Relic适用于 PHP。它免费使用一个月,并且确实能够很好地洞察不良代码味道。
另外,我也可以提供咨询;)
答案2
您的顶部输出中有一个引人注目的点,那就是 D 状态的进程数。 apache2 甚至 kjournald 的很大一部分都处于 D 状态。 众所周知,D 状态进程会增加 CPU 负载。
通常情况下,进程在等待 IO 时会进入 D 状态。获得 IO 后,它会再次从 D 状态进入 R 状态或 S 状态。执行实时调试的下一件事是检查这些 D 状态进程运行了多长时间。如果运行了很长时间,则存在问题。
无论如何,如果平均负载较高,您的问题就在于 IOwait,因为 top 报告的 iowait 值为 33.1%。%usr 和 %sys 并不多,因此我们可以放心地忽略进程失控、CPU 性能不佳或内存瓶颈。问题显然是 iowait。我主要使用 RHEL,所以我不能 100% 确定 ubuntu 以及是否有任何内置工具。
我主要做的是收集 top、vmstat 和 iostat 的多次迭代(使用适当的开关显示设备分解)、ps 和 ps -xv 的一次迭代并检查它们。通常,第一级调试可以从这么多中完成。接下来,我可能会收集一些 oprofile、perf 输出,具体取决于 RHEL 版本,但那是另一回事。
无论如何,请同时检查所有调试命令以获得更细致的视图。
答案3
我怀疑进程可能正在等待 IO,这可能导致平均负载过高。毕竟平均负载依赖于 CPU 的可运行进程队列。你在 iostat 命令中看到任何高值了吗?
答案4
我在使用 Ubuntu 12.04 桌面版时也遇到了类似的问题(它被用作服务器(不是我的选择))。
如果你已经在机器上安装了桌面管理器,你可能会发现vsync是问题所在。
Unity dm 导致 CPU 负载持续升高,关闭 vsync 立即解决了这个问题。我不知道其他 dm 是否也会导致此问题。