私たちは私たちを狂わせるような非常に奇妙な問題に直面しました。 File Share PCで新しく作成されたファイルが、しばらくの間「存在しない」場合がありました。問題を再現するには、少なくとも2台のコンピューターが必要です(alpha
およびbeta
)。 beta
PC(_\\beta\share\bug
_)にファイル共有を作成し、alpha
PCからこのPowerShellスクリプトを実行します。
_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
_でバグが見つかりました
Windowsエクスプローラーでalpha
PCのディレクトリコンテンツをリアルタイムで監視できないことに注意してください。このディレクトリをエクスプローラーで開くとバグが発生しないためです。バグを再現する前に、このようなウィンドウをすべて閉じてください。各スクリプトの再起動後、既に作成されたすべてのファイルを共有から手動で削除する必要があります(スクリプトはかなり愚かで常に0.txtから始まるため)。
現在、この問題には2つの回避策があります。
誰かがこれまでに同様の問題を発見したことがあり、それが発生する理由とそれを「正しく修正する」方法を説明できますか?
ありがとう
同様の問題が発生し、最終的にこの問題の原因を発見しました。特定の問題は、SMB2ディレクトリキャッシュです。これは、 SMB2クライアントリダイレクターキャッシュコンポーネントの1つです 。
これは、クライアントによって実行された最近のディレクトリ列挙のキャッシュです。クライアントアプリケーションによって行われた後続の列挙要求、およびディレクトリ内のファイルのメタデータクエリは、キャッシュから実行できます。また、クライアントはディレクトリキャッシュを使用して、ディレクトリ内のファイルの有無を判別し、その情報を使用して、サーバー上に存在しないことがわかっているファイルをクライアントが繰り返し開こうとしないようにします。このキャッシュは、サーバー上のファイルセットにアクセスする複数のコンピューターで実行されている分散アプリケーションに影響を与える可能性があります。アプリケーションは、帯域外メカニズムを使用して、サーバー上のファイルの変更/追加/削除について互いに通知します。
この素晴らしい小さなキャッシュのデフォルト値は10秒です。これにより、見ている動作が生成されます。コードがシステムにそのディレクトリ/ファイルについて尋ねると、キャッシュされた結果(10秒前)を取得しているため、ファイルが存在しないことがわかります。 HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Lanmanworkstation\Parameters\DirectoryCacheLifetime
(DWORD)を0
の値に設定すると、キャッシュが無効になり、ファイルが存在しないという問題が解決されます。意外なことに、この変更ではクライアントマシンの再起動は必要ありません。これにより、SMB2を有効にしておくこともできます。これは、SMB1を強制するよりも、多くの理由で優れているはずです。
さらに、問題の共有がWindowsエクスプローラーで開かれている場合は、キャッシュを使用しないでください。開いていると、システムはキャッシュをバイパスしてライブビューを継続するように指示します。ただし、コードを介して共有内の何かを変更することはできません。
この問題全体はWindows 2008 R2/7以降で修正されたと思いますが、絶対に確認することはできません。 これは、最新バージョンのWindowsではまだ問題です。詳細については、以下のコメントを参照してください。
1か月が経過しましたが、回答がありません...
したがって、「Disable SMB 2.0
"ソリューション。少なくとも機能します。
http://www.petri.co.il/how-to-disable-smb-2-on-windows-Vista-or-server-2008.htm
SMBを無効にしたり、レジストリキーを介してキャッシュしたりする代わりに、魔法のサフィックス$NOCSC$
を使用できます。これにより、すべてのWindows設定をそのままにして、同時に時間ファイルはキャッシュされません。
これは質問固有の例です:\\beta$NOCSC$\share\bug\1.txt
詳細が必要な場合は、このリンクを確認してください。
http://blog.wisefaq.com/2016/01/26/nocscno-client-side-caching/
Windows 7 SP1には、修正プログラムが利用可能なバグもあります。
ユーザーがリモートフォルダーに追加したファイルは、Windows 7またはWindows Server 2008 R2を実行しているコンピューターのエクスプローラーに表示されません
これを回避する最も簡単な方法(OPで推奨)は、ファイルが表示されるはずのフォルダーに一時ファイルまたはサブフォルダーを作成し、すぐに削除することです。これにより、変更が可視化されます。
フォルダーにFileSystemWatcher
を含めると、何も実行しない場合でも役立つことに気付きました。