我正在使用相同数量的内存和cpus在运行Oracle Linux 6.6(Kernel 2.6)和6.7(Kernel 3.8)的VMWare虚拟机上search一些性能问题。 这些机器通过NFS4挂载相同的共享,其中包含使用LD_LIBRARY_PATH生成的一些共享库。 两个系统都使用相同的安装选项(默认),这对于6.7来说显然意味着“硬”,对于6.6来说意味着“软”。 从6.7开始,我们观察到编译过程的性能下降了5倍,而CPU闲置在80%左右,但也没有观察到高的等待时间(最高报告〜0.4%wa)。
试图重现这个问题,我很快就发现,不仅编译而且几乎所有的命令,比如“ls”,只要通过LD_LIBRARY_PATH包含来自NFS挂载的共享库,6.7就慢得多。
我用一个简单的“时间”开始了我的调查:
在6.6上:没有设置LD_LIBRARY_PATH和PATH:
$ time for i in $(seq 0 1000); do ls done; ... ls output real 0m2.917s user 0m0.288s sys 0m1.012s
LD_LIBRARY_PATH和PATH被设置为包含NFS上的目录
$ time for i in $(seq 0 1000); do ls done; ... ls output real 0m2.766s user 0m0.184s sys 0m1.051s
在6.7没有LD_LIBRARY_PATH
$ time for i in $(seq 0 1000); do ls done; ... real 0m5.144s user 0m0.280s sys 0m1.172s
和LD_LIBRARY_PATH
$ time for i in $(seq 0 1000); do ls done; ... real 1m27.329s user 0m0.537s sys 0m1.792s
巨大的开销让我感到好奇,而且我发现NFS共享上一些共享库的parsing需要很长时间:
同样,没有设置LD_LIBRARY_PATH,strace输出中的“open”调用如下所示:
$ strace -T ls 2>&1|vim - # keep only the "open" calls open("/etc/ld.so.cache", O_RDONLY) = 3 <0.000014> open("/lib64/libselinux.so.1", O_RDONLY) = 3 <0.000013> open("/lib64/librt.so.1", O_RDONLY) = 3 <0.000016> open("/lib64/libcap.so.2", O_RDONLY) = 3 <0.000014> open("/lib64/libacl.so.1", O_RDONLY) = 3 <0.000014> open("/lib64/libc.so.6", O_RDONLY) = 3 <0.000016> open("/lib64/libdl.so.2", O_RDONLY) = 3 <0.000014> open("/lib64/libpthread.so.0", O_RDONLY) = 3 <0.000014> open("/lib64/libattr.so.1", O_RDONLY) = 3 <0.000014> open("/proc/filesystems", O_RDONLY) = 3 <0.000032> open("/usr/lib/locale/locale-archive", O_RDONLY) = 3 <0.000014> open(".", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 3 <0.001255>
与LD_LIBRARY_PATH它看起来像这样:
open("/usr/local/lib/librt.so.1", O_RDONLY) = -1 ENOENT (No such file or directory) <0.000013> open("/lib64/librt.so.1", O_RDONLY) = 3 <0.000018> open("/oracle/current/lib/libcap.so.2", O_RDONLY) = -1 ENOENT (No such file or directory) <0.006196> open("/opt/development/opt/gcc/gcc-5.3.0/lib64/libcap.so.2", O_RDONLY) = -1 ENOENT (No such file or directory) <0.002042> open("/usr/local/lib/libcap.so.2", O_RDONLY) = -1 ENOENT (No such file or directory) <0.000035> open("/lib64/libcap.so.2", O_RDONLY) = 3 <0.000039> open("/oracle/current/lib/libacl.so.1", O_RDONLY) = -1 ENOENT (No such file or directory) <0.009304> open("/opt/development/opt/gcc/gcc-5.3.0/lib64/libacl.so.1", O_RDONLY) = -1 ENOENT (No such file or directory) <0.009107> open("/usr/local/lib/libacl.so.1", O_RDONLY) = -1 ENOENT (No such file or directory) <0.000023> open("/lib64/libacl.so.1", O_RDONLY) = 3 <0.000027> open("/oracle/current/lib/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory) <0.009520> open("/opt/development/opt/gcc/gcc-5.3.0/lib64/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory) <0.007850> open("/usr/local/lib/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory) <0.000024> open("/lib64/libc.so.6", O_RDONLY) = 3 <0.000030> open("/oracle/current/lib/libdl.so.2", O_RDONLY) = -1 ENOENT (No such file or directory) <0.006916> open("/opt/development/opt/gcc/gcc-5.3.0/lib64/libdl.so.2", O_RDONLY) = -1 ENOENT (No such file or directory) <0.013979> open("/usr/local/lib/libdl.so.2", O_RDONLY) = -1 ENOENT (No such file or directory) <0.000023> open("/lib64/libdl.so.2", O_RDONLY) = 3 <0.000030> open("/oracle/current/lib/libpthread.so.0", O_RDONLY) = -1 ENOENT (No such file or directory) <0.015317> open("/opt/development/opt/gcc/gcc-5.3.0/lib64/libpthread.so.0", O_RDONLY) = -1 ENOENT (No such file or directory) <0.014230> open("/usr/local/lib/libpthread.so.0", O_RDONLY) = -1 ENOENT (No such file or directory) <0.000014> open("/lib64/libpthread.so.0", O_RDONLY) = 3 <0.000019> open("/oracle/current/lib/libattr.so.1", O_RDONLY) = -1 ENOENT (No such file or directory) <0.015212> open("/opt/development/opt/gcc/gcc-5.3.0/lib64/libattr.so.1", O_RDONLY) = -1 ENOENT (No such file or directory) <0.011979> open("/usr/local/lib/libattr.so.1", O_RDONLY) = -1 ENOENT (No such file or directory) <0.000014> open("/lib64/libattr.so.1", O_RDONLY) = 3 <0.000018> open("/proc/filesystems", O_RDONLY) = 3 <0.000025> open(".", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 3 <0.000014>
除了6.6的更多的呼叫,6.7的一些(不成功的)开放需要很长时间的6.7(0.01到0.000020)。
于是我开始研究NFS。 而nfsstat确实显示了两个系统的一些惊人的不同的统计数据:
在6.7
$ nfsstat Client rpc stats: calls retrans authrefrsh 1314991 0 1315849 Client nfs v4: null read write commit open open_conf 0 0% 3782 0% 1589 0% 1 0% 561257 42% 53 0% open_noat open_dgrd close setattr fsinfo renew 0 0% 0 0% 4750 0% 383 0% 7 0% 4094 0% setclntid confirm lock lockt locku access 2 0% 2 0% 80 0% 0 0% 80 0% 538017 40% getattr lookup lookup_root remove rename link 172506 13% 20536 1% 2 0% 112 0% 541 0% 2 0% symlink create pathconf statfs readlink readdir 0 0% 9 0% 5 0% 2057 0% 164 0% 942 0% server_caps delegreturn getacl setacl fs_locations rel_lkowner 12 0% 2968 0% 0 0% 0 0% 0 0% 80 0% secinfo exchange_id create_ses destroy_ses sequence get_lease_t 0 0% 0 0% 0 0% 0 0% 0 0% 0 0% reclaim_comp layoutget getdevinfo layoutcommit layoutreturn getdevlist 0 0% 0 0% 0 0% 0 0% 0 0% 0 0% (null) 0 0%
6.6
$ nfsstat Client rpc stats: calls retrans authrefrsh 637725 0 637781 Client nfs v4: null read write commit open open_conf 0 0% 23782 3% 13127 2% 48 0% 41244 6% 406 0% open_noat open_dgrd close setattr fsinfo renew 0 0% 0 0% 31228 4% 14668 2% 7 0% 27319 4% setclntid confirm lock lockt locku access 1 0% 1 0% 8493 1% 2 0% 8459 1% 175320 27% getattr lookup lookup_root remove rename link 134732 21% 112688 17% 2 0% 1007 0% 6728 1% 4 0% symlink create pathconf statfs readlink readdir 11 0% 129 0% 5 0% 7624 1% 143 0% 11507 1% server_caps delegreturn getacl setacl fs_locations rel_lkowner 12 0% 12732 1% 0 0% 0 0% 0 0% 6335 0% secinfo exchange_id create_ses destroy_ses sequence get_lease_t 0 0% 0 0% 0 0% 0 0% 0 0% 0 0% reclaim_comp layoutget getdevinfo layoutcommit layoutreturn getdevlist 0 0% 0 0% 0 0% 0 0% 0 0% 0 0% (null) 0 0%
这似乎证实了6.7的很长的开放时间,但是我不知道如何通过挂载选项来解决这个问题。
更多的实验表明,即使在Docker容器内部安装了最新的操作系统(CentOS 7,Ubuntu 16.04)的NFS,为了排除nfsutils等问题,在6.7主机上的性能总是显示出相同的低性能当使用NFS4。 6.7上的NFS3性能和6.6一样好。
在这一点上,我期望底层主机上的内核(-module)或者vmware-tools会导致这个问题,但是我错过了如何进一步挖掘的想法。
这是一个已知的问题吗? 我错过了一些可能的罪魁祸首吗? 你将如何进一步挖掘? 有没有一种方法来configurationNFS客户端? 我怎样才能排除VMware驱动程序的问题?
当然: 有没有人有一个简单的解决scheme?
编辑:我今天早上在一个不同的方向挖掘:与tcpdump我检查了NFS的stream量(再次),它看起来像没有caching发生在6.7。 每个对(不存在的)共享库的访问总是会导致实际的NFSstream量,因为LD_LIBRARY_PATH不包含大多数库通常返回reply ok 52 getattr ERROR: No such file or directory 。 在6.6上只有第一个造成实际的交通。 了解了这一点之后,我可以通过将LD_LIBRARY_PATH中的NFSpath移动到带有编译过程所需的库的额外ld.so.conf文件来解决标准命令(如“ls”)的基本性能问题。 但是,这仍然只是一个解决方法,现在的问题似乎是NFS客户机中没有发生caching。 所以我试着按照这里的build议再次激活NFS上的文件系统caching,但是仍然每一个“打开”都会导致NFSstream量和编译速度仍然令人难以接受。
按照shodanshok的要求:
6.6
server:/share /mnt nfs4 rw,relatime,vers=4,rsize=1048576,wsize=1048576,namlen=255,soft,proto=tcp,port=0,timeo=600,retrans=2,sec=sys,clientaddr=<clientip>,minorversion=0,local_lock=none,addr=<serverip> 0 0
在6.7(激活fsc之后)
server:/share /mnt nfs4 ro,relatime,vers=4.0,rsize=1048576,wsize=1048576,namlen=255,soft,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=<clientip>,fsc,local_lock=none,addr=<serverip> 0 0
这两台机器都不使用nscd。 不过我在前段时间在两台机器上都安装了cachefilesd,看看是否会对性能有所帮助,而不是。 目前6.6上的caching还没有活动(/ var / cache / fscache / *为空),并且在今天上午使用fsc开始,它实际上包含了6.7中的3个文件,但是它似乎并没有caching非caching,现有的共享库path,所以性能没有改变。 对于不存在的文件,我会期待acregmin等产生影响,但是尽pipe他们(默认值)对我来说似乎是合理的,但它们似乎没有任何影响。
输出mountstats
Stats for server:/share mounted on /mnt: NFS mount options: rw,vers=4.0,rsize=1048576,wsize=1048576,namlen=255,acregmin=3,acregmax=60,acdirmin=30,acdirmax=60,soft,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=10.114.160.159,fsc,local_lock=none NFS server capabilities: caps=0xfff7,wtmult=512,dtsize=32768,bsize=0,namlen=255 NFSv4 capability flags: bm0=0xfdffafff,bm1=0xf9be3e,acl=0x0,pnfs=notconfigured NFS security flavor: 1 pseudoflavor: 0
有人知道这些标志(即caps,bm0,bm1,…)是什么意思?
消毒ps ax输出:开启6.6
PID TTY STAT TIME COMMAND 1 ? Ss 0:01 /sbin/init 2 ? S 0:00 [kthreadd] 3 ? S 0:05 [ksoftirqd/0] 6 ? S 0:00 [migration/0] 7 ? S 0:10 [watchdog/0] 37 ? S< 0:00 [cpuset] 38 ? S< 0:00 [khelper] 39 ? S< 0:00 [netns] 40 ? S 0:06 [sync_supers] 41 ? S 0:00 [bdi-default] 42 ? S< 0:00 [kintegrityd] 43 ? S< 0:00 [kblockd] 50 ? S 0:49 [kworker/1:1] 51 ? S< 0:00 [xenbus_frontend] 52 ? S< 0:00 [ata_sff] 53 ? S 0:00 [khubd] 54 ? S< 0:00 [md] 55 ? S 0:01 [khungtaskd] 56 ? S 0:04 [kswapd0] 57 ? SN 0:00 [ksmd] 58 ? S 0:00 [fsnotify_mark] 59 ? S< 0:00 [crypto] 64 ? S< 0:00 [kthrotld] 66 ? S< 0:00 [kpsmoused] 240 ? S 0:00 [scsi_eh_0] 241 ? S 0:00 [scsi_eh_1] 248 ? S< 0:00 [mpt_poll_0] 249 ? S< 0:00 [mpt/0] 250 ? S 0:00 [scsi_eh_2] 313 ? S< 0:00 [kdmflush] 325 ? S 0:00 [kjournald] 445 ? S<s 0:00 /sbin/udevd -d 706 ? S< 0:00 [vmmemctl] 815 ? S< 0:00 [kdmflush] 865 ? S 0:08 [kjournald] 907 ? S 0:00 [kauditd] 1091 ? S 0:11 [flush-252:2] 1243 ? S 26:05 /usr/sbin/vmtoolsd 1311 ? Ssl 0:03 /sbin/rsyslogd -i /var/run/syslogd.pid -c 5 1334 ? Ss 0:06 cachefilesd -f /etc/cachefilesd.conf 1361 ? Ss 6:55 irqbalance --pid=/var/run/irqbalance.pid 1377 ? Ss 0:02 rpcbind 1397 ? Ss 0:00 rpc.statd 1428 ? S< 0:00 [rpciod] 1433 ? Ss 0:00 rpc.idmapd 1507 ? S< 0:00 [nfsiod] 1508 ? S 0:00 [nfsv4.0-svc] 1608 ? Ss 0:00 xinetd -stayalive -pidfile /var/run/xinetd.pid 1783 ? Ss 0:11 crond 1796 ? Ss 0:00 /usr/sbin/atd 1807 ? Ss 0:01 rhnsd 1989 ? S 99:05 /usr/lib/vmware-tools/sbin64/vmtoolsd -n vmusr 4879 ? S 0:00 /bin/sh /etc/xrdp/startwm.sh 4904 ? Ss 0:02 /bin/dbus-daemon --fork --print-pid 5 --print- address 7 --session 4924 ? S 60:14 /usr/lib/vmware-tools/sbin64/vmtoolsd -n vmusr
和6.7:
PID TTY STAT TIME COMMAND 1 ? Ss 0:01 /sbin/init 3 ? S 0:10 [ksoftirqd/0] 5 ? S< 0:00 [kworker/0:0H] 8 ? S 0:19 [migration/0] 11 ? S 0:02 [watchdog/0] 47 ? S< 0:00 [cpuset] 48 ? S< 0:00 [khelper] 49 ? S 0:00 [kdevtmpfs] 50 ? S< 0:00 [netns] 51 ? S 0:00 [bdi-default] 52 ? S< 0:00 [kintegrityd] 53 ? S< 0:00 [crypto] 54 ? S< 0:00 [kblockd] 62 ? S< 0:00 [ata_sff] 63 ? S 0:00 [khubd] 64 ? S< 0:00 [md] 66 ? S 0:00 [khungtaskd] 67 ? S 0:36 [kswapd0] 68 ? SN 0:00 [ksmd] 69 ? S 0:00 [fsnotify_mark] 80 ? S< 0:00 [kthrotld] 84 ? S< 0:00 [deferwq] 151 ? S< 0:00 [ttm_swap] 273 ? S 0:00 [scsi_eh_0] 274 ? S 0:00 [scsi_eh_1] 281 ? S< 0:00 [mpt_poll_0] 282 ? S< 0:00 [mpt/0] 283 ? S 0:00 [scsi_eh_2] 374 ? S< 0:00 [kdmflush] 387 ? S 0:00 [kjournald] 480 ? S<s 0:00 /sbin/udevd -d 872 ? S< 0:00 [kworker/2:1H] 1828 ? S< 0:00 [kdmflush] 1834 ? S< 0:00 [kdmflush] 1837 ? S< 0:00 [kdmflush] 1840 ? S< 0:00 [kdmflush] 1881 ? S 0:00 [kjournald] 1882 ? S 0:03 [kjournald] 1883 ? S 0:03 [kjournald] 1884 ? S 3:14 [kjournald] 1926 ? S 0:00 [kauditd] 2136 ? S 1:37 [flush-252:1] 2137 ? S 0:02 [flush-252:2] 2187 ? S 5:04 /usr/sbin/vmtoolsd 2214 ? S 0:00 /usr/lib/vmware-vgauth/VGAuthService -s 2264 ? Sl 1:54 ./ManagementAgentHost 2327 ? Ssl 0:00 /sbin/rsyslogd -i /var/run/syslogd.pid -c 5 2368 ? Ss 0:00 rpcbind 2390 ? Ss 0:00 rpc.statd 2425 ? S< 0:00 [rpciod] 2430 ? Ss 0:00 rpc.idmapd 2456 ? Ss 0:00 dbus-daemon --system 2473 ? S 0:00 [kworker/7:2] 2501 ? S< 0:00 [nfsiod] 2504 ? S 0:00 [nfsv4.0-svc] 2519 ? Ss 0:00 /usr/sbin/acpid 2531 ? Ssl 0:02 hald 2532 ? S 0:00 hald-runner 2564 ? S 0:00 hald-addon-input: Listening on /dev/input/ event1 /dev/input/event0 2580 ? S 0:00 hald-addon-acpi: listening on acpid socket /var/run/acpid.socket 2618 ? Ss 0:00 /usr/sbin/sshd 2629 ? Ss 0:00 xinetd -stayalive -pidfile /var/run/xinetd.pid 2778 ? S 0:00 qmgr -l -t fifo -u 2811 ? S 0:56 /usr/bin/python /usr/sbin/osad --pid-file /var/run/osad.pid 2887 ? S< 0:00 [dm_bufio_cache] 3008 ? Ss 0:00 rhnsd 3117 ? S 9:44 /usr/lib/vmware-tools/sbin64/vmtoolsd -n vmusr 3195 ? S 0:00 /usr/libexec/polkit-1/polkitd 3825 ? S< 0:17 [loop0] 3828 ? S< 0:21 [loop1] 3830 ? S< 0:00 [kdmflush] 3833 ? S< 0:00 [kcopyd] 3834 ? S< 0:00 [dm-thin] 6876 ? S 0:00 (unlinkd) 19358 ? S 0:00 [flush-0:19] 24484 ? S< 0:00 /sbin/udevd -d 24921 ? S< 0:00 /sbin/udevd -d 26201 ? Ss 0:00 cachefilesd -f /etc/cachefilesd.conf 29311 ? S< 0:00 [kdmflush] 29316 ? S 0:00 [jbd2/dm-6-8] 29317 ? S< 0:00 [ext4-dio-unwrit]
几天前,当我比较sysctl -a的输出时,我发现这个问题在两个系统上显示出fs.nfs.idmap_cache_timeout的不同,它在6.6上设置为600,在6.7上设置为0,但是也改变了它没有达到预期的效果。
但是我确实发现了另一个有用的命令: rpcdebug -m nfs -s all打印出了很多关于caching到系统日志(我的情况是/var/log/messages )的debugging信息。 当我做我的大多数条目看起来像下面
Feb 27 10:45:16 host kernel: NFS: nfs_lookup_revalidate(//opt) is valid Feb 27 10:45:16 host kernel: NFS: nfs_lookup_revalidate(opt/gcc) is valid Feb 27 10:45:16 host kernel: NFS: nfs_lookup_revalidate(gcc/gcc-5.3.0) is valid Feb 27 10:45:16 host kernel: NFS: nfs_lookup_revalidate(gcc-5.3.0/lib64) is valid
这些块每秒多个实例(甚至在lookupcache=all )。
干杯!
顺便说一句,小心使用soft安装:
使用软安装的文件系统时,您不得不担心由于写入不完整而导致数据损坏,无法访问交换进程的文本段,并使软安装的文件系统更能容忍服务器响应时间的差异。
为了保证数据的完整性,所有安装在读写上的文件系统都应该是安装好的。
软安装问题
build议在所有NFS安装的文件系统上使用hard,intr 。
你在CentOS 6.6安装中使用fs-cache或nscd吗? 你能发布两台机器的ps ax ,以及/proc/mounts/的输出吗?