'kafka篇-設計思路'

設計 操作系統 數據結構 技術 物理 IT技術分享 2019-08-28
"

1. 設計背景

許多互聯網公司,每天都會產生大量的日誌數據,包括用戶行為記錄、運營指標、系統運行狀況的監控數據等。為了分析用戶的行為或者監控系統的狀態,需要對這些數據進行週期性的分析和統計。

"

1. 設計背景

許多互聯網公司,每天都會產生大量的日誌數據,包括用戶行為記錄、運營指標、系統運行狀況的監控數據等。為了分析用戶的行為或者監控系統的狀態,需要對這些數據進行週期性的分析和統計。

kafka篇-設計思路

傳統的日誌分析系統提供了一種離線處理日誌信息的可擴展方案(類似於從生產環境的服務器上抓取日誌文件,然後聚合到數據倉庫進行離線分析),但如果要進行實時地處理,通常會有較大延遲。

kafka構建了一種新穎的消息系統,提供了類似於消息傳遞系統的API,允許應用程序實時的訂閱日誌事件,做到實時或近實時分析。

2. 持久化設計

與傳統消息系統不同的是,kafka會把消息持久化到磁盤上,以實現消息的回溯功能。

磁盤總是給人們留下“慢速”的印象,事實上,磁盤的速度要比人們預想中的快得多,這取決於使用磁盤的姿勢。常見的SATA磁盤隨機讀寫性能,僅為100K/s,而順序讀寫可達600MB/s,不同的使用姿勢,性能差距可達到6000倍。

kafka為了實現高吞吐的消息服務,充分藉助了磁盤順序讀寫的優勢。

2.1 磁盤順序讀寫

磁盤的順序讀寫是有規律的,並且操作系統進行了大量優化,包括read-ahead 和write-behind 技術,其中read-ahead 是以大的data block為單位預先讀取數據,而write-behind 則是將多個小型的邏輯寫操作,合併成一次大型的物理磁盤寫入。

除此之外,操作系統還對讀寫磁盤的內容進行cache,主動將系統空閒內存用作page cache ,所有的磁盤讀寫操作都會通過這個page cache 。

kafka沒有使用in-process cache 來緩存磁盤數據,而是使用了page cache ,因為即使進程維護了in-process cache ,在讀寫磁盤時,該數據也會被複制到操作系統的page cache 中。直接使用page cache 一方面可以使得緩存容量大大增加,另一方面kafka服務重啟的情況下,緩存依舊可用。

為了充分利用磁盤順序讀寫能力、實現消息存儲時的高吞吐,kafka只是對消息進行簡單的讀取和追加 ,並沒有使用類似於BTree的數據結構來索引數據和隨機讀寫數據。

消息系統一般都是順序消費、依次推送消息,這種根據需求特定場景進行的簡單讀取和追加,既可以滿足實際需求,又能大幅提升吞吐。

"

1. 設計背景

許多互聯網公司,每天都會產生大量的日誌數據,包括用戶行為記錄、運營指標、系統運行狀況的監控數據等。為了分析用戶的行為或者監控系統的狀態,需要對這些數據進行週期性的分析和統計。

kafka篇-設計思路

傳統的日誌分析系統提供了一種離線處理日誌信息的可擴展方案(類似於從生產環境的服務器上抓取日誌文件,然後聚合到數據倉庫進行離線分析),但如果要進行實時地處理,通常會有較大延遲。

kafka構建了一種新穎的消息系統,提供了類似於消息傳遞系統的API,允許應用程序實時的訂閱日誌事件,做到實時或近實時分析。

2. 持久化設計

與傳統消息系統不同的是,kafka會把消息持久化到磁盤上,以實現消息的回溯功能。

磁盤總是給人們留下“慢速”的印象,事實上,磁盤的速度要比人們預想中的快得多,這取決於使用磁盤的姿勢。常見的SATA磁盤隨機讀寫性能,僅為100K/s,而順序讀寫可達600MB/s,不同的使用姿勢,性能差距可達到6000倍。

kafka為了實現高吞吐的消息服務,充分藉助了磁盤順序讀寫的優勢。

2.1 磁盤順序讀寫

磁盤的順序讀寫是有規律的,並且操作系統進行了大量優化,包括read-ahead 和write-behind 技術,其中read-ahead 是以大的data block為單位預先讀取數據,而write-behind 則是將多個小型的邏輯寫操作,合併成一次大型的物理磁盤寫入。

除此之外,操作系統還對讀寫磁盤的內容進行cache,主動將系統空閒內存用作page cache ,所有的磁盤讀寫操作都會通過這個page cache 。

