Linux

防止多個 cron 作業同時執行

  • March 31, 2020

我的伺服器在午夜執行許多 cron 作業。每個作業都會創建一個備份,通過創建一個 tarball 並使用xz.

由於xz是 CPU 和記憶體豬,我為每個作業添加了隨機延遲,因此它們“不應該”相互破壞。但是有時確實會發生這種情況,並且會給伺服器帶來沉重的負擔。

假設:

  • 根據我的流量,午夜是進行備份的最佳時間 - 但仍然有流量(這就是我想避免過度負載的原因)
  • 每個面向公眾的應用程序都與它自己的備份作業相關聯,並且它們是解耦的(它們彼此不知道) - 所以我不能將備份 cron 作業合併到一個作業中,因為我需要那種粒度
  • 我不能硬編碼每個人的開始時間,因為這會增加維護 - 將應用程序添加到伺服器(通過 ansible),我只需部署它並將備份 cron 作業(計劃在午夜)放入/etc/cron.d/,然後隨機工作開始前的延遲通常就足夠了
  • 我稍微限制了作業tar ... | pv --rate-limit ... | xz ...- 但是雖然這減少了每個作業的負載,但它也減慢了每個作業的速度,因此增加了多個作業同時執行的可能性(當它們加在一起時可能會佔用 100% 的 CPU)

一個可能的解決方案是為每個作業創建一個臨時文件,表明它正忙,然後將其刪除。問題是如果一個作業檢測到這個文件,它會做什麼?睡覺?多長時間?我可以使用 讓它隨機休眠一段時間at,但是如果我的備份腳本出現問題,我可能會有大量的作業相互競爭。另一個維護難題。

那麼,通常如何解決這個問題呢?基本上,這是一種安排相關 cron 作業的簡單方法,不會讓它們相互干擾,也不需要微調開始時間。

隨機分配開始時間有利於避免高峰時間,並且使用 Ansible 很容易做到。但並不能真正確保資源可用於維持多個並發壓縮作業。關於如何進行低影響備份的方法有幾種,請考慮其中的一些或全部。

通過基於 CPU 節流的程序執行您的命令列表。例如,GNU 並行 --limit 100% 只會在平均負載低於 CPU 數量時執行。

每個作業都嘗試獲取少量鎖中的一個。例如flock來自 util-linux、Python 或 Perl。看起來很簡單,但是維護其中的一些會很煩人。我認為具有內置作業管理的包裝器命令更健壯,例如 GNU 並行。

評估您的壓縮算法。zstd是現代且快速的,只需要更多的記憶體。

將備份作業分散到更多小時。考慮一下 00:00 到 03:00 是否可以滿足您的性能和備份要求。

添加 CPU。為峰值容量調整大小可能很昂貴,但它允許更多的壓縮執行緒。

將備份完全解除安裝到另一台主機。拍攝儲存陣列或基於雲的磁碟快照。呈現給不同的主持人。從那裡備份。

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