壓縮具體來說就是用 cpu 時間去換磁碟空間或網路 i/o 傳輸量,希望以較多的 cpu 開銷帶來更少的磁碟占用或更少的網路 i/o 傳輸。在 kafka 中,壓縮也是用來做這件事的。
說起壓縮訊息,就要從 kafka 的訊息格式說起了。目前 kafka 目前共有三大類訊息格式v0、v1、v2
,詳細內容請參考文章:
不論是哪個版本,kafka 的訊息層次都分為兩層:訊息集合(message set)以及訊息(message)。乙個訊息集合中包含若干條日誌項(record item),而日誌項才是真正封裝訊息的地方。kafka 底層的訊息日誌由一系列訊息集合日誌項組成。kafka 通常不會直接操作具體的一條條訊息,它總是在訊息集合這個層面上進行寫入操作。
那麼社群引入 v2 版本的目的是什麼呢?v2 版本主要是針對 v1 版本的一些弊端做了修正,和我們今天討論的主題相關的修正有哪些呢?先介紹乙個,就是把訊息的公共部分抽取出來放到外層訊息集合裡面,這樣就不用每條訊息都儲存這些資訊了。
我來舉個例子。原來在 v1 版本中,每條訊息都需要執行 crc 校驗,但有些情況下訊息的 crc 值是會發生變化的。比如在 broker 端可能會對訊息時間戳字段進行更新,那麼重新計算之後的 crc 值也會相應更新;再比如 broker 端在執行訊息格式轉換時(主要是為了相容老版本客戶端程式),也會帶來 crc 值的變化。鑑於這些情況,再對每條訊息都執行 crc 校驗就有點沒必要了,不僅浪費空間還耽誤 cpu 時間,因此在 v2 版本中,訊息的 crc 校驗工作就被移到了訊息集合這一層。
v2 版本還有乙個和壓縮息息相關的改進,就是儲存壓縮訊息的方法發生了變化。之前 v1 版本中儲存壓縮訊息的方法是把多條訊息進行壓縮然後儲存到外層訊息的訊息體字段中;而 v2 版本的做法是對整個訊息集合進行壓縮。顯然後者應該比前者有更好的壓縮效果。
我對兩個版本分別做了乙個簡單的測試,結果顯示,在相同條件下,不論是否啟用壓縮,v2 版本都比 v1 版本節省磁碟空間。當啟用壓縮時,這種節省空間的效果更加明顯。
在 kafka 中,壓縮可能發生在兩個地方:生產者端和 broker 端
。
生產者程式中配置 compression.type 引數即表示啟用指定型別的壓縮演算法。比如下面這段程式**展示了如何構建乙個開啟 lz4 的 producer 物件:
properties props =
newproperties()
; props.
put(
"bootstrap.servers"
,"localhost:9092");
props.
put(
"acks"
,"all");
props.
put(
"key.serializer"
,"org.apache.kafka.common.serialization.stringserializer");
props.
put(
"value.serializer"
,"org.apache.kafka.common.serialization.stringserializer");
// 開啟 lz4 壓縮
props.
put(
"compression.type"
,"lz4");
producer
producer =
newkafkaproducer
<
>
(props)
;
這裡比較關鍵的**行是 props.put(「compression.type」, 「lz4」),它表明該 producer 的壓縮演算法使用的是 lz4。這樣 producer 啟動後生產的每個訊息集合都是經 lz4 壓縮過的,故而能很好地節省網路傳輸頻寬以及 kafka broker 端的磁碟占用。
在生產者端啟用壓縮是很自然的想法,那為什麼我說在 broker 端也可能進行壓縮呢?其實大部分情況下 broker 從 producer 端接收到訊息後僅僅是原封不動地儲存而不會對其進行任何修改,但這裡的「大部分情況」也是要滿足一定條件的。有兩種例外情況就可能讓 broker 重新壓縮訊息。
- broker 端發生了訊息格式轉換。
所謂的訊息格式轉換主要是為了相容老版本的消費者程式。還記得之前說過的 v1、v2 版本吧?在乙個生產環境中,kafka 集群中同時儲存多種版本的訊息格式非常常見。為了相容老版本的格式,broker 端會對新版本訊息執行向老版本格式的轉換。這個過程中會涉及訊息的解壓縮和重新壓縮。一般情況下這種訊息格式轉換對效能是有很大影響的,除了這裡的壓縮之外,它還讓 kafka 喪失了引以為豪的 zero copy 特性。
有壓縮必有解壓縮!通常來說解壓縮發生在消費者程式中,也就是說 producer 傳送壓縮訊息到 broker 後,broker 照單全收並原樣儲存起來。當 consumer 程式請求這部分訊息時,broker 依然原樣傳送出去,當訊息到達 consumer 端後,由 consumer 自行解壓縮還原成之前的訊息。
那麼現在問題來了,consumer 怎麼知道這些訊息是用何種壓縮演算法壓縮的呢?其實答案就在訊息中。kafka 會將啟用了哪種壓縮演算法封裝進訊息集合中,這樣當 consumer 讀取到訊息集合時,它自然就知道了這些訊息使用的是哪種壓縮演算法。
壓縮與解壓
linux下怎麼解字尾名是gzip的檔案?1.以.a為副檔名的檔案 tar xv file.a 2.以.z為副檔名的檔案 uncompress file.z 3.以.gz為副檔名的檔案 gunzip file.gz 4.以.bz2為副檔名的檔案 bunzip2 file.bz2 5.以.tar.z為...
壓縮與解壓
一 python壓縮解壓libs zlib infozip免費的壓縮lib。bzip2 讀寫bz壓縮檔案,與bzip2和bunzip2壓縮程式相容。gzip 讀寫gz壓縮檔案,與gnu壓縮程式gzip和gunzip相容。zipfile 讀寫zip壓縮檔案,與zip,unzip,pkzip,pkunz...
壓縮與解壓
1.基礎壓縮指令 gzip file 壓縮對應檔案,原始檔移除,如果是多個檔案壓縮,則被分別壓縮,不會打包。壓縮後檔名file.gz gunzip file.gz 解壓file.gz,壓縮包移除。bzip2 file k 同gzip,但是壓縮後的檔名file.bz2,k表示原始檔保留 bunzip2...