上回编译加载tcmalloc后,效果各有不同,所以还得细分具体运行情况,以便之后继续优化。 之前的架构是1个lvs下挂6台leaf+1台parent。现在已经给7台squid都加载tcmalloc了。leaf运行上佳,CPU占用率甚至降到了2%,loadavg也不过0.2。但parent的CPU占用率虽然降低,loadavg却依然在1以上——这对于单核服务器来说,可不是什么好事。分析日志,或者用squidclient分析cache情况,leaf如下: cat access.log |awk ‘{if(/NONE/){a[NONE]++}}END{print a[NONE]/NR}’ 0.981347 squidclient -p 80 mgr:info Cache information for squid: Request Hit Ratios: 5min: 97.8%, 60min: 98.3% Byte Hit Ratios: 5min: 97.8%, 60min: 98.2% Request Memory Hit Ratios: 5min: 85.8%, 60min: 86.8% Request Disk Hit Ratios: 5min: 9.8%, 60min: 9.1% Storage Swap size: 19891740 KB Storage Mem size: 1048572 KB Mean Object Size: 9.67 KB 可以看到缓存文件的平均大小不足10KB,绝大多数的请求都在内存中处理掉了。所以在加载了优化内存反应速度的tcmalloc后,效果那么明显。 parent如下: $ cat access.log |awk ‘{if(/NONE/){a[NONE]++}}END{print a[NONE]/NR}’ 0.179209 $ squidclient -p 80 mgr:info Cache information for squid: Request Hit Ratios: 5min: 31.1%, 60min: 32.3% Byte Hit Ratios: 5min: 38.4%, 60min: 36.9% Request Memory Hit Ratios: 5min: 7.8%, 60min: 12.2% Request Disk Hit Ratios: 5min: 32.7%, 60min: 37.9% Storage Swap size: 40300232 KB Storage Mem size: 524284 KB Mean Object Size: 11.68 KB 只有30%的缓存命中,而且基本还都是从磁盘读取的(awk结果排除了REFRESH_HIT,所以更低)。难怪上次优化没什么效用了…… 为了保证服务,先给这组服务器加上了round-robin的双parent。新parent的硬件情况和老的一样。而squid配置上,则采用了aufs方式,不再使用diskd方式。运行到现在30个小时,分析如下: $ cat /cache/logs/access.log |awk ‘{if(/NONE/){a[NONE]++}}END{print a[NONE]/NR}’ 0.238754 $ squidclient -p 80 mgr:info Cache information for squid: Request Hit Ratios: 5min: 22.7%, 60min: 22.8% Byte Hit Ratios: 5min: 22.9%, 60min: 20.1% Request Memory Hit Ratios: 5min: 22.2%, 60min: 24.3% Request Disk Hit Ratios: 5min: 64.4%, 60min: 65.0% Storage Swap size: 4640308 KB Storage Mem size: 1048588 KB Mean Object Size: 9.08 KB
看起来差不多的样子。 因为确认mem没怎么用上,下一步看disk的I/O。 采用diskd的parent如下:
[root@tinysquid2 ~]# iostat -x /dev/xvdb2 5 5
Linux 2.6.18-128.el5xen (tinysquid2)
02/06/2010
avg-cpu: %user %nice %system %iowait %steal %idle
0.00 0.00 0.00 10.00 0.00 90.00
Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s avgrq-sz avgqu-sz await svctm %util
xvdb2
0.00 5.00 8.60 46.60 81.60 412.80 8.96 0.32 5.80 1.75 9.68
采用aufs的parent如下:
[root@tinysquid3 ~]# iostat -x /dev/xvdb2 5 5
Linux 2.6.18-128.el5xen (tinysquid3)
02/06/2010
avg-cpu: %user %nice %system %iowait %steal %idle
0.20 0.00 0.40 1.60 0.20 97.60
Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s avgrq-sz avgqu-sz await svctm %util
xvdb2
0.00 8.58 3.19 6.19 25.55 118.16 15.32 0.02 2.47 1.70 1.60
以上结果的解释如下:
rrqm/s: 每秒进行 merge 的读操作数目。即 delta(rmerge)/s
wrqm/s: 每秒进行 merge 的写操作数目。即 delta(wmerge)/s
r/s: 每秒完成的读 I/O 设备次数。即 delta(rio)/s
w/s: 每秒完成的写 I/O 设备次数。即 delta(wio)/s
rsec/s: 每秒读扇区数。即 delta(rsect)/s
wsec/s: 每秒写扇区数。即 delta(wsect)/s
rkB/s: 每秒读K字节数。是 rsect/s 的一半,因为每扇区大小为512字节。(需要计算)
wkB/s: 每秒写K字节数。是 wsect/s 的一半。(需要计算)
avgrq-sz: 平均每次设备I/O操作的数据大小(扇区)。delta(rsect+wsect)/delta(rio+wio)
avgqu-sz: 平均I/O队列长度。即 delta(aveq)/s/1000(因为aveq的单位为毫秒)。
await: 平均每次设备I/O操作的等待时间 (毫秒)。即delta(ruse+wuse)/delta(rio+wio)
svctm: 平均每次设备I/O操作的服务时间 (毫秒)。即 delta(use)/delta(rio+wio)
%util: 一秒中有百分之多少的时间用于 I/O 操作,或者说一秒中有多少时间 I/O 队列是非空的。即 delta(use)/s/1000(因为use的单位为毫秒)
从上面的运行情况看,都是w操作为主,但diskd比aufs每秒w的次数要大,而每次w的服务时间也大——大的同时波动性也不太稳定——由此导致rw时的等待时间也延长——进一步的结果就是I/O非空时间变少——最后的结果就是disk的I/O压力变大! 因为现在已经双parent,loadavg降低,所以不好看出之前的高loadavg问题关键。不过至少从现在的运行来看,aufs比diskd要好。
———————————————————————————————————————— 3月25日补充:
aufs虽然是异步io,但某些文件默认的写操作并不如此。需要在编译时修改src/fs/aufs/store_asyncufs.h中的#define ASYNC_WRIT值为1。 对于aufs,可以使用squidclient mgr:squidaio_counts查看,其中queue一项,据说不应该超过线程数量的5倍。而线程数量跟cache_dir数量的关系如下:
cache_dirs Threads 1 16 2 26 3 32 4 36 5 40 6 44