Поделиться через


Передача данных с разгрузкой Windows

ODX (разгрузка передачи данных) — это функция, которая ускоряет операции копирования и перемещения сервера. Эта функция доступна начиная с Windows Server 2012 и поддерживается в томах NTFS. На этой странице описывается ODX с точки зрения файловой системы и минифильтра. Сведения, связанные с устройствами хранения, см. в разделе "Разгрузка данных хранилища Windows".

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

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

Типичные передачи данных

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

Схема, показывающая типичную передачу данных.

Этот сценарий включает копирование файла между двумя расположениями на двух разных файловых серверах, каждый из которых имеет собственный виртуальный диск, предоставляемый с помощью интеллектуального массива хранилища (ISA). Сначала инициируемая система должна считывать данные из исходного виртуального диска в локальный буфер. Затем он упаковает и передает данные через некоторые транспорт и протокол (например, SMB более 1 ГбE) во вторую систему. Затем вторая система получает данные и выводит его в локальный буфер. Затем целевая система записывает данные на целевой виртуальный диск. В этом сценарии описывается типичный метод передачи данных чтения и записи, который выполняется несколько раз различными приложениями каждый день.

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

Разгрузка передачи данных (ODX)

Разгрузка передачи данных

В Windows 8 появились два FSCTL, которые упрощают загрузку передачи данных. Это разгрузка сдвигает нагрузку на перемещение битов с серверов на битовое перемещение, которое происходит интеллектуально в подсистемах хранения. Лучший способ визуализировать семантику команды заключается в том, чтобы рассматривать их как аналогичные небуферируемой операции чтения и неуправляемой записи.

  • FSCTL_OFFLOAD_READ

    Этот запрос элемента управления принимает смещение в файле для чтения и требуемой длины в структуре FSCTL_OFFLOAD_READ_INPUT. Если поддерживается, подсистема хранения, в которой размещен файл, получает связанную команду разгрузки считывания хранилища. Затем он создает маркер, который является логическим представлением данных, предназначенных для чтения во время команды разгрузки чтения. Эта строка маркера возвращается вызывающей строке в структуре FSCTL_OFFLOAD_READ_OUTPUT.

  • FSCTL_OFFLOAD_WRITE

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

Как и на первой схеме, на следующей схеме показана простая копия файлов между двумя виртуальными дисками на двух разных серверах.

Схема, показывающая разгрузку передачи данных.

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

Интеграция с подсистемой копирования

Ядро обработчика копирования в Windows используется copyFile и связанными функциями. Начиная с Windows 8 подсистема копирования прозрачно пытается использовать ODX перед традиционным путем копирования кода файла. API копирования используются большинством приложений, служебных программ и оболочки. Эти вызывающие пользователи могут использовать возможности ODX по умолчанию с небольшим количеством изменений кода или вмешательства пользователя.

Ниже приведены инструкции по попытке обработчика копирования odX:

  1. Модуль копирования выдает FSCTL_OFFLOAD_READ в исходном файле для получения маркера чтения.
  2. Если произошел сбой при получении маркера чтения, подсистема копирования возвращается к традиционным чтениям и записи (традиционный путь к файлу копирования). Если сбой указывает, что исходный том не поддерживает разгрузку, подсистема копирования также помечает том в кэше каждого процесса. Подсистема копирования больше не пытается выгрузить тома в кэше каждого процесса.
  3. Если маркер был успешно получен, подсистема копирования пытается выдавать FSCTL_OFFLOAD_WRITE команды в целевом файле в больших блоках до тех пор, пока все данные, логически представленные маркером, не записываются.
  4. Любые ошибки при выполнении разгрузки чтения и записи приводят к тому, что модуль копирования возвращается к традиционному пути кода чтения и записи. Этот резервный вариант начинается с того, откуда закончился путь к коду разгрузки (где чтение или запись была усечена). Модуль копирования обновляет один и тот же кэш для каждого процесса, поэтому не пытается отключить нагрузку на эти тома, если одно из следующих условий имеет значение true. Этот кэш для каждого процесса периодически сбрасывается.
  • Сбой указывает, что целевой том не поддерживает разгрузку.
  • Исходный том не может достичь целевого тома.

Следующие функции поддерживают ODX:

  • CopyFile
  • CopyFileEx
  • MoveFile
  • MoveFileEx
  • CopyFile2

Следующие функции не поддерживают ODX.

  • CopyFileTransacted
  • MoveFileTransacted

Поддерживаемые сценарии передачи данных разгрузки