kafka沒有使用in-process cache 來緩存磁盤數據,而是使用了page cache ,因為即使進程維護了in-process cache ,在讀寫磁盤時,該數據也會被複制到操作系統的page cache 中。直接使用page cache 一方面可以使得緩存容量大大增加,另一方面kafka服務重啟的情況下,緩存依舊可用。

為了充分利用磁盤順序讀寫能力、實現消息存儲時的高吞吐,kafka只是對消息進行簡單的讀取和追加 ,並沒有使用類似於BTree的數據結構來索引數據和隨機讀寫數據。

消息系統一般都是順序消費、依次推送消息,這種根據需求特定場景進行的簡單讀取和追加,既可以滿足實際需求,又能大幅提升吞吐。

kafka篇-設計思路

2.2 消息過期機制

在 Kafka 中,可以讓消息保留相對較長的一段時間(比如一週),而不是試圖在被消費後立即刪除,也可以讓消息保留到一定規模後,比如消息大小超出2G,再清除舊數據。

3. 高吞吐設計

kafka的吞吐表現是極為優秀的,在kafka篇-基本介紹中也給出了吞吐性能的測試數據,這裡簡單談一談kafka高吞吐的設計要點。

3.1 本地IO的優化

kafka強依賴操作系統提供的page cache功能,採用簡單讀取、順序追加的方式,保證讀寫操作均屬於Sequence I/O,從而充分利用了磁盤順序讀寫的性能。

3.2 網絡IO的優化

kafka是一個分佈式的消息系統,在消息的生產和消費過程中,不僅涉及到本地的IO,還涉及大量的網絡IO,對於網絡層IO的優化,主要涉及兩個方面:

  • 避免大量小型的IO操作
  • 避免過多的字節拷貝

小型的IO操作發生在客戶端與服務器之間,以及服務端自身的持久化操作中。為了避免大量小型的IO操作,kafka對消息進行分組,使得多個消息打包成一組,而不是每次發送一條消息 ,這樣可以減少小型網絡IO的操作,批處理從而帶來更大的吞吐。

為了避免過多的字節拷貝,kafka對日誌塊的網絡傳輸也進行了優化,通過sendfile 系統調用將數據從page cache直接轉移到socket網絡連接中。數據從文件到套接字,常見的數據傳輸路徑如下:

  • 操作系統從磁盤讀取數據 -> 內核空間的page cache
  • 應用程序讀取內核空間數據 -> 用戶空間的緩衝區
  • 應用程序將數據(用戶空間的緩衝區) -> 內核空間到套接字緩衝區(內核空間)
  • 操作系統將數據從套接字緩衝區(內核空間) -> 網絡發送的 NIC 緩衝區

中間涉及4次copy操作和兩次系統調用,而通過sendfile的話,可以允許操作系統將數據從page cache直接發送到網絡,即只需最後一步操作,可將數據複製到NIC緩衝區。

"

1. 設計背景

許多互聯網公司,每天都會產生大量的日誌數據,包括用戶行為記錄、運營指標、系統運行狀況的監控數據等。為了分析用戶的行為或者監控系統的狀態,需要對這些數據進行週期性的分析和統計。

kafka篇-設計思路

傳統的日誌分析系統提供了一種離線處理日誌信息的可擴展方案(類似於從生產環境的服務器上抓取日誌文件,然後聚合到數據倉庫進行離線分析),但如果要進行實時地處理,通常會有較大延遲。

kafka構建了一種新穎的消息系統,提供了類似於消息傳遞系統的API,允許應用程序實時的訂閱日誌事件,做到實時或近實時分析。

2. 持久化設計

與傳統消息系統不同的是,kafka會把消息持久化到磁盤上,以實現消息的回溯功能。

磁盤總是給人們留下“慢速”的印象,事實上,磁盤的速度要比人們預想中的快得多,這取決於使用磁盤的姿勢。常見的SATA磁盤隨機讀寫性能,僅為100K/s,而順序讀寫可達600MB/s,不同的使用姿勢,性能差距可達到6000倍。

kafka為了實現高吞吐的消息服務,充分藉助了磁盤順序讀寫的優勢。

2.1 磁盤順序讀寫

磁盤的順序讀寫是有規律的,並且操作系統進行了大量優化,包括read-ahead 和write-behind 技術,其中read-ahead 是以大的data block為單位預先讀取數據,而write-behind 則是將多個小型的邏輯寫操作,合併成一次大型的物理磁盤寫入。

除此之外,操作系統還對讀寫磁盤的內容進行cache,主動將系統空閒內存用作page cache ,所有的磁盤讀寫操作都會通過這個page cache 。

