Kafka這些名詞都說不出所以然,您竟然敢說自己精通kafka

2020-12-13 阿啄debugIT

Kafka具有快速,可擴展,耐用和容錯的發布、訂閱消息傳遞系統,被用於JMS(Java消息隊列服務)。

Kafka具有更高的吞吐量,可靠性和複製特性,使其適用於跟蹤服務呼叫或物聯網傳感器數據。

kafka與內存微服務一起使用,提供可靠性,可用於向 CEP(複雜事件流系統)和IoT / IFTTT式自動化系統提供事件。

Kafka可以與Flume ,Spark Streaming,Storm,HBase,Flink和Spark一起工作,以實時接收,分析和處理流數據。

Kafka代理支持在Hadoop或Spark中進行低延遲後續分析的大量消息流,及Kafka流媒體可用於實時分析。

…………

kafka基於發布/訂閱模式的消息隊列

kafka有那麼多優異的性能,難怪許多大公司都在使用Kafka!

01kafka架構

Kafka 運行在一個由一臺或多臺伺服器組成的集群上,並且分區可以跨集群分布。

Kafka 存儲的消息來自任意多被稱為 Producer 生產者的進程。數據從而可以被發布到不同的 Topic 主題下不同 Partition 分區。在一個分區內,這些消息被索引,連同時間戳存儲在一起。其它被稱為 Consumer 消費者的進程,可以從分區訂閱消息。

Kafka 一些重要概念,您真的認識熟悉?

kafka架構

Producer: 消息生產者,向 Kafka Broker 發消息的客戶端。

Consumer: 消息消費者,從Kafka Broker 取消息的客戶端。

Consumer Group: 消費者組(CG),消費者組內每個消費者,負責消費不同分區的數據,提高消費能力。一個分區只能由組內一個消費者消費,消費者組之間互不影響。所有的消費者都屬於某個消費者組,即消費者組是邏輯上的一個訂閱者

Broker:一臺 Kafka 機器就是一個 broker。一個集群由多個 broker 組成。一個 broker 可以容納多個 topic

Topic: 可以理解為一個隊列,topic 將消息分類,生產者和消費者面向的是同一個 topic

Partition: 為了實現擴展性,提高並發能力,一個非常大的 topic ,可以分布到多個 broker (即伺服器)上,一個 topic 可以分為多個 partition,每個 partition 是一個有序的隊列。

Replica: 副本,為實現備份的功能,保證集群中的某個節點發生故障時,該節點上的 partition 數據不丟失,且 Kafka 仍然能夠繼續工作,Kafka 提供了副本機制,一個 topic 的每個分區,都有若干個副本,一個 leader 和若干個 follower

Leader: 每個分區多個副本「主」副本,生產者發送數據的對象,以及消費者消費數據的對象,都是leader

Follower: 每個分區多個副本「從」副本實時從 leader 中同步數據,保持和 leader 數據的同步。leader 發生故障時,某個 follower 還會成為新的 leader。

offset: 消費者消費的位置信息,監控數據消費到什麼位置,當消費者掛掉,再重新恢復的時候,可以從消費位置繼續消費

Zookeeper: Kafka 集群能夠正常工作,需要依賴於 zookeeper,zookeeper 幫助Kafka 存儲和管理集群信息。

02kafka工作流程

Kafka集群是一個分布式流平臺,將 Record 流存儲在稱為 topic 的類別中,每個記錄由一個鍵、一個值和一個時間戳組成。

kafka工作流程

發布和訂閱記錄流,類似於消息隊列或企業消息傳遞系統:Kafka 中消息是以 topic 進行分類的,生產者生產消息,消費者消費消息,面向的都是同一個 topic。容錯的持久方式存儲記錄流:topic 是邏輯上的概念,而 partition 是物理上的概念,每個 partition 對應於一個 log 文件,該 log 文件中存儲的就是 Producer 生產的數據處理記錄流:Producer 生產的數據,會不斷追加到該 log 文件末端,且每條數據都有自己的 offset。消費者組中的每個消費者,都會實時記錄自己消費到了哪個 offset,以便出錯恢復時,從上次的位置繼續消費。

03Kafka存儲機制

