奈飛傾向於使用速度優先的快速資料壓縮演算法

banq發表於2022-05-12

Joey Lynch 是 Netflix 的高階軟體工程師,負責雲資料工程。他花費大量時間在資料庫之間移動資料以及對資料進行雜湊/壓縮。
根據他的所有經驗,他寫了一篇很棒的部落格文章,介紹了您必須處理資料的一些常見任務,他談到了最好的演算法、最差的演算法以及預期的效能差異:

作為一名主要處理資料和資料庫的工程師,我花了很多時間移動資料、雜湊、壓縮、解壓縮,並且通常嘗試透過 TLS 在 VM 和 blob儲存之間剷起資料。我經常驚訝於有多少系統只支援執行這些操作的緩慢、低效和昂貴的方式。

以我的經驗,這些糟糕的演算法選擇比現代替代方案慢幾個數量級。事實上,使用快速演算法通常是實際進行壓縮/雜湊/加密和“嗯,我會跳過它”之間的區別。為了使用我們更多的 CPU 時間來做有用的工作,而不是融化冰蓋和給程式設計師過長的咖啡休息時間,我們將在這篇文章中探索一些更快的替代方案。

常見的不良選擇

  • gzip( zlib):一個值得信賴的主力,但也是一個非常慢的演算法。在很多情況下,您的網路速度很快1 Gbps+(
  • xz( lzma):一種具有相當好的比率的演算法,但壓縮速度很慢,以至於在實踐中唯一的潛在用例是單寫多讀用例。
  • snappy:作為最早的“我會用比率來換取速度”的演算法之一,snappy 在當時是很好的。如今,它幾乎總是優於其他選擇。


如果我關心的是比率
試試 zstd:為了花費更多的壓縮CPU時間以獲得更好的壓縮率,增加壓縮級別或增加塊的大小。我發現在大多數資料庫工作負載中,預設級別(3)甚至是1級是寫量大的資料集的好選擇(越來越接近lz4),10級是讀量大的資料集的好選擇(在每個維度上都超過了gzip)。請注意,zstd嚴格地支配著gzip,因為它更快,而且得到更好的比率。

更棒的是:zstd支援訓練字典,如果你有很多單獨的小而集體的大的JSON資料(看著你的追蹤系統),這真的可以派上用場。

如果我只關心速度
試試lz4:憑藉接近記憶體的速度和體面的比率,這種演算法幾乎總是比完全不壓縮更安全的選擇。它有很好的語言支援,對於實時壓縮/解壓縮來說是特別好的,因為它是如此便宜。

如果我想把資料從這裡鏟到那裡
試試zstd --adapt. :這個功能會隨著IO條件的變化而自動調整壓縮率,以便在CPU和 "保持管道暢通 "之間做出當前的最佳權衡。

例如,如果你的系統有很少的空閒CPU,但有一個快速的網路(看著你的i3en例項),zstd --adapt將自動以較低的水平進行壓縮,以儘量減少總傳輸時間。如果你有一個緩慢的網路和額外的CPU,它將自動在一個較高的級別上進行壓縮。

為什麼快速的資料演算法很重要?
它很重要,因為大多數系統是選擇慢速選項,並使常規開發活動在現代雲基礎設施(快速網路)中花費更多時間。比如說。

  • 備份資料。使用gzip和sha256將1 TiB的資料備份到一個快速的blob儲存(可以沉降多個GiBps),需要15個小時左右。用zstd和xxhash做則需要2.2小時。及時備份是資料系統最重要的屬性之一。
  • 軟體包。在預設情況下,debian的軟體包要麼不壓縮,要麼用xz壓縮。在一個1G的網路上安裝500 MiB的未壓縮的debian軟體包需要~5s,用xz壓縮實際上會變慢,需要~1s+~6s=~7s,而用zstd -19壓縮需要~1s+~1s=~2s。如果檢查sha256,將再增加~20s,總共~30s,而如果我們用blake3檢查,將增加~0.1s,總共~3s。我寧願選擇3秒而不是30秒。當你構建容器映象、烘烤雲虛擬機器映象或用配置管理(puppet/chef)啟動伺服器時,這一點都很重要。
  • 容器映象。預設情況下,docker使用gzip壓縮和sha256校驗,這意味著要解壓和校驗4GiB的容器,我需要大約60s的CPU時間,而不是使用zstd和xxhash的6s(或使用blake3的6.5s)。當你的docker pull在你的應用程式的啟動路徑中時,這很重要。


使用好的演算法的一個主要缺點是它們可能並不總是預設出現在您的語言或作業系統中。我在以下實現方面有很好的經驗:


 

相關文章