Поддержка операций разгрузки предоставляется в стеке хранилища Hyper-V и в файловом сервере Windows SMB. Где резервное физическое хранилище поддерживает операции ODX, вызывающие серверы могут выдавать FSCTL_OFFLOAD_READ и FSCTL_OFFLOAD_WRITE файлы, размещенные на виртуальных жестких дисках или на удаленных файловых ресурсах, будь то в виртуальной машине или на физическом оборудовании. На следующей схеме показаны самые основные поддерживаемые целевые объекты источника и назначения для ODX.

Схема, показывающая сценарии передачи данных с разгрузкой.

Модель фильтра файловой системы и влияние на приложения

Начиная с Windows 8 диспетчер фильтров позволяет фильтру указывать возможность разгрузки в качестве поддерживаемой функции. Фильтры файловой системы, подключенные к тому, могут коллективно определить, поддерживается ли определенная отключенная операция. Если она не поддерживается, операция завершается ошибкой с соответствующим кодом ошибки.

Фильтр должен указывать, что он поддерживает FSCTL_OFFLOAD_READ и FSCTL_OFFLOAD_WRITE через значение DWORD реестра с именем SupportedFeatures, расположенное в определении службы драйверов в реестре по адресу HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Filter Driver name\. Это значение содержит битовые поля, в которых биты определяют, какие функции выбираются и должны быть заданы во время установки фильтра.

В настоящее время определенные биты:

Флаг Значение
SUPPORTED_FS_FEATURES_OFFLOAD_READ 0x00000001 Фильтр поддерживает FSCTL_OFFLOAD_READ
SUPPORTED_FS_FEATURES_OFFLOAD_WRITE 0x00000002 Фильтр поддерживает FSCTL_OFFLOAD_WRITE

Модель фильтра может быть включена или отключена на основе значения, присутствующих в разделе реестра HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\FileSystem\FilterSupportedFeaturesMode, который имеет следующие значения:

Значение FilterSupportedFeaturesMode Значение
0 (по умолчанию) Выполняйте обычную обработку согласия.
1 Никогда не отказывайтесь (эквивалентно настройке supportedFeatures значение 0 для всех фильтров, подключенных)

Тестирование

Чтобы проверить поддерживаемые функции фильтра в стеке, используйте служебную программу fltmc. Запустите экземпляры fltmc –v [volume]: в качестве пользователя с повышенными привилегиями и проверьте столбец SprtFtrs :

  • Если значение SprtFtrs 0x00, это означает, что фильтр блокирует разгрузку на этом томе. Если sprtFtrs имеет значение 0x03, поддерживаются обе операции разгрузки.

Проверка поддержки функций в обработке IRP

В рамках обработки IRP подпрограмма FsRtlGetSupportedFeatures извлекает агрегированное состояние SupportedFeatures для всех фильтров, подключенных к заданному стеку томов. Такие компоненты, как диспетчер ввода-вывода и SRV (SMB), вызывают эту подпрограмму, чтобы проверить состояние SupportedFeatures для всех фильтров в стеке. Компоненты, которые свернуты собственные разгрузки IRPs, должны вызвать эту функцию, чтобы проверить поддержку этого действия.

Рекомендации по драйверам фильтров

ODX — это способ перемещения данных в центре обработки данных. Из-за интеграции логики разгрузки в ядре копирования многие приложения по умолчанию могут выполнять перемещение отключенных данных без явного согласия. В результате разработчикам фильтров необходимо понять, как эти операции влияют на фильтры. Не понимать эти операции полностью или не оценивать изменение потока данных может привести к сценариям, когда данные могут стать несогласованными или поврежденными. В следующем списке приведен набор элементов действий для разработчиков фильтров, которые следует заметить с разгрузкой:

  • Изучите этот поток данных, влияние на фильтр и возможность фильтра поддерживать эти отключенные операции.
  • Обновите установщик фильтра, чтобы добавить значение REG_DWORD для SupportedFeatures в подраздел HKLM\System\CurrentControlSet\Services\[filter]. Инициализировать его, чтобы указать функции разгрузки.
  • Для фильтров, которые хотят действовать при операциях разгрузки, обновите регистрацию, чтобы IRP_MJ_FILE_SYSTEM_CONTROL обрабатывать FSCTL_OFFLOAD_READ и FSCTL_OFFLOAD_WRITE.
  • Для фильтров, которые должны блокировать отключенные операции, верните код состояния STATUS_NOT_SUPPORTED из фильтра. Не используйте значение реестра для принудительного применения блокирующих операций разгрузки, так как конечные пользователи могут изменить его. Фильтр должен явно разрешать или запрещать операции разгрузки.

Копирование маркеров

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

  • Непрозрачная и уникальная строка формата, созданного подсистемой хранения для конкретного поставщика.
  • Известный тип, представляющий шаблон данных (например, диапазон данных, логически эквивалентный нулю).