由於生產者生產的消息,會不斷追加到 log 文件末尾,為防止log 文件過大,導致數據定位效率低下,Kafka 採取了分片索引機制,將每個 partition分為多個 segment(段),每個 segment 對應兩個文件:「. index」 索引文件和 「. log」 數據文件。

Kafka存儲機制

這些文件位於同一文件下,該文件夾的命名規則為:topic 名-分區號。例如,first 這個 topic 有三分分區,則其對應的文件夾為 first-0,first-1,first-2。

segment 對應的文件

index 和 log 文件以當前 segment的第一條消息的 offset 命名。下圖為 index 文件 和 log 文件的結構示意圖。

二分法查找數據

「.index」 文件存儲大量的索引信息,「.log」 文件存儲大量的數據,索引文件中的元數據指向對應數據文件中 message 的物理偏移量

04Kafka如何保證百萬級寫入速度?

1、頁緩存技術 + 磁碟順序寫,針對於Producer: 消息生產者

Kafka每次接到數據,都會往磁碟上去寫

首先Kafka是基於作業系統頁緩存來實現文件寫入的。

作業系統本身有一層緩存,叫做page cache,是在內存裡的緩存,我們也可以稱之為os cache,意思就是作業系統自己管理的緩存

你在寫入磁碟文件的時候,可以直接寫入這個os cache裡,也就是僅僅寫入內存中,接下來由作業系統自己,決定什麼時候把os cache裡的數據,真的刷入磁碟文件中。

因為其實這裡相當於是在寫內存,不是在寫磁碟,大家看下圖。

Kafka是基於作業系統的頁緩存

接著另外一個就是kafka寫數據的時候,非常關鍵的一點,他是以磁碟順序寫的方式來寫的。也就是說,僅僅將數據追加到文件的末尾不是在文件的隨機位置,來修改數據。

普通的機械磁碟,如果你要是隨機寫的話,確實性能極差,也就是隨便找到文件的某個位置來寫數據。

但是如果你是追加文件末尾按照順序的方式,來寫數據的話,那麼這種磁碟順序寫的性能,基本上可以跟寫內存的性能本身也是差不多的

Kafka在寫數據的時候,一方面基於了os層面的page cache來寫數據,本質就是在寫內存罷了;另一方面,採用磁碟順序寫的方式,即使數據刷入磁碟的時候,性能也是極高的,也跟寫內存是差不多的。

所以要保證每秒寫入幾萬,甚至幾十萬條數據的核心點,就是盡最大可能提升每條數據寫入的性能,這樣就可以在單位時間內,寫入更多的數據量,提升吞吐量

2、零拷貝技術,針對於Consumer: 消息消費者

從Kafka裡經常要消費數據,那麼消費的時候,實際上,就是要從kafka的磁碟文件裡,讀取某條數據,然後發送給下遊的消費者,如下圖所示。

那麼這裡如果頻繁的從磁碟讀數據,然後發給消費者,性能瓶頸在哪裡呢?

kafka頻繁的從磁碟讀數據

假設要是kafka什麼優化都不做,就是很簡單的從磁碟讀數據發送給下遊的消費者,那麼大概過程如下所示:

先看看要讀的數據在不在os cache裡,如果不在的話,就從磁碟文件裡讀取數據後,放入os cache。

接著從作業系統的os cache裡,拷貝數據應用程式進程的緩存裡,再從應用程式進程的緩存裡,拷貝數據到作業系統層面的Socket緩存裡,最後從Socket緩存裡,提取數據後發送到網卡,最後發送出去給下遊消費。

整個過程,如下圖所示:

kafka不做優化的消費流程

看上圖,很明顯可以看到,有兩次沒必要拷貝吧!

一次是從作業系統的cache裡,拷貝到應用進程的緩存裡,接著又從應用程式緩存拷貝回作業系統的Socket緩存裡。而且為了進行這兩次拷貝,中間還發生了好幾次上下文切換,一會兒是應用程式在執行,一會兒上下文切換到作業系統來執行。

所以這種方式來讀取數據是比較消耗性能的。

Kafka為了解決這個問題,在讀數據的時候是引入零拷貝技術

也就是說,直接讓作業系統的cache中的數據,發送到網卡後,傳輸給下遊的消費者,中間跳過了兩次拷貝數據的步驟,Socket緩存中僅僅會拷貝一個描述符過去,不會拷貝數據到Socket緩存。

大家看下圖,體會一下這個精妙的過程:

