[对不起,我试图保持简短,但这是不可能的]
我在 Fujitsu Siemens Primergy RX200 S3 上运行 Linux 2.6.22.19 和linux - vserver 2.3.0.34用于开发目的。Intel(R) Xeon(R) 5140 @ 2.33Ghz,4GB RAM(其中大部分 500MB 仍然可用)。服务器有两个热插拔 250GB 用于镜像 RAID 配置:
dev:~# mpt-status --newstyle
ioc:0 vol_id:0 type:IM raidlevel:RAID-1 num_disks:2 size(GB):231 state: OPTIMAL flags: ENABLED
ioc:0 phys_id:0 scsi_id:1 vendor:ATA product_id:WDC WD2500JS-55N revision:2E01 size(GB):232 state: ONLINE flags: NONE sync_state: 100 ASC/ASCQ:0xff/0xff SMART ASC/ASCQ:0xff/0xff
ioc:0 phys_id:1 scsi_id:8 vendor:ATA product_id:WDC WD2500JS-55N revision:2E01 size(GB):232 state: ONLINE flags: NONE sync_state: 100 ASC/ASCQ:0xff/0xff SMART ASC/ASCQ:0xff/0xff
scsi_id:0 100%
scsi_id:1 100%
我正在运行LVM和 ext3。
我们从 2007 年 7 月/8 月左右开始使用这台机器,除了同一天修复的损坏的 RAM 之外,没有任何问题。而且,基本上,一切都比我们以前的机器好。
然而,性能问题是在 2008 年 8 月左右首次发现的,直到最近我才对问题的出处充满信心。现在平均有七台虚拟服务器在运行(三台 MySQL 机器、两台 tomcat、三台 Apache、Hudson、CruiseControl、MediaWiki、Samba 等)。但不要产生错误的印象,就开发人员和其他访问服务器的人而言,我们是一家小公司,所以没有那么多事情发生(浏览 MediaWiki,Hudson 自动化在晚上运行,大多数 Apache/PHP 应用程序有很多静态内容)。
安装 munin 后,我开始看到有趣的东西,尤其是在夜间。由于在每个虚拟服务器中都在find
运行(同时,无处不在)负载猛增到像 15、17 或 20 这样的虚数。
但最终问题不仅存在于夜间(我开始禁用查找工作,反正没有使用),而且还存在于白天,尤其是当我们最近开始一个项目时,我们必须使用数据库一个 500MB 的 MySQL 转储文件。
我第一次在工作时间导入转储文件(mysql < dump.sql
; 在我们的一个运行 MySQL 实例的虚拟服务器中),定时输出是:
real 71m28.630s
user 0m15.477s
sys 0m10.185s
由于我没有注意并且正在开会,所以只是我的同事问我服务器出了什么问题,因为他非常慢。
我在晚上重新进行了测试,在主机上安装了一个 vanilla Debian MySQL(不是在来宾内部;关闭所有这些)并达到以下数字:
real 48m33.067s
user 0m15.397s
sys 0m13.517s
我还是觉得是的,很好,这是 500MB 的转储文件;转储到 InnoDB 空间大约需要 1GB,这是相当多的数据。我做了一些测试,比如在这样的测试期间将一行写入文件vim
并使用 strace 捕获它:
0.000048 write(1, "\33[?25l\"foo\" \33[78;7H\33[K", 22) = 22
0.000033 stat64("foo", 0xbfda1f04) = -1 ENOENT (No such file or directory)
0.000033 open("foo", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 4
0.000035 write(4, "thios isthis ia a testa\n", 24) = 24
0.000144 fsync(4) = 0
7737.631089 stat64("foo", {st_mode=S_IFREG|0664, st_size=24, ...}) = 0
0.000084 close(4) = 0
0.000117 write(1, "\33[78;7H[New] 1L, 24C written", 28) = 28
0.000051 lseek(3, 0, SEEK_SET) = 0
0.000022 write(3, "b0VIM 7.0\0\0\0\0\20\0\0\0\0\0\0\0\0\0\0!\21\0\0mark"..., 4096) = 4096
0.000052 select(1, [0], NULL, [0], {0, 0}) = 1 (in [0], left {0, 0})
这对我来说是一个令人难以置信的事实数字。似乎 stat64 系统调用被迫等待转储操作完成。更不用说在这样的转储期间在 MediaWiki 中提供页面也需要几分钟。
无论如何,我与我们的托管公司安排了一个测试时间框架,在晚上在我们的生产服务器上进行测试,我得到了完全不同的画面:
real 7m4.063s
user 0m2.690s
sys 0m30.500s
我被吹走了。我还获得了 Amazon EC2 的测试批准,而且我得到的数字更低(在 m1.large 实例上大约 5 分钟,其中 MySQL 数据被写入 EBS 卷以保持永久状态)。
此外,在导入数据时,其他所有操作都变得如此缓慢,以至于事情变得无法使用,并且负载迅速上升到 5 或 7(尽管似乎并没有发生太多事情;看起来进程开始相互阻塞现在的理由)。
然后我开始做bonnie++ 测试,看起来像这样(我实际上从去年开始进行了一次测试,但我几乎忘记了)。所以这里是2008 年 10 月:
Version 1.03 ------Sequential Output------ --Sequential Input- --Random-
-Per Chr- --Block-- -Rewrite- -Per Chr- --Block-- --Seeks--
Machine Size K/sec %CP K/sec %CP K/sec %CP K/sec %CP K/sec %CP /sec %CP
vserver-host 8G 12332 21 12600 3 10290 2 48519 74 52431 6 235.8 0
------Sequential Create------ --------Random Create--------
-Create-- --Read--- -Delete-- -Create-- --Read--- -Delete--
files /sec %CP /sec %CP /sec %CP /sec %CP /sec %CP /sec %CP
16 +++++ +++ +++++ +++ +++++ +++ +++++ +++ +++++ +++ +++++ +++
vserver-host,8G,12332,21,12600,3,10290,2,48519,74,52431,6,235.8,0,16,+++++,+++,+++++,+++,+++++,+++,+++++,+++,+++++,+++,+++++,+++
这是2009 年 4 月的当前版本:
Version 1.03 ------Sequential Output------ --Sequential Input- --Random-
-Per Chr- --Block-- -Rewrite- -Per Chr- --Block-- --Seeks--
Machine Size K/sec %CP K/sec %CP K/sec %CP K/sec %CP K/sec %CP /sec %CP
vserver-host 8G 9705 16 7268 1 4823 1 29620 45 41336 5 73.1 0
------Sequential Create------ --------Random Create--------
-Create-- --Read--- -Delete-- -Create-- --Read--- -Delete--
files /sec %CP /sec %CP /sec %CP /sec %CP /sec %CP /sec %CP
16 11678 15 +++++ +++ +++++ +++ +++++ +++ +++++ +++ 27739 31
vserver-host,8G,9705,16,7268,1,4823,1,29620,45,41336,5,73.1,0,16,11678,15,+++++,+++,+++++,+++,+++++,+++,+++++,+++,27739,31
我不知道在哪里调整什么来摆脱问题,因为我还不完全确定真正的问题在哪里/是什么。我想我开始看不到树木了。
更新1:
感谢到目前为止的反馈,我首先选择了可以轻松测试而无需安排维护时间的东西。
首先,我测试了 MySQL 转储/dev/null
:
dev01:~$ time mysqldump -u root -h db01 database-p >/dev/null
Enter password:
real 0m18.871s
user 0m12.713s
sys 0m0.512s
系统负载几乎不引人注意:
10:27:18 up 77 days, 9:10, 7 users, load average: 0.16, 0.75, 0.67
[...]
10:27:33 up 77 days, 9:10, 7 users, load average: 0.52, 0.79, 0.69
此测试期间的sar
输出也没有显示任何特别之处:
12:11:45 PM DEV tps rd_sec/s wr_sec/s avgrq-sz avgqu-sz await svctm %util
12:11:46 PM dev8-0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
12:11:46 PM dev254-0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
12:11:46 PM dev254-1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
12:11:46 PM DEV tps rd_sec/s wr_sec/s avgrq-sz avgqu-sz await svctm %util
12:11:47 PM dev8-0 5.00 0.00 200.00 40.00 0.18 36.00 20.00 10.00
12:11:47 PM dev254-0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
12:11:47 PM dev254-1 25.00 0.00 200.00 8.00 0.74 29.60 4.00 10.00
然后我在转储到文件时运行测试:
dev01:~$ time mysqldump -u root -h db01 database -p >foo.sql
real 1m7.527s
user 0m13.497s
sys 0m2.724s
它所花费的时间对我来说并不奇怪,转储以一个 570MB 的文件结束。
但是,负载非常有趣...
10:30:49 up 77 days, 9:14, 7 users, load average: 0.76, 0.89, 0.75
10:30:57 up 77 days, 9:14, 7 users, load average: 1.34, 1.01, 0.79
10:31:05 up 77 days, 9:14, 7 users, load average: 2.13, 1.19, 0.85
10:31:13 up 77 days, 9:14, 7 users, load average: 2.68, 1.32, 0.89
10:31:21 up 77 days, 9:14, 7 users, load average: 3.79, 1.60, 0.99
10:31:29 up 77 days, 9:14, 7 users, load average: 4.05, 1.69, 1.02
10:31:37 up 77 days, 9:14, 7 users, load average: 4.82, 1.93, 1.10
10:31:45 up 77 days, 9:15, 7 users, load average: 4.54, 1.97, 1.12
10:31:53 up 77 days, 9:15, 7 users, load average: 4.89, 2.08, 1.16
10:31:57 up 77 days, 9:15, 7 users, load average: 5.30, 2.22, 1.21
10:32:01 up 77 days, 9:15, 7 users, load average: 5.12, 2.23, 1.22
10:32:05 up 77 days, 9:15, 7 users, load average: 5.03, 2.26, 1.24
10:32:13 up 77 days, 9:15, 7 users, load average: 4.62, 2.22, 1.23
......就像sar
......
12:16:47 PM DEV tps rd_sec/s wr_sec/s avgrq-sz avgqu-sz await svctm %util
12:16:48 PM dev8-0 116.00 0.00 21712.00 187.17 134.04 559.31 8.62 100.00
12:16:48 PM dev254-0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
12:16:48 PM dev254-1 3369.00 0.00 26952.00 8.00 3271.74 481.27 0.30 100.00
12:16:48 PM DEV tps rd_sec/s wr_sec/s avgrq-sz avgqu-sz await svctm %util
12:16:49 PM dev8-0 130.00 0.00 17544.00 134.95 143.78 752.89 7.69 100.00
12:16:49 PM dev254-0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
12:16:49 PM dev254-1 1462.00 0.00 11696.00 8.00 2749.12 1407.78 0.68 100.00
12:16:49 PM DEV tps rd_sec/s wr_sec/s avgrq-sz avgqu-sz await svctm %util
12:16:50 PM dev8-0 128.00 0.00 18400.00 143.75 143.68 1593.91 7.84 100.40
12:16:50 PM dev254-0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
12:16:50 PM dev254-1 810.00 0.00 6480.00 8.00 1598.99 4911.94 1.24 100.40
在这个测试中,我很快开始vim
做一个简单的写测试。自身的加载vim
也很缓慢,但我无法从strace
. 只有挂起的stat64
呼叫再次清晰可见:
0.000050 stat64("bla", 0xbf98caf4) = -1 ENOENT (No such file or directory)
0.000038 open("bla", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 4
0.000053 write(4, "fooo\n", 5) = 5
0.000051 fsync(4) = 0
5.385200 stat64("bla", {st_mode=S_IFREG|0664, st_size=5, ...}) = 0
0.000073 close(4) = 0
我会尽快追加进一步的文件系统测试。
更新 2 / 解决方案:
根据 Mihai 关于 MTP 设备和 RAID 配置的反馈,我对该主题进行了深入研究。通过lspci
我检索到 RAID 控制器信息:
dev:~$ sudo lspci|grep -i lsi
05:05.0 SCSI storage controller: LSI Logic / Symbios Logic SAS1068 PCI-X Fusion-MPT SAS (rev 01)
出乎意料的是,a 在http://www.ask.com/web?q=linux+problem+performance+SAS1068上试了一下,发现LSI Logic SAS1068 存在写入性能问题。错误描述进一步链接到博客谈论DELL PE860 性能问题,该问题也使用 SAS1068。
文章提到了LSIUtil 的使用,可从 lsi.com 获得。这篇文章还lsiutil
详细介绍了描述如何打开写入缓存的菜单。
毫不奇怪,事实证明这对性能有重大影响。激活前:
dev:~# time (dd if=/dev/zero of=bigfile count=1024 bs=1M; sync)
1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB) copied, 180.902 seconds, 5.9 MB/s
real 3m8.472s
user 0m0.004s
sys 0m3.340s
启用写缓存后:
dev:~# time (dd if=/dev/zero of=bigfile count=1024 bs=1M; sync)
1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB) copied, 43.7899 seconds, 24.5 MB/s
real 0m46.413s
user 0m0.000s
sys 0m3.124s
这就像白天和黑夜,黑白。有时感觉自己很愚蠢是可以的。我可能应该知道 RAID 控制器默认禁用写缓存。
更新 3:
我偶然发现了一个名为diskstat的 munin 插件,它为所有块设备提供了详细的 IO、读/写/等待等图表。作者还有一篇非常不错且详细的博文,标题为Graphing Linux Disk I/O statistics with Munin。
这对我来说是一个令人难以置信的事实数字。似乎 stat64 系统调用被迫等待转储操作完成。
这就是你要找的线索。我敢打赌,这里的罪魁祸首是 ext3。默认情况下,在 ext3 下,任何用户帐户下的任何应用程序发出的任何 fsync 都会强制将整个日志写入磁盘。如果您正在运行经常需要发出 fsync() 调用的数据库,这尤其令人讨厌。在不支持写屏障的 RAID 设备上运行时,这更加烦人(不知道 MPT 设备是否支持它们,抱歉。)
如果您对 UPS 和服务器的稳定性有相当的把握,请尝试使用
data=writeback
mount 选项而不是默认的data=ordered
. 面对服务器崩溃,您将牺牲可靠性,但如果您的性能受到如此糟糕的影响,那也不是什么大损失。不过,长期的解决方案可能是切换到更好的文件系统。目前我会推荐 XFS。我已经使用了多年,没有出现大问题。唯一的缺点是它不能像 ext2/3 一样被缩小——虽然它可以被扩展。
尝试做 mysql dump do
/dev/null
。这将告诉您是写作部分还是阅读部分负责。尝试将转储写入单独的逻辑卷/文件系统或 RAM 磁盘。
检查
journal
文件系统上的 ling 选项。检查文件系统上的
noatime
/状态atime
文件系统是否已满?通常,当其上的数据量达到某个阈值时,性能会降低。
这里有一些来自其他海报的关于排除软件和调整 RAID 性能的好建议。值得一提的是,如果您的工作负载写入繁重,那么如果您正在考虑更换套件,那么选择具有电池支持的写入缓存的硬件可能是正确的做法。
闻起来就像您只是在填充 IO 容量。首先检查以确保您的一个磁盘没有死掉(扇区重新映射会对 IO 造成不良影响),然后运行
sar -d 1 0
并查看%util
物理磁盘的数量。如果增加了 100% 左右,那么我只需投入更多的主轴,将它们放入 RAID-10 中。你不会获得双倍的性能,但它会给你更多的魅力。如今,250GB 的磁盘并不是非常昂贵。哦,为了让我的工作更皮条客,把一堵文字墙与你的文字墙交战,我写的一个指南来追踪性能问题:http ://www.anchor.com.au/hosting/development/ HuntingThePerformanceWumpus涵盖了您应该了解的有关跟踪性能问题的所有信息。