Windows Server で NFS 共有を使用すると、メモリが枯渇する場合があります。

現象

以下のような状況を想定します。

・Windows Server で、NFS サーバーのファイル共有を構築します。

・NFS クライアントから NFS v3 プロトコルで非同期書き込みが実行されるオプションを指定して、NFS サーバー上のファイル共有をマウントします。

・NFS クライアントから大量の非同期の Write 要求を発生させます。(大きなファイルや大量のファイルを NFS サーバーへ書き込んだりコピーしたりする場合。)

この場合、NFS サーバーが使用する非ページプールのメモリ量が増加していき、その分、利用可能なメモリが減ります。利用可能なメモリが 0 に近づくと、Windows やその上で動作するアプリケーションまたはドライバーなどによるメモリ確保が失敗する場合があります。

原因


NFS サーバー上では、非同期の書き込み要求を受けると、非ページプールメモリ(プールタグ ‘XdBP’)から書き込み用のバッファ領域を確保し、そのデータがディスクに書き込まれた時点でバッファも解放されます。しかし、前述のシナリオではディスクへの書き込み処理が、クライアントからの要求量に追い付かない場合に、バッファとして確保される非ページプールメモリの使用量が増加していき、最終的にはメモリが確保できなくなります。

この現象は、NFSクライアントからのNFS書き込み要求のスループット(転送速度)が、NFSサーバーのディスクへの書き込みスループットよりも速い場合に発生します。また、NFSサーバー上で、NFS 以外の処理によりディスクの負荷が高い場合は、NFSサーバーからのディスクへの書き込みスループットが低下し、事象が発生しやすくなります。

なお、本現象はメモリリークではありませんので、クライアントからの要求が終了したり、ディスクへの書き込みが完了すれば、非ページプールメモリの使用量も減り、元の状態に戻ります

回避策

NFS クライアントから NFS v3でマウントする際に、mountコマンドのオプション指定等により書き込み要求が同期書き込みとなるように設定してください。(NFSクライアントのOSがLinuxの場合は、mountコマンドでsyncオプションを指定します。)

これにより、NFS サーバーはディスクへの書き込みが終わってバッファを解放するまでは、NFS クライアントに応答を返さないため、NFS サーバーで使用するバッファの増加を抑えることができます。ただし、同期書き込みのmountオプションを指定した場合、NFS クライアントから見た書き込みのパフォーマンスは低下します。

NFS サーバーで使用するストレージ装置自体がキャッシュ機能を持つ場合、ストレージのキャッシュ機能を有効にすることでも回避できる場合があります。

詳細


NFS クライアントからの書き込み要求が非同期であるかどうかを確認する方法として、ネットワークキャプチャーを採取して判断することもできます。以下では例として Network Monitor 3.4 を使用して表示したパケットの内容を示しています。

非同期書き込みの例:

===================================================================================================================================================================
  Frame: Number = 118, Captured Frame Length = 1514, MediaType = ETHERNET
+ Ethernet: Etype = Internet IP (IPv4),DestinationAddress:[XX-XX-XX-XX-XX-XX],SourceAddress:[YY-YY-YY-YY-YY-YY]
+ Ipv4: Src = 192.168.0.1, Dest = 192.168.0.2, Next Protocol = TCP, Packet ID = 38425, Total IP Length = 1500
+ Tcp: Flags=...A...., SrcPort=XSTP(723), DstPort=NFS(2049), PayloadLen=1448, Seq=1988860094 - 1988861542, Ack=1951608740, Win=165 (scale factor 0x7) = 21120
+ SunRpcOverTcp: SunRPCOverTCP Blob
+ SunRPC: Call, Program = nfs, Procedure = Write to file
- Nfs: Write to file Call
  - WriteCall:
   + File:
     FileOffset: 0 (0x0)
     Count: 32768 (0x8000)
     Stable: UNSTABLE, 0(0x0)    <=「非同期」の指定。この場合は問題事象が発生する可能性があります。
   + Data:(略)

===================================================================================================================================================================

同期書き込みの例:

===================================================================================================================================================================
  Frame: Number = 265, Captured Frame Length = 1514, MediaType = ETHERNET
+ Ethernet: Etype = Internet IP (IPv4),DestinationAddress:[ XX-XX-XX-XX-XX-XX],SourceAddress:[ YY-YY-YY-YY-YY-YY]
+ Ipv4: Src = 192.168.0.1, Dest = 192.168.0.2, Next Protocol = TCP, Packet ID = 12530, Total IP Length = 1500
+ Tcp: Flags=...A...., SrcPort=itm-mcell-s(828), DstPort=NFS(2049), PayloadLen=1448, Seq=2866318645 - 2866320093, Ack=1346024332, Win=207 (scale factor 0x7) = 26496
+ SunRpcOverTcp: SunRPCOverTCP Blob
+ SunRPC: Call, Program = nfs, Procedure = Write to file
- Nfs: Write to file Call
  - WriteCall:
   + File:
     FileOffset: 163840 (0x28000)
     Count: 32768 (0x8000)
     Stable: FILE_SYNC, 2(0x2)   <=「同期」の指定。この場合は問題事象は発生しません。
   + Data: (略)
プロパティ

文書番号:3193544 - 最終更新日: 2016/09/16 - リビジョン: 1

Windows Server 2012 R2 Standard, Windows Server 2012 R2 Datacenter, Windows Server 2012 Standard, Windows Server 2012 Standard, Windows Server 2012 Standard, Windows Server 2012 Standard, Windows Server 2012 Datacenter, Windows Server 2012 Datacenter, Windows Server 2012 Datacenter, Windows Server 2012 Datacenter, Windows Server 2008 R2 Enterprise

フィードバック