kafka設計思想

動機

  • 爲了作一個公共、統1、能夠支持龐大數據量、實時的平臺。
  • 須要具有高吞吐量來支持龐大的事件流
  • 能夠處理積壓數據,能夠緩存數據,用來支持週期性從線下load進來的數據
  • 系統爲了處理更多的消息,不得不低延時提交數據???
  • 咱們想讓系統支持,分區、分佈式、實時處理新增以及衍生的消息,所以設計了分區和消費模式。
  • 由於是分佈式,因此須要支持容錯機制
  • 當知足以上支持條件後,kafka更像是一個日誌數據庫。

持久化

  • kafka使用磁盤來存儲和緩存消息。
  • 線性讀寫的速度是隨機讀寫的6000倍
  • http://queue.acm.org/detail.cfm?id=1563874,在這篇文章中介紹,線性讀寫磁盤的速度近乎趕得上隨機內存訪問
  • kafka是基於jvm之上的,所以也有以下兩個弊端linux

    • 數據對象要比數據佔用更多的空間,有的時候會是原數據大小的一倍
    • 垃圾回收愈來愈複雜,特別是隨着堆的增長,垃圾回收會愈來愈慢
  • 基於以上兩個緣由,咱們選擇磁盤存儲和緩存數據。
  • 數據存儲於磁盤,能夠避免掉GC
  • 數據緩存於磁盤,當服務down掉後,重啓能夠從新運行,數據不丟失,若是緩存於內存,數據將會丟失,即便down掉前刷入磁盤,從新從磁盤load進內存也將花費不少時間。
  • 全部的日誌數據一旦進來,當即刷入磁盤,並不會先儘可能使用內存。
  • 傳統的消息隊列都會使用B樹來管理消息,以便用來隨機讀取。B樹 時間複雜度 0(log n),可是這個並不適用於磁盤操做。磁盤尋道大概要花費10ms,而且尋道不是並行的。
  • 使用無線空間的磁盤,kafka能夠提供不少傳統消息服務沒有的特性。例如,在kafka中當消息被消費後不試圖刪除消息,咱們能夠保存消息一段時間(一般是一週),這樣消費端就能夠更靈活的消費消息。數據庫

性能

  • 排除掉磁盤讀寫太低的性能問題,還有兩個性能問題。緩存

    • 過多的微小的IO操做
    • 序列化
  • 爲了下降IO的次數,kafka添加了消息集,這樣能夠一次性的將消息推送進服務端,而不像傳統的消息服務,每次只能推送單條消息。這樣還有一個好處,就是講網絡消耗均分,不會集中在一點。一樣消費端也能夠一次消費取大量的消息。數據塊越大,線性讀寫的優點就越明顯。
  • 序列化是消耗性能的另外一個問題,爲解決這個問題,kafka引入標準二進制消息協議,生產者將消息序列化後傳給服務端。所以在生產者、消費者、服務端都是公用的,而且在傳輸過程當中,消息是不可更改的。消息服務端只是維護這些消息二進制文件。
  • linux 從文件到socket流。 磁盤->kernel->user space -> kernel(socker buffer)-> nic buffer
  • sendfile 能夠避免重複copy數據,能夠直接從包緩存到網絡,只有NICbuffer是必須的。這樣能夠提升消費消息的效率
  • kafka提供了數據壓縮,基於消息集合的壓縮服務器

生產者

  • 負載均衡網絡

    • kafka的消息是直接傳送給broker的,不通過任何中間路由,爲此,全部的kafka節點須要返回,哪一個節點是存活的,主節點和消息的分片都在哪。而後生產者直接請求分片便可。(與hdfs的設計相同)
    • kafka提供基礎分片方式,經過key進行hash。
  • 異步發送負載均衡

    異步發送是爲了知足一次性傳輸大的消息集合。經過異步的方式能夠提升吞吐量。異步

消費者

  • 推送和拉取的抉擇jvm

    • kafka採用拉取的方式來消費消息。
    • 拉取方式能夠配合消息集使用。
    • 拉取消息的缺陷是爲了更快的響應,須要不停地輪詢消息隊列,即使當前消息隊列沒有消息。若是當前拉取數據時消息隊列中沒有消息,則kafka會在拉取時阻塞,知道有數據。(保持長鏈接)
    • 除此以外還有一些別消息傳輸,例如:生產者,生產並存儲消息進生產自身磁盤中,當消費者拉取消息的時候,服務端從生產者服務器拉取。不過這種方式不適合多生產者。數據很是散,不易管理。
  • 記錄消費位置socket

    • 大部分消息系統會將消息是否已消費,消費到哪了,記錄在broker中。這有不少弊端:每當一個一個消息被消費後,服務端除了本身要記錄下來之外,還須要等待消費的ack確認。所以,這種設計在集羣化的消息系統中效率是很低下的,這種設計又是必須的,由於服務端須要知道哪些消息已經被消費了,能夠刪除這些消息了,這樣才能保證broker中的數據足夠小。
    • 常規的消息系統爲了須要維護消息的多種狀態(已發送,已確認),而且有消費屢次的可能性(消費消息後發送ack失敗)
    • kafka將消息進行分區,每一個分區只有一個消費者。拉取的方式只是爲消費者記錄一個位置便可。
    • kakfa提供重複消費消息的功能。
  • 加載離線數據分佈式

    • kafka能夠做爲離線數據,用做hadoop MR的輸入。

消息傳遞的真諦

  • kafka經過在消息上標記惟一key來避免重複傳輸。(當網絡出現故障後,從新傳入數據,經過key能夠判斷當前數據是否已經存在。)
相關文章
相關標籤/搜索