kafka沒有使用in-process cache 來緩存磁盤數據,而是使用了page cache ,因為即使進程維護了in-process cache ,在讀寫磁盤時,該數據也會被複制到操作系統的page cache 中。直接使用page cache 一方面可以使得緩存容量大大增加,另一方面kafka服務重啟的情況下,緩存依舊可用。

為了充分利用磁盤順序讀寫能力、實現消息存儲時的高吞吐,kafka只是對消息進行簡單的讀取和追加 ,並沒有使用類似於BTree的數據結構來索引數據和隨機讀寫數據。

消息系統一般都是順序消費、依次推送消息,這種根據需求特定場景進行的簡單讀取和追加,既可以滿足實際需求,又能大幅提升吞吐。

kafka篇-設計思路

2.2 消息過期機制

在 Kafka 中,可以讓消息保留相對較長的一段時間(比如一週),而不是試圖在被消費後立即刪除,也可以讓消息保留到一定規模後,比如消息大小超出2G,再清除舊數據。

3. 高吞吐設計

kafka的吞吐表現是極為優秀的,在kafka篇-基本介紹中也給出了吞吐性能的測試數據,這裡簡單談一談kafka高吞吐的設計要點。

3.1 本地IO的優化

kafka強依賴操作系統提供的page cache功能,採用簡單讀取、順序追加的方式,保證讀寫操作均屬於Sequence I/O,從而充分利用了磁盤順序讀寫的性能。

3.2 網絡IO的優化

kafka是一個分佈式的消息系統,在消息的生產和消費過程中,不僅涉及到本地的IO,還涉及大量的網絡IO,對於網絡層IO的優化,主要涉及兩個方面:

  • 避免大量小型的IO操作
  • 避免過多的字節拷貝

小型的IO操作發生在客戶端與服務器之間,以及服務端自身的持久化操作中。為了避免大量小型的IO操作,kafka對消息進行分組,使得多個消息打包成一組,而不是每次發送一條消息 ,這樣可以減少小型網絡IO的操作,批處理從而帶來更大的吞吐。

為了避免過多的字節拷貝,kafka對日誌塊的網絡傳輸也進行了優化,通過sendfile 系統調用將數據從page cache直接轉移到socket網絡連接中。數據從文件到套接字,常見的數據傳輸路徑如下:

  • 操作系統從磁盤讀取數據 -> 內核空間的page cache
  • 應用程序讀取內核空間數據 -> 用戶空間的緩衝區
  • 應用程序將數據(用戶空間的緩衝區) -> 內核空間到套接字緩衝區(內核空間)
  • 操作系統將數據從套接字緩衝區(內核空間) -> 網絡發送的 NIC 緩衝區

中間涉及4次copy操作和兩次系統調用,而通過sendfile的話,可以允許操作系統將數據從page cache直接發送到網絡,即只需最後一步操作,可將數據複製到NIC緩衝區。

kafka篇-設計思路

3.3 壓縮

kafka提供了端到端的數據壓縮功能,將消息以壓縮格式寫入,並在日誌中保持壓縮,只在consumer消費時解壓縮。

4. 穩定性設計

穩定性對每一個系統來說,都是尤為重要的,kafka為了保障穩定性,不僅為每個數據分區實現了副本的概念,而且為日誌備份提供了一整套的保障機制。

4.1 分區和副本

kafka將主題劃分為多個分區,通過分區規則將消息存儲到相應的分區,只要分區規則設置的合理,那麼所有消息將會被均勻的分佈到不同的分區中,從而實現負載均衡和水平擴展。kafka每個分區擁有若干副本,當集群部分節點出現問題時,可以進行故障轉移,以保證數據的可用性。

4.2 日誌備份 ISR

kafka穩定性的核心是備份日誌文件,正常情況下每個分區都有一個leader和零或多個followers,讀寫操作均由leader處理,followers節點同步leader節點的日誌,保持消息和偏移量同leader一致。日誌的讀寫操作均由leader完成,其他follower節點從leader同步日誌。如果leader因意外而退出,kafka會通過ISR集合選出新的leader節點。

ISR(a set of in-sync replicas)是kafka維護的同步狀態集合,只有這個集合的成員才有資格被選為leader,並且一條消息需要被這個集合的所有節點讀取並追加到日誌,這條消息才可以被視為提交,ISR集合的變化會持久化到ZooKeeper中。

需要的Java架構師方面的資料可以關注之後私信哈,回覆“資料”領取免費架構視頻資料,記得要點贊轉發噢!!!

"

相關推薦

推薦中...