Linux

通過 ssh 複製大量文件

  • April 8, 2018

我通過 ssh 掛載遠端伺服器(使用 sshfs)。我想將大量文件從遠端伺服器複製到本地:

cp -rnv /mounted_path/source/* /local_path/destination

該命令執行不會覆蓋現有文件的遞歸複製。但複製過程相當緩慢。我注意到它沒有按順序複製文件。所以我的問題是:我可以通過打開多個終端並執行上面相同的命令來加快複製過程嗎?複製程序是否足夠聰明,不會覆蓋其他程序複製的文件?

……按照所述回答原始問題……

這裡有兩件事要討論。

使用 SSHFS

SSHFS 使用 SSH 協議的 SFTP“子系統”使遠端文件系統看起來好像是在本地掛載的。

這裡很關鍵的是要注意 SSHFS 將低級別的 系統呼叫翻譯成相對高級的 SFTP 命令,然後將這些命令翻譯成 SFTP 伺服器在伺服器上執行的系統呼叫,然後將它們的結果發送回客戶端並向後翻譯.

這個過程有幾個緩慢的來源:

  • 對文件的不同操作有不同的系統呼叫,它們按照客戶端發出的順序執行。比如說,客戶端stat(2)-s 一個文件的資訊,然後open(2)-s 那個文件,然後讀取它的數據——通過 read(2)連續執行幾個呼叫,然後最後close(2)-s 文件,所有這些系統呼叫都必須轉換為 SFTP 命令,發送到伺服器並在那里處理,並將結果發送回客戶端,翻譯回來。
  • 即使 SSHFS 似乎實現了某些巧妙的技巧,例如“預讀”(推測性地讀取比客戶端請求的數據更多的數據),但每個系統呼叫都會導致往返於伺服器並返回。也就是說,我們將數據發送到伺服器然後等待它響應然後處理它的響應。IIUC,SFTP 沒有實現“流水線”——一種我們在命令完成之前發送命令的操作模式,所以基本上是每個系統呼叫。雖然在技術上可以 在一定程度上進行此類處理,sshfs但似乎無法實現。

IOW,cp您的客戶端機器上的每個系統呼叫都會被轉換為對伺服器的請求,然後等待它響應,然後接收它的響應。

多個cp -n程序並行執行

是否可以使用多個cp -n程序並行複製文件的問題的答案取決於幾個考慮因素。

首先,如果它們都將在同一個SSHFS 掛載上執行,顯然不會有任何加速,因為多個發出的所有系統呼叫cp最終都會命中同一個 SFTP 客戶端連接,並且由於上述原因而被它序列化。

cp -n其次,在不同的SSHFS 掛載點上運​​行多個執行實例 可能是值得的——達到網路吞吐量和目標文件系統下的介質/媒體的 I/O 吞吐量提供的限制。在這種情況下,至關重要的是要理解,由於 SSHFS 不會在伺服器上使用任何鎖定,因此不同的實例cp -n必須在不同的目錄層次結構上執行——只是為了不踩到彼此的腳趾。

不同/更明智的方法

首先,通過管道傳輸由 或其他流歸檔器創建的數據流tarcpio對其進行遠端處理具有避免文件系統操作的所有往返行程的優點:本地歸檔器創建流的速度與源文件系統上的 I/O 吞吐量一樣快允許並以網路允許的速度發送;刪除歸檔器從流中提取數據並儘可能快地更新其本地文件系統。不涉及執行基本“命令”的往返行程:您只需盡可能快地執行此管道中最慢的 I/O 點允許的速度;根本不可能走得更快。

其次,另一個答案建議使用rsync,您拒絕了該建議,理由是

rsync 很慢,因為它必須對文件進行校驗和。

這是完全錯誤的。引用rsync手冊頁:

-c,--checksum

這改變了 rsync 檢查文件是否已更改並需要傳輸的方式。如果沒有這個選項,rsync 使用“快速檢查”(預設情況下)檢查每個文件的大小和最後修改時間是否在發送者和接收者之間匹配。此選項將其更改為比較每個具有匹配大小的文件的 128 位校驗和。

-I,--ignore-times

通常 rsync 會跳過任何已經相同大小且具有相同修改時間戳的文件。此選項關閉此“快速檢查”行為,從而更新所有文件。

--size-only

這修改了 rsync 用於查找需要傳輸的文件的“快速檢查”算法,將其從預設傳輸具有更改大小或更改最後修改時間的文件更改為僅查找大小已更改的文件。這在使用另一個可能無法準確保留時間戳的鏡像系統後開始使用 rsync 時很有用。

最後

--existing 跳過在接收器上創建新文件

--ignore-existing 跳過更新接收器上存在的文件

那是,

  • 預設情況下rsync不會散列文件的內容以查看文件是否已更改。
  • 您可以告訴它的行為與 完全相同cp -n,也就是說,如果文件僅存在於遠端,則跳過更新文件。

引用自:https://serverfault.com/questions/878161