Файлообменник Windows: почему иногда вновь созданные файлы не видны какое-то время?

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

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

Спасибо


person Roman    schedule 01.03.2011    source источник
comment
Вы смотрели на трассировку сети, чтобы увидеть, что происходит?   -  person selbie    schedule 02.03.2011
comment
Нет, к сожалению, я не смотрел трассировку сети   -  person Roman    schedule 02.03.2011
comment
Я не думаю, что трассировка сети поможет. Похоже, это проблема кэширования на стороне сервера. У нас точно такая же проблема при переходе с Windows 2003 на 2012R2. Кажется, что SMB показывает файлы для сервера, который их создал, но затем показывает, что файлы еще не существуют для других серверов, которые запрашивают их. Это очень плохо.   -  person Brain2000    schedule 04.01.2015


Ответы (5)


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

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

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

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

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

person Justin Michael    schedule 29.03.2012
comment
Это не исправлено в 2008R2 и выше. Фактически, это все еще проблема в Windows 2012R2. - person Brain2000; 04.01.2015
comment
Кстати, это решение устранило проблему для машин, обращающихся к Windows 2012R2 через общие ресурсы SMB. Спасибо, Джастин, ваша информация здесь была чрезвычайно ценной! - person Brain2000; 04.01.2015
comment
@ Brain2000 Спасибо, что подтвердили, что это все еще проблема в более поздних версиях. - person Justin Michael; 05.01.2015
comment
Я все еще считаю, что это проблема в Windows 8.1. - person Holf; 30.06.2015
comment
Да, все еще проблема в 8.1 - person Vladislav Rastrusny; 11.01.2016
comment
Недавно возникла эта проблема в Windows 10. Это исправило ее для меня. - person Edd; 05.06.2017
comment
Красивый! Теперь все, что мне нужно, это 2 файла с расширением .reg, один для включения кэширования, а другой для его отключения. Спасибо чувак! Спас мой рассудок! - person dkellner; 11.03.2019

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

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

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

person Roman    schedule 31.03.2011


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

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

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

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

person zmechanic    schedule 09.12.2016
comment
Однако похоже, что Win Server 2012 R2 не понимает этого намека. - person satnhak; 22.03.2018

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

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

person Michel de Ruiter    schedule 02.02.2016
comment
Как ни смешно это звучит, это был самый простой ответ для меня (я просматривал как пользователь, а не автоматизировал) - person Basic; 08.03.2016