共用方式為


Windows 卸載數據傳輸

ODX(卸載數據傳輸)是一項功能,用於加速伺服器的複製和移動操作。 此功能可從 Windows Server 2012 開始提供,且支援 NTFS 磁碟區。 此頁面從檔案系統和迷你過濾器的角度描述 ODX。 如需與儲存裝置相關的資訊,請參閱 Windows 儲存裝置卸載資料傳輸

在電腦或同一部計算機之間傳輸數據是常見的檔案系統活動。 從功能的觀點來看,使用標準 ReadFileWriteFile 函式可正常運作,但它牽涉到系統所有層級的繁重數據移動,並可能透過網路移動。 這種複雜性可能會影響傳輸所涉及的系統可用性,以及連接系統的網路。 許多記憶體子系統所提供的進階功能,可提供更有效率的方式來執行數據移動的繁重工作。

應用程式可以利用這些功能,協助將數據移動的處理過程交由儲存子系統處理。 檔系統篩選通常可藉由攔截對磁碟區的讀取和寫入要求來監視這些動作。 篩選器需採取更多措施,才能識別 ODX。

一般數據傳輸

現今在應用程式案例中移動數據會比較簡單。 它牽涉到將數據讀取到本機記憶體,然後將它寫回新的位置。 下圖說明此案例。

顯示一般數據傳輸的圖表。

此案例牽涉到在兩部不同文件伺服器上的兩個位置之間複製檔案,每個位置都有透過智慧型存儲設備陣列 (ISA) 公開的專屬虛擬磁碟。 起始系統必須先將數據從來源虛擬磁碟讀取到本機緩衝區。 然後,它會封裝資料,並透過某些傳輸和通訊協定(例如SMB超過1 GbE)傳輸到第二個系統。 第二個系統接著會接收數據,並將它輸出到本機緩衝區。 然後,目標系統會將數據寫入目的地虛擬磁碟。 此案例描述一般的數據傳輸讀取/寫入方法,每天由許多不同的應用程式執行多次。

雖然標準的讀取和寫入在大多數情況下運作良好,但要複製的數據可能位於同一智慧型儲存陣列所管理的虛擬磁碟上。 這種情況表示數據會移出陣列、伺服器、透過網路傳輸、移至另一部伺服器,然後再次回到相同的陣列。 在伺服器內部和跨網路傳輸移動數據的行為,可能會大幅影響這些系統的可用性。 此外,數據移動的輸送量受限於網路的輸送量和可用性。

