Общий доступ к файлам Windows: почему иногда вновь созданные файлы не отображаются в течение некоторого периода времени? - PullRequest
24 голосов
/ 01 марта 2011

Мы столкнулись с очень странной проблемой, которая сводила нас с ума.Иногда вновь созданные файлы на нашем ПК с совместным использованием файлов в течение некоторого периода времени отсутствовали.Чтобы воспроизвести проблему, у вас должно быть как минимум два компьютера, назовите их alpha и beta.Создайте общий файловый ресурс на beta ПК (\\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

Обратите внимание, что вы не можете просматривать содержимое каталога на alpha ПК в Windows 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

Кто-нибудь когда-либо имелобнаружил подобную проблему и может объяснить, почему она возникает и как ее «правильно исправить»?

Спасибо

Ответы [ 5 ]

39 голосов
/ 30 марта 2012

У меня была похожая проблема, и, в конце концов, я нашел причину этой проблемы.Конкретной проблемой является кэш каталога SMB2, который является одним из компонентов кэша перенаправителя клиента SMB2 :

Это кэш последних перечислений каталога, выполняемых клиентом.Последующие запросы на перечисление, сделанные клиентскими приложениями, а также запросы метаданных для файлов в каталоге могут быть выполнены из кэша.Клиент также использует кэш каталога для определения наличия или отсутствия файла в каталоге и использует эту информацию для предотвращения повторных попыток клиентов открыть файлы, о которых известно, что они не существуют на сервере.Этот кэш, вероятно, повлияет на распределенные приложения, работающие на нескольких компьютерах, которые получают доступ к набору файлов на сервере - где приложения используют механизм внешней сети, чтобы сигнализировать друг другу об изменении / добавлении / удалении файлов на сервере.

Значение по умолчанию для этого замечательного маленького кэша составляет 10 секунд, что вызывает поведение, которое вы видите.Когда ваш код запрашивает систему об этом каталоге / файле, он получает кэшированный результат, которому 10 секунд, поэтому он говорит, что файл не существует.Установка HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Lanmanworkstation\Parameters\DirectoryCacheLifetime (DWORD) в значение 0 отключит кэш и решит проблему с несуществующим файлом.Удивительно, но это изменение не требует перезагрузки клиентского компьютера!Это также позволит вам поддерживать SMB2 включенным, что должно быть лучше по ряду причин по сравнению с принудительным использованием SMB1.

Кроме того, кэш не используется, когда рассматриваемый общий ресурс открывается в проводнике Windows, посколькупри открытии он сообщает системе обойти кеш, чтобы поддерживать просмотр в реальном времени.Однако изменение чего-либо в общем ресурсе с помощью кода не помогает.

Я думаю, что вся эта проблема исправлена ​​в Windows 2008 R2 / 7 и более поздних версиях, но я не могу полностью подтвердить это. Этовсе еще проблема в современных версиях Windows.Подробности смотрите в комментариях ниже.

3 голосов
/ 09 декабря 2016

Вы можете использовать магический суффикс $NOCSC$ вместо отключения SMB или кэширования через ключи реестра, как предлагали некоторые другие. Это позволит вам оставить все настройки Windows без изменений, но в то же время файлы не будут кэшироваться.

Вот пример конкретного вопроса: \\beta$NOCSC$\share\bug\1.txt

Проверьте эту ссылку, если вы хотите получить более подробную информацию:

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

3 голосов
/ 17 февраля 2015
3 голосов
/ 31 марта 2011

Прошел месяц, а ответа нет ...

Итак, мы остановились на решении "Disable SMB 2.0". По крайней мере, это работает.

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

2 голосов
/ 02 февраля 2016

Самый простой способ обойти это (как предлагает ОП) - создать временный файл или подпапку в папке, в которой вы ожидаете появления файлов, и сразу же удалить ее.Это приводит к тому, что изменение становится видимым.

Мы заметили, что наличие FileSystemWatcher в папке также помогает, даже если оно ничего не делает.

...