Socket緩存中僅僅會拷貝一個描述符

通過零拷貝技術,就不需要把os cache裡的數據,拷貝到應用緩存,再從應用緩存拷貝到Socket緩存了兩次拷貝都省略了,所以叫做零拷貝。

對Socket緩存,僅僅就是拷貝數據的描述符過去,然後數據就直接從os cache中,發送到網卡上去了,這個過程大大的提升了數據消費時,讀取文件數據的性能。

而且大家會注意到,在從磁碟讀數據的時候,會先看看os cache內存中是否有,如果有的話,其實讀數據都是直接讀內存的。

如果kafka集群經過良好的調優,大家會發現大量的數據,都是直接寫入os cache中,然後讀數據的時候,也是從os cache中讀。

相當於是Kafka完全基於內存提供數據的寫和讀了,所以這個整體性能會極其的高。

這個原理與Elasticsearch的架構原理類似,其實ES底層,也是大量基於os cache,實現了海量數據的高性能檢索的。

05Kafka如何做到不丟失不重複消費

kafka其實有兩次消息傳遞,一次生產者發送消息給kafka,一次消費者去kafka消費消息。

兩次傳遞都會影響最終結果,兩次都是精確一次,最終結果才是精確一次

1、Produce端消息傳遞

producer端的代碼

其中指定了一個參數 acks 可以有三個值選擇:

0: 實現了at most once,producer完全不管broker的處理結果,回調也就沒有用了,並不能保證消息成功發送,但是這種吞吐量最高。

-1或者all: leader broker會等消息寫入 並且ISR(In-Sync Replicas)都寫入後,才會響應,這種只要ISR有副本存活就肯定不會丟失,但吞吐量最低

1: 默認值為1,producer級別是at least once。並不能exactly once。 leader broker自己寫入後就響應,不會等待ISR其他的副本寫入,只要leader broker存活就不會丟失,即保證了不丟失,也保證了吞吐量

ISR有副本存活就肯定不會丟失

若消息成功寫入,而這個時候由於網絡問題,producer沒有收到寫入成功的響應,producer就會開啟重試的操作,直到網絡恢復,消息就發送了多次。這就是at least once了。

2、Consumer端消息傳遞

consumer是靠offset保證消息傳遞

其中有一個參數是 enable.auto.commit,若設置為true,自動提交的機制,consumer在消費前提交offset,就實現了at most once;若設置為false,是消費後提交,那麼 auto.commit.interval.ms 也就不被再考慮了,就實現了 at least once

06kafka可以在消費端實現"Exactly Once"

通過了解producer端與consumer端的設置,發現kafka在兩端的默認配置,都是at least once可能重複,通過配置也不能做到exactly once,好像kafka的消息一定會丟失或者重複的,是不是沒有辦法做到exactly once了呢?

有辦法做到exactly once

確實在kafka 0.11.0.0版本之前producer端確實是不可能的,但是在kafka 0.11.0.0版本之後,kafka正式推出了idempotent(冪等的) producer,及對事務的支持。

冪等的producer

kafka 0.11.0.0版本引入了idempotent producer機制,在這個機制中,同一消息可能被producer發送多次,但是在broker端只會寫入一次,他為每一條消息編號去重,而且對kafka開銷影響不大

如何設置開啟呢? 需要設置producer端的新參數 enable.idempotent 為true。

而多分區的情況,我們需要保證原子性的寫入多個分區,即寫入到多個分區的消息要麼全部成功,要麼全部回滾。

這時候就需要使用事務,在producer端設置 transcational.id,為一個指定字符串。

這樣冪等producer,只能保證單分區上無重複消息;事務可以保證多分區寫入消息的完整性。

冪等的producer

這樣producer端實現了exactly once,那麼consumer端呢?

consumer端,由於可能無法消費事務中所有消息,並且消息可能被刪除,所以事務並不能解決consumer端exactly once的問題,我們可能還是需要自己處理這方面的邏輯。比如自己管理offset的提交不要自動提交,也是可以實現exactly once的。

Kafka Streams

還有一個選擇就是使用kafka自己的流處理引擎,也就是Kafka Streams,設置processing.guarantee=exactly_once,就可以輕鬆實現exactly once了。