卸載資料傳輸 (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. 執行卸除讀取/寫入時發生的任何錯誤,都會導致複製引擎回復到傳統的讀取/寫入程式代碼路徑。 此回退將從卸載程式路徑結束之處開始(在此處讀取或寫入已被截斷)。 複製引擎會更新相同的每個進程快取,因此如果下列任一條件成立,就不會嘗試卸除這些磁碟區。 此每個處理程序的快取會定期重設。
  • 失敗表示目的地磁碟區不支援卸除。
  • 來源磁碟區無法連線到目的地磁碟區。

下列功能支援 ODX:

  • CopyFile
  • CopyFileEx
  • MoveFile
  • MoveFileEx
  • CopyFile2

下列函式不支援 ODX:

  • CopyFileTransacted
  • MoveFileTransacted

支援的卸載資料傳輸場景

Hyper-V 儲存堆棧和 Windows SMB 檔案伺服器中會提供卸載作業的支援。 當實體儲存設備支援 ODX 作業時,使用者可以從虛擬機器或實體機器對位於 VHD 或遠端檔案共用上的檔案發出FSCTL_OFFLOAD_READFSCTL_OFFLOAD_WRITE。 下圖說明 ODX 最基本的支援來源和目的地目標。

顯示卸除數據傳輸場景的圖表。

檔案系統篩選加入模型和對應用程式的影響

從 Windows 8 開始,篩選管理程式允許篩選條件將卸載能力指定為支援的特性。 附加至磁碟區的文件系統篩選器可以共同判斷是否支援特定卸載作業。 如果不支援,作業會失敗,並出現適當的錯誤碼。

篩選器必須表明其支援FSCTL_OFFLOAD_READFSCTL_OFFLOAD_WRITE,並透過名為SupportedFeatures的登錄DWORD值來實現,此值位於登錄中的驅動程式服務定義,位址為HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\filter driver name\。 這個值包含位元欄位,這些位元決定啟用哪些功能,並且應該在過濾器安裝期間設定。

目前,定義的位元為:

旗標 意義
SUPPORTED_FS_FEATURES_OFFLOAD_READ 0x00000001 篩選支援FSCTL_OFFLOAD_READ
支援的 FS 功能:卸載寫入 0x00000002 篩選支援FSCTL_OFFLOAD_WRITE

可以根據 HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\FileSystem\FilterSupportedFeaturesMode 登錄機碼中的值來啟用或禁用篩選自選模式,該機碼有以下值:

FilterSupportedFeaturesMode 值 意義
0 (預設值) 執行一般同意加入處理。
1 絕對不要加入(相當於在所有附加的篩選條件上將 SupportedFeatures 設定為 0)

測試

若要檢查篩選器支援的堆疊功能,請使用 fltmc 公用程式。 以提升許可權的使用者身分執行 fltmc instances –v [volume]: 並檢查 SprtFtrs 欄:

  • 如果 SprtFtrs 值是0x00,則表示篩選器會封鎖此磁碟區上的卸載功能。 如果 SprtFtrs 設定為 0x03,則支援兩種卸載作業。

檢查 IRP 處理過程中的功能支持

在 IRP 處理中,FsRtlGetSupportedFeatures 例行程序會擷取附加至指定磁碟區堆棧的所有篩選器的 匯總SupportedFeatures 狀態。 I/O 管理員和 SRV (SMB) 等元件會呼叫此例程,以驗證 堆疊上所有篩選條件的 SupportedFeatures 狀態。 自行實作卸載 IRP 的元件應該呼叫此函式,以驗證該操作的選擇性支援。

篩選驅動程序的考慮

ODX 是在資料中心內傳輸數據的一種方式。 由於核心複製引擎中卸載邏輯的整合,許多應用程式默認具備執行卸載數據移動的能力,不需明確選擇加入。 因此,篩選開發人員必須瞭解這些作業如何影響篩選。 不完全了解這些作業或未評估數據流的變更,可能會導致數據可能變得不一致或損毀的情況。 以下是篩選開發人員在卸載時需要注意的一組行動事項摘要清單:

  • 瞭解此數據流、對篩選器的影響,以及篩選器支持這些卸載作業的能力。
  • 更新您的篩選工具,為 HKLM\System\CurrentControlSet\Services\[filter] 子機碼的 SupportedFeatures 新增一個 REG_DWORD 數值。 將它初始化以指定卸除功能。
  • 對於想要在卸載作業上採取行動的篩選器,請將註冊更新為 IRP_MJ_FILE_SYSTEM_CONTROL 來處理 FSCTL_OFFLOAD_READFSCTL_OFFLOAD_WRITE
  • 對於需要封鎖卸載程序的篩選器,請在篩選器內傳回狀態代碼 STATUS_NOT_SUPPORTED。 請勿依賴登錄值來強制執行封鎖卸除作業,因為終端使用者可以變更作業。 篩選條件應明確允許或不允許卸除作業。

複製令牌

使用卸載作業時,I/O 堆疊不會看到檔案數據。 相反地,檔案數據被視為 512 位元組的邏輯代理標記。 此代幣為:

  • 儲存子系統生成的特定於廠商格式的不透明且唯一的字串。
  • 表示數據模式的已知型別(例如邏輯上相當於零的數據範圍)。

修改 Proxy 令牌的數據會導致令牌失效,或讓記憶體子系統透過某些廠商特定的方式保存原始數據,例如透過快照集機制。 後續針對檔案中指定範圍的讀取要求將導致生成獨特的標記。

有一個標記類別代表妥善定義的數據模式。 最常見的已知令牌是零令牌,相當於零。 當令牌定義為已知令牌時,STORAGE_OFFLOAD_TOKEN 結構中的 TokenType 成員會設定為 STORAGE_OFFLOAD_TOKEN_TYPE_WELL_KNOWN。 設定此欄位時,WellKnownPattern 成員會決定令牌的數據模式。

  • 當 WellKnownPattern 字段設定為 STORAGE_OFFLOAD_PATTERN_ZERO 或 STORAGE_OFFLOAD_PATTERN_ZERO_WITH_PROTECTION_INFORMATION 時,表示 "Zero Token"。 當由FSCTL_OFFLOAD_READ作業傳回此令牌時,表示在所需檔案範圍中包含的數據在邏輯上等同於零。 當這個令牌提供給 FSCTL_OFFLOAD_WRITE 作業時,表示要寫入的檔案所需範圍應該以邏輯方式為零。
  • 除了零令牌以外,目前沒有其他已知的令牌模式。 不建議用戶定義自己的已知令牌模式。

截斷

Windows 與通訊的基礎記憶體子系統可以處理卸載作業中所需的較少數據。 此條件稱為截斷。 透過卸除讀取,傳回的令牌代表小於所要求數據的範圍。 FSCTL_OFFLOAD_READ_OUTPUT 結構中的 TransferLength 成員用來表示此值,這是要讀取之檔案範圍的開頭位元組計數。 針對卸載寫入,截斷表示寫入的資料比預期或計畫的要少。 FSCTL_OFFLOAD_WRITE_OUTPUT 結構中的 LengthWritten 成員表示這個值,這是要寫入之檔案範圍的開頭位元組計數。 在命令處理中出現的錯誤或堆疊範圍過大時的限制都會導致截斷。

NTFS 截斷要卸載讀取或寫入的範圍有兩種情況:

  1. 如果 VDL 在檔案結尾之前,複製範圍會截斷為有效數據長度 (VDL)。 此動作假設 VDL 會對齊邏輯扇區界限,否則請參閱案例。

    圖表顯示 VDL 發生在 EOF 之前。

    在執行FSCTL_OFFLOAD_READ操作期間,FSCTL_OFFLOAD_READ_OUTPUT結構中會設定旗標OFFLOAD_READ_FLAG_ALL_ZERO_BEYOND_CURRENT_RANGE,指出檔案的其餘部分為零,並將TransferLength成員截斷至VDL。

  2. 類似於案例 1,但是當 VDL 與邏輯扇區界限不一致時,NTFS 會將所需的範圍截斷為下一個邏輯扇區界限。

    顯示 VDL 與扇區界限不對齊的圖表。

限制

  • 只有NTFS磁碟區支援卸除作業。
  • 如果下列條件都成立,則透過遠端檔案伺服器支援卸載作業:
    • 遠端共用是NTFS磁碟區。
    • 伺服器正在執行 Windows Server 2012 或更新版本(假設遠端堆疊也支援卸載作業)。
  • NTFS 不支援對使用 Bitlocker 或 NTFS 加密(EFS)加密的檔案、已去重複的檔案、壓縮檔案、常駐檔案、稀疏檔案或參與 TxF 交易的檔案執行的卸載 FSCTL。
  • NTFS 不支援卸除在 volsnap 快照集內檔案上執行的 FSCTL。
  • 如果下列其中一個條件成立,NTFS 會使卸載 FSCTL 失敗。 這種方法遵循與不使用快取的 IO 相同的語義。
    • 所需的檔案範圍未對齊來源裝置上的邏輯扇區大小。
    • 所需的檔案範圍未對齊目的地裝置上的邏輯扇區大小。
  • 目的地檔案必須先預先配置 (SetEndOfFile,而不是 SetAllocation),才能FSCTL_OFFLOAD_WRITE
  • 當 NTFS 處理卸載讀取和寫入操作時,它會先呼叫 CcCoherencyFlushAndPurgeCache,以提交系統快取中任何已修改的數據。 此動作與未快取 IO 的語意相同。