Windows 卸除數據傳輸
ODX(卸除數據傳輸)是加速伺服器複製和移動作業的功能。 此功能可從 Windows Server 2012 開始提供,且支援 NTFS 磁碟區。 此頁面描述檔系統和小型篩選檢視方塊中的 ODX。 如需與儲存設備相關的資訊,請參閱 Windows 記憶體卸除數據傳輸。
在電腦或同一部計算機之間傳輸數據是常見的檔案系統活動。 從功能的觀點來看,使用標準 ReadFile 和 WriteFile 函式可正常運作,但它牽涉到系統所有層級的繁重數據移動,並可能透過網路移動。 這種複雜性可能會影響傳輸所涉及的系統可用性,以及連接系統的網路。 許多記憶體子系統所提供的進階功能,可提供更有效率的方式來執行數據移動的繁重工作。
應用程式可以利用這些功能,協助卸除數據移動至記憶體子系統的程式。 檔系統篩選通常可藉由攔截對磁碟區的讀取和寫入要求來監視這些動作。 篩選需要執行更多動作,才能知道 ODX。
一般數據傳輸
現今在應用程式案例中移動數據會比較簡單。 它牽涉到將數據讀取到本機記憶體,然後將它寫回新的位置。 下圖說明此案例。
此案例牽涉到在兩部不同文件伺服器上的兩個位置之間複製檔案,每個位置都有透過智慧型存儲設備陣列 (ISA) 公開的專屬虛擬磁碟。 起始系統必須先將數據從來源虛擬磁碟讀取到本機緩衝區。 然後,它會封裝資料,並透過某些傳輸和通訊協定(例如SMB超過1 GbE)傳輸到第二個系統。 第二個系統接著會接收數據,並將它輸出到本機緩衝區。 然後,目標系統會將數據寫入目的地虛擬磁碟。 此案例描述一般的數據傳輸讀取/寫入方法,每天由許多不同的應用程式執行多次。
雖然標準讀取和寫入在大部分情況下運作良好,但想要複製的數據可能位於相同智慧型手機記憶體陣列所管理的虛擬磁碟上。 這種情況表示數據會移出陣列、伺服器、透過網路傳輸、移至另一部伺服器,然後再次回到相同的陣列。 在伺服器內和跨網路傳輸行動數據的行為,可能會大幅影響這些系統的可用性。 此外,數據移動的輸送量受限於網路的輸送量和可用性。
卸載資料傳輸 (ODX)
卸除數據傳輸
Windows 8 中引進了兩個 FSCTL,有助於卸除數據傳輸的方法。 此卸除會將位移動的負擔從伺服器轉移到儲存子系統內以智慧方式發生的位移動。 可視化命令語意的最佳方式是將其視為類似未壓縮的讀取和未壓縮的寫入。
-
此控件要求會取得檔案內要讀取的位移,以及FSCTL_OFFLOAD_READ_INPUT結構中所需的長度。 如果支援,裝載檔案的記憶體子系統會收到相關聯的卸除讀取記憶體命令。 然後,它會產生令牌,這是在卸除讀取命令時要讀取之數據的邏輯表示法。 這個令牌字串會傳回給FSCTL_OFFLOAD_READ_OUTPUT 結構中的呼叫端。
-
此控制要求會接受要寫入之檔案內的位移、寫入所需的長度,以及要寫入之數據的邏輯表示法的標記。 如果支援,裝載要寫入之檔案的記憶體子系統會收到相關聯的卸除寫入記憶體命令。 它會先嘗試辨識指定的令牌,然後盡可能執行寫入作業。 寫入作業會在 Windows 底下完成,因此檔案系統和記憶體堆疊上的元件不會看到數據移動。 數據移動完成後,寫入的位元組數目會傳回給呼叫端。
與第一個圖表類似,下圖顯示兩部不同伺服器上的兩個虛擬磁碟之間的簡單檔案複本。
不過,我們不會執行一般讀取和寫入,而是將大量位移動卸除至儲存數位。 第一個系統會發出卸除讀取作業,要求陣列產生令牌,代表要在第一個虛擬磁碟區域內讀取之數據的時間點檢視。 第一個系統接著會將令牌傳輸至第二個系統,接著會使用令牌向第二個虛擬磁碟發出卸除寫入作業。 接著,陣列會解譯令牌,並嘗試在虛擬磁碟之間執行數據移動。 實際的數據傳輸會在智慧型手機記憶體數位內發生,而不是發生在兩部主機之間。 此設計可大幅改善兩個系統的可用性,同時幾乎消除系統之間的網路流量。
與複製引擎整合
Windows 中的核心複製引擎會由 CopyFile 和相關函式使用。 從 Windows 8 開始,複製引擎會以透明方式嘗試在傳統複製檔案程式代碼路徑之前使用 ODX。 大部分的應用程式、公用程式和殼層都會使用複製 API。 根據預設,這些呼叫端幾乎不需要修改程式碼或使用者介入,就能使用ODX功能。
下列步驟摘要說明複製引擎如何嘗試 ODX:
- 複製引擎會在來源檔案上發出 FSCTL_OFFLOAD_READ ,以取得讀取令牌。
- 如果擷取讀取令牌失敗,複製引擎會回復為傳統的讀取和寫入(傳統複製檔案程式代碼路徑)。 如果失敗指出來源磁碟區不支援卸除,複製引擎也會在個別進程快取中標記磁碟區。 複製引擎不會再嘗試針對每個進程快取中的磁碟區卸除。
- 如果成功擷取令牌,複製引擎會嘗試在大型區塊中發出 目標檔案上的FSCTL_OFFLOAD_WRITE 命令,直到令牌以邏輯方式表示的所有數據都會卸除。
- 執行卸除讀取/寫入時發生的任何錯誤,都會導致複製引擎回復到傳統的讀取/寫入程式代碼路徑。 此後援會從卸除程式代碼路徑結束的位置開始(其中已截斷讀取或寫入)。 複製引擎會更新相同的每個進程快取,因此如果下列任一條件成立,就不會嘗試卸除這些磁碟區。 此個別進程快取會定期重設。
- 失敗表示目的地磁碟區不支援卸除。
- 來源磁碟區無法連線到目的地磁碟區。
下列函式支援 ODX:
- CopyFile
- CopyFileEx
- MoveFile
- MoveFileEx
- CopyFile2
下列函式不支援 ODX:
- CopyFileTransacted
- MoveFileTransacted
支援的卸除數據傳輸案例
Hyper-V 儲存堆棧和 Windows SMB 檔案伺服器中會提供卸載作業的支援。 支援實體記憶體支援 ODX 作業的位置,呼叫者可以從虛擬機內部或實體硬體,對位於 VHD 或遠端檔案共用上的檔案發出FSCTL_OFFLOAD_READ和FSCTL_OFFLOAD_WRITE。 下圖說明 ODX 最基本的支援來源和目的地目標。
檔案系統篩選加入模型和對應用程式的影響
從 Windows 8 開始,篩選管理員允許篩選條件將卸除功能指定為支援的功能。 附加至磁碟區的文件系統篩選器可以共同判斷是否支援特定卸載作業。 如果不支援,作業會失敗,並出現適當的錯誤碼。
篩選必須指出它支援FSCTL_OFFLOAD_READ FSCTL_OFFLOAD_WRITE,並透過名為 SupportedFeatures 的登錄 DWORD 值,位於登錄中的驅動程式服務定義HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\filter 驅動程式名稱\。 這個值包含位欄位,其中位會決定加入宣告哪些功能,而且應該在篩選安裝期間設定。
目前,定義的位為:
旗標 | 意義 |
---|---|
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 狀態。 I/O 管理員和 SRV (SMB) 等元件會呼叫此例程,以驗證 堆疊上所有篩選條件的 SupportedFeatures 狀態。 捲動自己卸除 IRP 的元件應該呼叫此函式,以驗證該作業的加入支援。
篩選驅動程序的考慮
ODX 是行動資料中心內數據的方式。 由於核心複製引擎中的卸除邏輯整合,許多應用程式默認能夠執行卸除的數據移動,而不需要明確選擇加入。 因此,篩選開發人員必須瞭解這些作業如何影響篩選。 不完全了解這些作業或未評估數據流的變更,可能會導致數據可能變得不一致或損毀的情況。 下列清單摘要說明一組動作專案,讓篩選開發人員記下卸除:
- 瞭解此數據流、對篩選的影響,以及篩選條件支持這些卸載作業的能力。
- 更新篩選安裝程式,將 SupportedFeatures 的REG_DWORD值新增至 HKLM\System\CurrentControlSet\Services\[filter] 子機碼。 將它初始化以指定卸除功能。
- 對於想要在卸除作業上採取行動的篩選,請將註冊更新為 IRP_MJ_FILE_SYSTEM_CONTROL 來處理FSCTL_OFFLOAD_READ和FSCTL_OFFLOAD_WRITE。
- 對於需要封鎖卸除作業的篩選,請從篩選內傳回狀態代碼STATUS_NOT_SUPPORTED。 請勿依賴登錄值來強制執行封鎖卸除作業,因為終端使用者可以變更作業。 篩選條件應明確允許或不允許卸除作業。
複製令牌
使用卸載作業時,I/O 堆疊不會看到檔案數據。 相反地,檔案數據會被視為數據邏輯 Proxy 的 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時,表示零令牌。 當FSCTL_OFFLOAD_READ作業傳回此令牌時,表示所需檔案範圍中包含的數據在邏輯上相當於零。 當這個令牌提供給 FSCTL_OFFLOAD_WRITE 作業時,表示要寫入的檔案所需範圍應該以邏輯方式為零。
- 除了零令牌以外,目前沒有其他已知的令牌模式。 不建議用戶定義自己的已知令牌模式。
截斷
Windows 與通訊的基礎記憶體子系統可以處理卸載作業中所需的較少數據。 此條件稱為截斷。 透過卸除讀取,傳回的令牌代表小於所要求數據的範圍。 FSCTL_OFFLOAD_READ_OUTPUT 結構中的 TransferLength 成員用來表示此值,這是要讀取之檔案範圍的開頭位元組計數。 針對卸除寫入,截斷表示寫入的數據比預期少。 FSCTL_OFFLOAD_WRITE_OUTPUT 結構中的 LengthWritten 成員表示這個值,這是要寫入之檔案範圍的開頭位元組計數。 命令處理中的錯誤,或堆疊中大型範圍的限制,會導致截斷。
NTFS 截斷要卸除讀取或寫入的範圍有兩種情況:
如果 VDL 在檔案結尾之前,複製範圍會截斷為有效數據長度 (VDL)。 此動作假設 VDL 會對齊邏輯扇區界限,否則請參閱案例。
在FSCTL_OFFLOAD_READ作業期間,旗標OFFLOAD_READ_FLAG_ALL_ZERO_BEYOND_CURRENT_RANGE是在 FSCTL_OFFLOAD_READ_OUTPUT 結構中設定,指出檔案的其餘部分包含零,且 TransferLength 成員會截斷為 VDL。
類似於案例 1,但是當 VDL 與邏輯扇區界限不一致時,NTFS 會將所需的範圍截斷為下一個邏輯扇區界限。
限制
- 只有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的語意相同。