相關焦點

  • kafka極簡教程
    Apache kafka是消息中間件的一種,我發現很多人不知道消息中間件是什麼,在開始學習之前,我這邊就先簡單的解釋一下什麼是消息中間件,只是粗略的講解,目前kafka已經可以做更多的事情。再比如生產者很強勁(大交易量的情況),生產者1秒鐘生產100個雞蛋,消費者1秒鐘只能吃50個雞蛋,那要不了一會,消費者就吃不消了(消息堵塞,最終導致系統超時),消費者拒絕再吃了,」雞蛋「又丟失了,這個時候我們放個籃子在它們中間,生產出來的雞蛋都放到籃子裡,消費者去籃子裡拿雞蛋,這樣雞蛋就不會丟失了,都在籃子裡,而這個籃子就是」kafka「。
  • 大白話+13張圖解 Kafka
    一、Kafka基礎消息系統的作用應該大部份小夥伴都清楚,用機油裝箱舉個例子所以消息系統就是如上圖我們所說的倉庫,能在中間過程作為緩存,並且實現解耦合的作用。kafka還有一個概念叫Partition(分區),分區具體在伺服器上面表現起初就是一個目錄,一個主題下面有多個分區,這些分區會存儲到不同的伺服器上面,或者說,其實就是在不同的主機上建了不同的目錄。
  • kafka入門(原理-搭建-簡單使用)
    前言公司在用kafka接受和發送數據,自己學習過Rabbitmq,不懂kafka挺不爽的,說幹就幹!網上找了許多帖子,學習了很多,小小的demo自己也搭建起來了,美滋滋,下面我認為優秀的網站和自己的步驟展現給大家。
  • 不了解Kafka的acks配置,怎麼能說你會Kafka?
    Kafka生產者有很多可以配置的參數,這些在kafka的說明文檔中已經有詳細的說明,它們大部分都有合理的默認值,一般情況下,我們不需要修改。不過有些參數在內存使用、性能和可靠性方面對生產者的影響比較大,今天就重點來講講acks參數對消息可靠性的影響。
  • kafka使用原理介紹
    但是當kafka的讀寫流量都非常巨大的時候,TalkingData的一個bug是,由於網絡等原因,kafka controller和Zookeeper有6s中沒有通信,於是重新選舉出了一個新的kafka controller,但是原來的controller在shut down的時候總是不成功,這個時候producer進來的message由於Kafka集群中存在兩個kafka controller而無法落地
  • Apache Kafka 快速入門指南
    寫博客一方面是對自己學習的一點點總結及記錄,另一方面則是希望能夠幫助更多對大數據感興趣的朋友。如果你也對 數據中臺以及 Hadoop / Flink / Spark 等大數據技術感興趣,可以關注我的博客, 每天都要進步一點點,生命不是要超越別人,而是要超越自己!(ง •_•)ง❞一、Kafka 是什麼?
  • Kafka官方文檔翻譯-最新版v2.7(三)
    每條消息由一個64位整數偏移量唯一標識,給出該消息在該分區上所有發送到該主題的消息流中開始的字節位置。每條消息的磁碟格式如下。每個日誌文件都以它所包含的第一條消息的偏移量命名。所以創建的第一個文件將是000000000.kafka,每一個額外的文件將有一個整數名,大約是前一個文件的S字節,其中S是配置中給出的最大日誌文件大小。
  • 從未如此簡單:10分鐘帶你逆襲Kafka!
    ③擴展性:因為消息隊列解耦了你的處理過程,所以增大消息入隊和處理的頻率是很容易的,只要另外增加處理過程即可。不需要改變代碼、不需要調節參數。擴展就像調大電力按鈕一樣簡單。實驗表明:入隊時,當數據比較小時 Redis 的性能要高於 RabbitMQ,而如果數據大小超過了 10K,Redis 則慢的無法忍受;出隊時,無論數據大小,Redis 都表現出非常好的性能,而 RabbitMQ 的出隊性能則遠低於 Redis。③ZeroMQ:ZeroMQ 號稱最快的消息隊列系統,尤其針對大吞吐量的需求場景。
  • Kafka【入門】就這一篇!
    討論一:Kafka 存儲在文件系統上是的,您首先應該知道 Kafka 的消息是存在於文件系統之上的。Kafka 高度依賴文件系統來存儲和緩存消息,一般的人認為 「磁碟是緩慢的」,所以對這樣的設計持有懷疑態度。實際上,磁碟比人們預想的快很多也慢很多,這取決於它們如何被使用;一個好的磁碟結構設計可以使之跟網絡速度一樣快。
  • kafka異步雙活方案 mirror maker2深度解析
    mirror maker2背景通常情況下,我們都是使用一套kafka集群處理業務。但有些情況需要使用另一套kafka集群來進行數據同步和備份。在kafka早先版本的時候,kafka針對這種場景就有推出一個叫mirror maker的工具(mirror maker1,以下mm1即代表mirror maker1),用來同步兩個kafka集群的數據。
  • CentOS7下簡單搭建zookeeper+kafka集群
    root@node2ssh-copy-id root@node3如果有必要的話,三臺機器間兩兩互信3、提前下載JDK,zookeeper,kakfa的相關安裝包,並上傳到/opt目錄如下圖所示scp /opt/* root@node2:/optscp /opt/* root@node3:/opt二、每臺機器都安裝
  • Kafka 基本原理(8000 字小結)
    消費者(Consumer):可以訂閱一個或多個話題,並從Broker拉數據,從而消費這些已發布的消息。1)kafka以topic來進行消息管理,每個topic包含多個partition,每個partition對應一個邏輯log,有多個segment組成。
  • flink-1.12.0 upsert-kafka connector demo
    https://ci.apache.org/projects/flink/flink-docs-release-1.12/zh/dev/table/connectors/upsert-kafka.html Flink 1.12.0 已經發布了有一段時間了, 這段時間都比較忙,很少嘗試新版本的功能,之前升級,只是修改了 flink 的版本號,把一些報錯、不適用的代碼從項目中移除
  • Kafka常見錯誤整理(不斷更新中)
    :分區數據不在原因分析:producer向不存在的topic發送消息,用戶可以檢查topic是否存在 或者設置auto.create.topics.enable參數2、LEADER_NOT_AVAILABLEWARN Errorwhile fetching metadata with
  • 利用flume+kafka+storm+mysql構建大數據實時系統
    數據流向圖KafkaKafka是一個消息中間件,它的特點是:1、關注大吞吐量,而不是別的特性2、針對實時性場景3、關於消息被處理的狀態是在consumer端維護,而不是由kafka server端維護。4、分布式,producer、broker和consumer都分布於多臺機器上。
  • 圖解SparkStreaming與Kafka的整合,細節滿滿
    首先我們要知道為什麼會有SparkStreaming與Kafka的整合,任何事情的出現都不是無緣無故的!我們要知道Spark作為實時計算框架,它僅僅涉及到計算,並沒有涉及到數據的存儲,所以我們後期需要使用spark對接外部的數據源。
  • Flink保證端到端exactly-once語義(也適用於kafka)
    後面我們會flink是如何與外部系統進行二次提交協議來保證語義的 使用flink來保證端到端的數據不丟失不重複 下面我們來看看flink消費並寫入kafka的例子是如何通過兩部提交來保證exactly-once語義的。kafka從0.11開始支持事物操作,若要使用flink端到端exactly-once語義需要flink的sink的kafka是0.11版本以上的。
  • Flume+Kafka+Storm+Redis構建大數據實時處理系統
    在我們的場景中,兩個Flume Agent分別部署在兩臺Web伺服器上,用來採集Web伺服器上的日誌數據,然後其數據的下沉方式都為發送到另外一個Flume Agent上,所以這裡我們需要配置三個Flume Agent。
  • Logstash讀取Kafka數據寫入HDFS詳解
    /bin/logstash-plugin install logstash-output-webhdfs配置hostsHDFS集群內通過主機名進行通信所以logstash所在的主機需要配置hadoop集群的hosts信息192.168.107.154 master01192.168.107.155 slave01192.168.107.156
  • Kafka快速入門秘籍:背景介紹,應用場景分析、核心架構分析
    下篇文章或者視頻,我們將帶你看官網學習kafka環境搭建、kafka基本用法、kafka的容錯性測試,在掌握知識的同時,還能順便學習下英文。1)問題引入:假設我們現在需要設計這樣一個用戶註冊系統:用戶註冊完成後,需要給用戶發送激活郵件,開通用戶帳號,記錄用戶IP、用戶設備、時間等信息。起初的設計: