25

私たちは非常に奇妙な問題に直面し、頭がおかしくなりました。ファイル共有 PC で新しく作成されたファイルが、一定期間「存在しない」場合がありました。alpha問題を再現するには、少なくとも 2 台のコンピューターが必要betaです。betaPC ( ) でファイル共有を作成し、PC\\beta\share\bugから次の PowerShell スクリプトを実行します。alpha

param(
  $sharePath="\\beta\share\bug"
)
$sharePC = ($sharePath -split '\\')[2]
$session = New-PSSession -ComputerName $sharePC
$counter = 0
while ($true) {
  $fileName = $sharePath + "\$counter.txt"
  Invoke-Command -Session $session -ScriptBlock {
    param(
      $fileName
    )
    "" > $fileName
  } -ArgumentList $fileName
  if (Test-Path $fileName) {
    Write-Host "File $fileName exists" -fore Green
  } else {
    Write-Host "!!! File $fileName does NOT exist!" -fore Red
  }

  $counter = $counter + 1
  Start-Sleep 2
}

このスクリプトを開始すると、次のメッセージが表示されるはずです。

File \\beta\share\bug\1.txt exists
File \\beta\share\bug\2.txt exists
...

そして今cmd.exe:このコマンドを開いて実行します:

if exist \\beta\share\bug\foo.txt echo 1

この後、約 10 秒間、次のメッセージが表示されます。

!!! File \\beta\share\bug\3.txt does NOT exist!
!!! File \\beta\share\bug\4.txt does NOT exist!

新しいファイルが作成される共有ディレクトリを列挙することによってバグが発生することがわかりました。バグを再現するためのPython呼び出し中。os.listdir('//beta/share/bug')C#Directory.GetDirectories(@"\\beta\share\bug")。シェルを使用して共有ディレクトリに移動し、lsまたはを呼び出すこともできdirます。

バグが見つかりましたWindows Server 2008 R2

alphaPC 上のディレクトリ コンテンツを Windows Explorer でリアルタイムで見ることはできないことに注意してください。これは、このディレクトリを Explorer で開くとバグが発生しないためです。そのため、バグを再現する前に、そのようなウィンドウをすべて閉じてください。スクリプトを再起動するたびに、既に作成されているすべてのファイルを共有から手動で削除する必要があります (スクリプトはかなり愚かで、常に 0.txt から開始されるため)。

現在、この問題には 2 つの回避策があります。

  1. クライアントがこの状況を見た場合、問題のあるディレクトリに一時ファイルを作成します - このファイルが魔法のように表示された後。
  2. SMB 2.0 を無効にします: http://www.petri.co.il/how-to-disable-smb-2-on-windows-vista-or-server-2008.htm

誰かが同様の問題を発見したことがあり、なぜそれが発生するのか、どのように「正しく修正」するのかを説明できますか?

ありがとう

4

5 に答える 5

41

私も同様の問題を経験していましたが、最終的にこの問題の原因を見つけました。特定の問題は、SMB2クライアントリダイレクタキャッシュコンポーネントの1つであるSMB2ディレクトリキャッシュです。

これは、クライアントによって実行された最近のディレクトリ列挙のキャッシュです。クライアントアプリケーションによって行われた後続の列挙要求、およびディレクトリ内のファイルのメタデータクエリは、キャッシュから満たすことができます。また、クライアントはディレクトリキャッシュを使用してディレクトリ内のファイルの有無を判断し、その情報を使用して、サーバー上に存在しないことがわかっているファイルをクライアントが繰り返し開こうとするのを防ぎます。このキャッシュは、サーバー上のファイルのセットにアクセスする複数のコンピューターで実行されている分散アプリケーションに影響を与える可能性があります。アプリケーションは、帯域外メカニズムを使用して、サーバー上のファイルの変更/追加/削除について相互に通知します。

この素晴らしい小さなキャッシュのデフォルト値は10秒で、これはあなたが見ている振る舞いを生み出しています。コードがそのディレクトリ/ファイルについてシステムに問い合わせると、キャッシュされた結果(10秒前)が取得されるため、ファイルが存在しないことが示されます。HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Lanmanworkstation\Parameters\DirectoryCacheLifetime(DWORD)をの値に設定0すると、キャッシュが無効になり、ファイルが存在しないという問題が解決されます。驚いたことに、この変更ではクライアントマシンを再起動する必要はありません。これにより、SMB2を有効に保つこともできます。これは、SMB1を強制するよりも多くの理由で優れているはずです。

さらに、問題の共有がWindowsエクスプローラーで開かれている場合、キャッシュは使用されません。キャッシュを開くと、ライブビューを継続するために、キャッシュをバイパスするようにシステムに指示されます。ただし、コードを介して共有内の何かを変更することはできません。

この問題全体はWindows2008R2 / 7以降で修正されていると思いますが、完全に確認することはできません。これは、最新バージョンのWindowsではまだ問題です。詳細については、以下のコメントを参照してください。

于 2012-03-29T23:35:25.783 に答える
4

1ヶ月経ったのに返事が来ない…

Disable SMB 2.0そのため、" " ソリューションにとどまりました。少なくともそれは機能します。

http://www.petri.co.il/how-to-disable-smb-2-on-windows-vista-or-server-2008.htm

于 2011-03-31T18:01:50.910 に答える
3

$NOCSC$他の人が示唆したように、SMB を無効にしたり、レジストリ キーを介してキャッシュしたりする代わりに、magic suffix を使用できます。これにより、すべての Windows 設定をそのままにしておくことができますが、同時にファイルはキャッシュされません。

質問の具体例は次のとおりです。 \\beta$NOCSC$\share\bug\1.txt

詳細が必要な場合は、このリンクを確認してください。

http://blog.wisefaq.com/2016/01/26/nocscno-client-side-caching/

于 2016-12-09T10:08:41.700 に答える
2

これを回避する最も簡単な方法は (OP で提案されているように)、ファイルが表示されると予想されるフォルダーに一時ファイルまたはサブフォルダーを作成し、すぐに削除することです。これにより、変更が表示されるようになります。

FileSystemWatcher何もしない場合でも、フォルダーに があると役立つことに気付きました。

于 2016-02-02T16:02:55.163 に答える