Rsync

未更改的大目錄的更快 rsync

  • October 10, 2020

我們使用 rsync 來備份伺服器。

不幸的是,某些伺服器的網路速度很慢。

rsync 最多需要五分鐘才能檢測到大型目錄中沒有任何變化。這些巨大的目錄樹包含很多小文件(大約 80k 個文件)。

我猜 rsync 客戶端會為每個 80k 文件發送數據。

由於網路很慢,我想避免發送有關每個文件的 80k 次資訊。

有沒有辦法告訴 rsync 對子目錄樹進行雜湊和?

這樣,rsync 客戶端將只為一個巨大的目錄樹發送幾個字節。

更新

到目前為止,我的策略是使用rsync. 但如果不同的工具更適合這裡,我可以切換。兩者(伺服器和客戶端)都在我的控制之下。

更新2

一個目錄樹中有 80k 個文件。每個單個目錄的文件或子目錄不超過 2k

更新3

有關網路緩慢的詳細資訊:

time ssh einswp 'cd attachments/200 && ls -lLR' >/tmp/list
real    0m2.645s

tmp/list 文件大小:2MByte

time scp einswp:/tmp/list tmp/
real    0m2.821s

結論:scp速度一樣(不意外)

time scp einswp:tmp/100MB tmp/
real    1m24.049s

速度:1.2MB/秒

一些不相​​關的點:

80K是很多文件。

一個目錄中有 80,000 個文件?預設情況下,沒有作業系統或應用程序可以很好地處理這種情況。你只是碰巧注意到 rsync 的這個問題。

檢查您的 rsync 版本

現代 rsync 比過去更好地處理大型目錄。確保您使用的是最新版本。

即使是舊的 rsync 在高延遲連結上也能很好地處理大型目錄……但是 80k 文件並不大……它很大!

也就是說,rsync 的記憶體使用量與樹中的文件數量成正比。大型目錄佔用大量 RAM。緩慢可能是由於兩邊都缺少 RAM。在觀察記憶體使用情況的同時進行測試執行。Linux 使用任何剩餘的 RAM 作為磁碟記憶體,因此如果 RAM 不足,磁碟記憶體就會減少。如果您的 RAM 用完並且系統開始使用交換,性能將非常糟糕。

確保沒有使用 –checksum

--checksum(或-c)需要讀取每個文件的每個塊。您可能可以通過僅讀取修改時間(儲存在 inode 中)的預設行為來解決問題。

將作業分成小批量。

有一些像Gigasync這樣的項目將“通過使用 perl 遞歸目錄樹來減少工作量,建構小的文件列表以使用 rsync 傳輸。”

額外的目錄掃描將是一個很大的成本,但也許它會是一個淨贏。

作業系統預設值不適用於這種情況。

如果您使用所有預設設置的 Linux/FreeBSD/etc,那麼所有應用程序的性能都會很糟糕。預設值假定目錄較小,以免在超大記憶體上浪費 RAM。

調整文件系統以更好地處理大型目錄:大型文件夾會降低 IO 性能嗎?

查看“namei 記憶體”

BSD-like 作業系統有一個記憶體,可以加速查找一個名字到 inode(“namei”記憶體)。每個目錄都有一個 namei 記憶體。如果它太小,它是一個障礙而不是優化。由於 rsync 對每個文件執行 lstat(),因此 80k 文件中的每一個都訪問了 inode。這可能會破壞您的記憶體。研究如何調整系統上的文件目錄性能。

考慮不同的文件系統

XFS 旨在處理更大的目錄。請參閱文件系統單個目錄中的大量文件

也許5分鐘是你能做的最好的。

考慮計算正在讀取的磁碟塊數,併計算您期望硬體能夠以多快的速度讀取那麼多塊。

也許你的期望太高了。考慮必須讀取多少磁碟塊才能在沒有更改文件的情況下執行 rsync:每台伺服器都需要讀取目錄並為每個文件讀取一個 inode。讓我們假設沒有記憶體任何內容,因為 80k 文件可能已經耗盡了您的記憶體。假設為了保持數學簡單,它是 80k 塊。那是大約 40M 的數據,應該可以在幾秒鐘內讀取。但是,如果需要在每個塊之間進行磁碟尋軌,則可能需要更長的時間。

因此,您將需要讀取大約 80,000 個磁碟塊。你的硬碟能多快做到這一點?考慮到這是隨機 I/O,而不是長時間的線性讀取,5 分鐘可能非常出色。那是 1 / (80000 / 600),或者每 7.5 毫秒讀取一次磁碟。你的硬碟是快還是慢?這取決於型號。

針對類似事物的基準

另一種思考方式是這樣。如果沒有文件更改,ls -Llr則執行相同數量的磁碟活動,但從不讀取任何文件數據(僅元數據)。執行所需的時間ls -Llr是您的上限。

  • rsync(沒有文件更改)明顯慢於ls -Llr?然後可以改進您用於 rsync 的選項。也許-c已啟用或其他一些標誌,它讀取的不僅僅是目錄和元數據(inode 數據)。
  • rsync(沒有文件更改)幾乎和 rsync 一樣快ls -Llr嗎?然後你已經盡可能地調整了 rsync。您必須調整作業系統、添加 RAM、獲得更快的驅動器、更改文件系統等。

與您的開發人員交談

80k 文件只是糟糕的設計。很少有文件系統和系統工具能很好地處理如此大的目錄。如果文件名是 abcdefg.txt,請考慮將它們儲存在 abdc/abcdefg.txt 中(注意重複)。這會將目錄分成更小的目錄,但不需要對程式碼進行巨大的更改。

另外….考慮使用數據庫。如果您在一個目錄中有 80k 個文件,那麼您的開發人員可能正在解決他們真正想要的是數據庫這一事實。MariaDB 或 MySQL 或 PostgreSQL 將是儲存大量數據的更好選擇。

嘿,5分鐘有什麼問題?

最後,5分鐘真的那麼糟糕嗎?如果您每天執行一次此備份,那麼 5 分鐘並不是很多時間。是的,我喜歡速度。但是,如果 5 分鐘對您的客戶來說“足夠好”,那麼對您來說就足夠了。如果您沒有書面的 SLA,不妨與您的使用者進行一次非正式討論,了解他們期望備份的速度。

如果不需要提高性能,我假設您沒有問這個問題。但是,如果您的客戶對 5 分鐘感到滿意,請宣布勝利並繼續其他需要您努力的項目。

*更新:*經過一些討論,我們確定瓶頸是網路。在我放棄之前,我要推薦兩件事:-)。

  • 嘗試通過壓縮從管道中擠出更多頻寬。但是壓縮需要更多的 CPU,所以如果你的 CPU 過載,它可能會使性能變差。嘗試使用和不使用 rsync,並-z在使用和不使用壓縮的情況下配置您的 ssh。對所有 4 種組合計時,看看它們中的任何一種表現是否明顯優於其他組合。

  • 觀察網路流量以查看是否有任何暫停。如果有停頓,您可以找到導致停頓的原因並在那裡進行優化。如果 rsync 總是發送,那麼你真的是在你的極限。您的選擇是:

    • 更快的網路
    • rsync 以外的東西
    • 將源和目標移得更近。如果你不能這樣做,你可以 rsync 到本地機器然後 rsync 到真正的目的地嗎?如果系統在初始 rsync 期間必須關閉,這樣做可能會有好處。

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