web-dev-qa-db-ja.com

Oracle Linux 6.7でのNFSパフォーマンスの問題:NFS上の共有ライブラリはシステムの速度を低下させます

現在、同じ量のメモリとCPUを搭載し、Oracle Linux 6.6(カーネル2.6)と6.7(カーネル3.8)を実行している一部のVMWare仮想マシンでパフォーマンスの問題を探しています。マシンは、LD_LIBRARY_PATHを使用したビルドに含まれるいくつかの共有ライブラリを含むNFS4を介して同じ共有をマウントします。どちらのシステムも同じマウントオプション(デフォルト)を使用します。これは、6.7の場合は「ハード」、6.6の場合は「ソフト」を意味するようです。 6.7から、CPUが約80%アイドル状態のときに、コンパイルプロセスのパフォーマンスが5分の1に低下することがわかりましたが、高いio-waitも観察できませんでした(上位レポート〜0.4%wa)。

問題を再現しようとすると、コンパイルだけでなく、たとえば「ls」などのほとんどすべてのコマンドが、NFSマウントからの共有ライブラリがLD_LIBRARY_PATHを介して含まれるとすぐに、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

LD_LIBRARY_PATHなしの6.7の場合

$ 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

巨大なオーバーヘッドが私を興味深くさせ、straceを使用して、NFS共有上のいくつかの共有ライブラリの解決に非常に長い時間がかかることがわかりました。

繰り返しますが、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ではいくつかの(失敗した)オープンに非常に長い時間がかかります(〜0.000020と比較して最大0.01)。

そこで私は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の長いオープン時間を確認しているようですが、マウントオプションなどでこれに取り組む方法がよくわかりません。

より多くの実験では、最新のOS(CentOS 7、Ubuntu 16.04)を使用してDockerコンテナー内からNFSをマウントした場合でも、nfsutilsなどの問題を除外するために、6.7ホストでのパフォーマンスは常に同じ遅いパフォーマンスを示しました。 NFS4を使用する場合。 NFS3を使用すると、6.7でのパフォーマンスは6.6と同じくらい良好です。

この時点で、基盤となるホストのkernel(-module)またはvmware-toolsのいずれかが問題を引き起こすと予想していますが、さらに掘り下げる方法がわかりません。

これは既知の問題ですか?考えられる原因を見逃しましたか?さらに掘り下げますか?NFSクライアントのプロファイルを作成する方法はありますか?vmwareドライバーを問題として除外するにはどうすればよいですか?

そしてもちろん:誰か私のための簡単な解決策はありますか?

編集:今朝は少し違う方向にDigを実行しました:tcpdumpを使用してNFSトラフィックを(再度)チェックしましたが、6.7ではキャッシュが発生していないようです。 LD_LIBRARY_PATHにはほとんどのライブラリが含まれていないため、(存在しない)共有ライブラリにアクセスするたびに、常に実際のNFSトラフィックが発生します。通常はreply ok 52 getattr ERROR: No such file or directoryを返します。 6.6では、最初のものだけが実際のトラフィックを引き起こします。これを学んだので、NFSパスをLD_LIBRARY_PATHからコンパイルプロセスに必要なライブラリを含む追加のld.so.confファイルに移動することで、「ls」などの標準コマンドの根本的なパフォーマンスの問題を回避することができました。ただし、これはまだ回避策であり、問​​題は、NFSクライアントでキャッシュが発生していないことであるように思われます。そこで、提案されているように、NFSでファイルシステムキャッシュを再度アクティブ化しようとしました ここ 、それでもすべての「オープン」はNFSトラフィックを引き起こし、コンパイルは依然として許容できないほど遅いです。

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のキャッシュはアクティブではなく(/ var/cache/fscache/*は空です)、今朝マウントオプションでfscを使用すると、実際には6.7の3つのファイルが含まれますが、非キャッシュは表示されないようです。既存の共有ライブラリパスであるため、パフォーマンスは変更されていません。存在しないファイルの場合、acregminなどが影響を与えると思いますが、それらの(デフォルトの)値は(私には)妥当なように見えますが、効果はないようです。

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、...)の意味を誰かが知っていますか?

サニタイズされたpsax出力: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の出力を比較すると、6.6では600に設定され、6.7では0に設定されているfs.nfs.idmap_cache_timeoutに違いが見られたときに、問題が見つかったと確信していましたが、また、望ましい効果がありませんでした。

ただし、別の便利なコマンドを見つけました。rpcdebug -m nfs -s allは、キャッシュに関する多くのデバッグ情報をシステムログ(私の場合は/var/log/messages)に出力します。私のlsを実行するときのほとんどのエントリは次のようになります

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

これらのうち、1秒あたり複数のインスタンスをブロックします(これはlookupcache=allでも同様です)。

乾杯!

4
Nodebody

ところで、softマウントの使用には注意してください:

ソフトマウントされたファイルシステムでは、不完全な書き込みによるデータの損傷、スワップされたプロセスのテキストセグメントへのアクセスの喪失、およびソフトマウントされたファイルシステムのサーバー応答時間の変動に対する耐性を高めることを心配する必要があります。

データの整合性を保証するには、読み取り/書き込みでマウントされたすべてのファイルシステムをハードマウントする必要があります。

ソフトマウントの問題

NFSでマウントされたすべてのファイルシステムでは、hard,intrを使用することをお勧めします。

1
DLade

CentOS6.6のインストールでfs-cacheまたはnscdを使用していますか?両方のマシンのps axと、/proc/mounts/の出力を投稿できますか?

0
shodanshok