Изменения данных маркера прокси-сервера приводят к недопустимости маркера или для подсистемы хранилища для сохранения исходных данных определенным поставщиком средств, таких как через механизм моментального снимка. Последующие запросы на чтение считывания в указанный диапазон в файле приводят к уникальным маркерам.

Существуют классы маркеров, представляющих шаблон данных, которые хорошо определены. Наиболее распространенный известный токен — нулевой маркер, эквивалентный нулю. Если маркер определен как известный токен, то для элемента TokenType в структуре STORAGE_OFFLOAD_TOKEN задано значение STORAGE_OFFLOAD_TOKEN_TYPE_WELL_KNOWN. Если это поле задано, член WellKnownPattern определяет, какой шаблон данных является маркером.

  • Если для поля WellKnownPattern задано значение STORAGE_OFFLOAD_PATTERN_ZERO или STORAGE_OFFLOAD_PATTERN_ZERO_WITH_PROTECTION_INFORMATION, он указывает нулевой маркер. Если этот маркер возвращается операцией FSCTL_OFFLOAD_READ , он указывает, что данные, содержащиеся в требуемом диапазоне файлов, логически эквивалентны нулю. Если этот маркер предоставляется операции FSCTL_OFFLOAD_WRITE , он указывает, что требуемый диапазон файла, на который необходимо записать, должен быть логически ноленем.
  • Кроме нулевого маркера, в настоящее время не определены другие известные шаблоны маркеров. Пользователям не рекомендуется определять собственные шаблоны известных маркеров.

Усечение

Базовая подсистема хранения, с которую Windows взаимодействует, может обрабатывать меньше данных, которые были нужны в операции разгрузки. Это условие называется усечением. При чтении разгрузки возвращенный маркер представляет диапазон данных меньше, чем запрошенные данные. Элемент TransferLength в структуре FSCTL_OFFLOAD_READ_OUTPUT используется для указания этого значения, которое является числом байтов с начала диапазона файла для чтения. Для записи разгрузки усечение указывает на то, что данные были записаны меньше, чем было необходимо. Элемент LengthWritten в структуре FSCTL_OFFLOAD_WRITE_OUTPUT указывает это значение, которое является числом байтов в начале диапазона файла, который требуется записать. Ошибки в обработке команд или ограничениях в стеке для больших диапазонов приводят к усечению.

Существует два сценария, в которых NTFS усечен диапазон для разгрузки для чтения или записи:

  1. Диапазон копирования усечен до допустимой длины данных (VDL), если VDL находится до конца файла (EOF). Это действие предполагает, что VDL соответствует границе логического сектора, в противном случае см. сценарий.

    Схема, показывающая VDL перед EOF.

    Во время операции FSCTL_OFFLOAD_READ флаг OFFLOAD_READ_FLAG_ALL_ZERO_BEYOND_CURRENT_RANGE задается в структуре FSCTL_OFFLOAD_READ_OUTPUT, указывающей, что остальная часть файла содержит нули, а элемент TransferLength усечен в VDL.

  2. Аналогично сценарию 1, но если VDL не соответствует границе логического сектора, NTFS усечение нужного диапазона до следующей границы логического сектора.

    Схема, показывающая несоответствие VDL с границой сектора.

Ограничения

  • Операции разгрузки поддерживаются только в томах NTFS.
  • Операции разгрузки поддерживаются через удаленные файловые серверы, если оба условия имеют значение true:
    • Удаленный общий ресурс — это том NTFS.
    • Сервер работает под управлением Windows Server 2012 или более поздних версий (если удаленный стек также поддерживает операции разгрузки).
  • NTFS не поддерживает разгрузку FSCTLs, выполняемых в файлах, зашифрованных с помощью шифрования Bitlocker или NTFS (EFS), дедупликированных файлов, сжатых файлов, резидентных файлов, разреженных файлов или файлов, участвующих в транзакциях TxF.
  • NTFS не поддерживает разгрузку FSCTLs, выполняемую в файлах в моментальном снимке volsnap.
  • NTFS завершает сбой разгрузки FSCTL, если одно из следующих условий имеет значение true. Этот подход соответствует той же семантике, что и некичированные операции ввода-вывода.
    • Требуемый диапазон файлов не соответствует размеру логического сектора на исходном устройстве.
    • Требуемый диапазон файлов не соответствует размеру логического сектора на целевом устройстве.
  • Целевой файл должен быть предварительно расположен (SetEndOfFile и не SetAllocation) перед FSCTL_OFFLOAD_WRITE.
  • Когда NTFS обрабатывает разгрузку операций чтения и записи, сначала вызывает CcCoherencyFlushAndPurgeCache для фиксации любых измененных данных в системном кэше. Это действие совпадает с семантикой операций ввода-вывода без кэширования.