Kafka日記(一)Kafka概念

由於工作需要研究Kafka,在網上搜索了許久,關於PHP+Kafka的使用偏向於過多重複華,在實際的使用中並沒有解決的我的問題。特此記錄,以供學習者少走彎路。

此篇摘自http://orchome.com,更多資料可以訪問查看。

一 Kafka入門

Kafka所使用的基本術語

Topi

Kafka將消息種子(Feed)分門別類,每一類的消息稱之爲一個主題(Topic).

Producer

發佈消息的對象稱之爲主題生產者(Kafka topic producer)

Consumer

訂閱消息並處理髮布的消息的種子的對象稱之爲主題消費者(consumers)

Broker

已發佈的消息保存在一組服務器中,稱之爲Kafka集羣。集羣中的每一個服務器都是一個代理(Broker). 消費者可以訂閱一個或多個主題(topic),並從Broker拉數據,從而消費這些已發佈的消息。

主題和日誌 (Topic和Log)

讓我們更深入的瞭解Kafka中的Topic。

Topic是發佈的消息的類別或者種子Feed名。對於每一個Topic,Kafka集羣維護這一個分區的log,就像下圖中的示例:

![img](file:///C:\Users\tech010\AppData\Local\Temp\ksohtml4600\wps4.jpg)

每一個分區都是一個順序的、不可變的消息隊列, 並且可以持續的添加。

分區中的消息都被分了一個序列號,稱之爲偏移量(offset),在每個分區中此偏移量都是唯一的。

Kafka集羣保持所有的消息,直到它們過期, 無論消息是否被消費了。

實際上消費者所持有的僅有的元數據就是這個偏移量,也就是消費者在這個log中的位置。 這個偏移量由消費者控制:正常情況當消費者消費消息的時候,偏移量也線性的的增加。但是實際偏移量由消費者控制,消費者可以將偏移量重置爲更老的一個偏移量,重新讀取消息。 可以看到這種設計對消費者來說操作自如, 一個消費者的操作不會影響其它消費者對此log的處理。

再說說分區。Kafka中採用分區的設計有幾個目的。

一是可以處理更多的消息,不受單臺服務器的限制。Topic擁有多個分區意味着它可以不受限的處理更多的數據。

第二,分區可以作爲並行處理的單元,稍後會談到這一點。
![img](file:///C:\Users\tech010\AppData\Local\Temp\ksohtml4600\wps5.jpg)

分佈式(Distribution)

Log的分區被分佈到集羣中的多個服務器上。每個服務器處理它分到的分區。 根據配置每個分區還可以複製到其它服務器作爲備份容錯。 每個分區有一個leader,零或多個follower。Leader處理此分區的所有的讀寫請求,而follower被動的複製數據。如果leader宕機,其它的一個follower會被推舉爲新的leader。 一臺服務器可能同時是一個分區的leader,另一個分區的follower。 這樣可以平衡負載,避免所有的請求都只讓一臺或者某幾臺服務器處理。

Geo-Replication(異地數據同步技術)

Kafka MirrorMaker爲羣集提供geo-replication支持。藉助MirrorMaker,消息可以跨多個數據中心或雲區域進行復制。 您可以在active/passive場景中用於備份和恢復; 或者在active/passive方案中將數據置於更接近用戶的位置,或數據本地化。

生產者(Producers)

生產者往某個Topic上發佈消息。生產者也負責選擇發佈到Topic上的哪一個分區。最簡單的方式從分區列表中輪流選擇。也可以根據某種算法依照權重選擇分區。開發者負責如何選擇分區的算法。

消費者(Consumers)

通常來講,消息模型可以分爲兩種, 隊列和發佈-訂閱式。

隊列的處理方式是 一組消費者從服務器讀取消息,一條消息只有其中的一個消費者來處理。在發佈-訂閱模型中,消息被廣播給所有的消費者,接收到消息的消費者都可以處理此消息。Kafka爲這兩種模型提供了單一的消費者抽象模型: 消費者組 (consumer group)。

消費者用一個消費者組名標記自己。 一個發佈在Topic上消息被分發給此消費者組中的一個消費者。 假如所有的消費者都在一個組中,那麼這就變成了queue模型。 假如所有的消費者都在不同的組中,那麼就完全變成了發佈-訂閱模型。 更通用的, 我們可以創建一些消費者組作爲邏輯上的訂閱者。每個組包含數目不等的消費者, 一個組內多個消費者可以用來擴展性能和容錯。正如下圖所示:
![img](file:///C:\Users\tech010\AppData\Local\Temp\ksohtml4600\wps6.jpg)2個kafka集羣託管4個分區(P0-P3),2個消費者組,消費組A有2個消費者實例,消費組B有4個。

正像傳統的消息系統一樣,Kafka保證消息的順序不變。 再詳細扯幾句。傳統的隊列模型保持消息,並且保證它們的先後順序不變。但是, 儘管服務器保證了消息的順序,消息還是異步的發送給各個消費者,消費者收到消息的先後順序不能保證了。這也意味着並行消費將不能保證消息的先後順序。用過傳統的消息系統的同學肯定清楚,消息的順序處理很讓人頭痛。如果只讓一個消費者處理消息,又違背了並行處理的初衷。 在這一點上Kafka做的更好,儘管並沒有完全解決上述問題。 Kafka採用了一種分而治之的策略:分區。 因爲Topic分區中消息只能由消費者組中的唯一一個消費者處理,所以消息肯定是按照先後順序進行處理的。但是它也僅僅是保證Topic的一個分區順序處理,不能保證跨分區的消息先後處理順序。 所以,如果你想要順序的處理Topic的所有消息,那就只提供一個分區。

Kafka的保證(Guarantees)

· 生產者發送到一個特定的Topic的分區上,消息將會按照它們發送的順序依次加入,也就是說,如果一個消息M1和M2使用相同的producer發送,M1先發送,那麼M1將比M2的offset低,並且優先的出現在日誌中。

· 消費者收到的消息也是此順序。

· 如果一個Topic配置了複製因子(replication factor)爲N, 那麼可以允許N-1服務器宕機而不丟失任何已經提交(committed)的消息。

· 有關這些保證的更多詳細信息,請參見文檔的設計部分。

kafka作爲一個消息系統

Kafka的流與傳統企業消息系統相比的概念如何?

傳統的消息有兩種模式:隊列和發佈訂閱。 在隊列模式中,消費者池從服務器讀取消息(每個消息只被其中一個讀取); 發佈訂閱模式:消息廣播給所有的消費者。這兩種模式都有優缺點,隊列的優點是允許多個消費者瓜分處理數據,這樣可以擴展處理。但是,隊列不像多個訂閱者,一旦消息者進程讀取後故障了,那麼消息就丟了。而發佈和訂閱允許你廣播數據到多個消費者,由於每個訂閱者都訂閱了消息,所以沒辦法縮放處理。

kafka中消費者組有兩個概念:

隊列:消費者組(consumer group)允許同名的消費者組成員瓜分處理。

發佈訂閱:允許你廣播消息給多個消費者組(不同名)。

kafka的每個topic都具有這兩種模式。

kafka有比傳統的消息系統更強的順序保證。

傳統的消息系統按順序保存數據,如果多個消費者從隊列消費,則服務器按存儲的順序發送消息,但是,儘管服務器按順序發送,消息異步傳遞到消費者,因此消息可能亂序到達消費者。這意味着消息存在並行消費的情況,順序就無法保證。消息系統常常通過僅設1個消費者來解決這個問題,但是這意味着沒用到並行處理。

kafka做的更好。通過並行topic的parition —— kafka提供了順序保證和負載均衡。每個partition僅由同一個消費者組中的一個消費者消費到。並確保消費者是該partition的唯一消費者,並按順序消費數據。每個topic有多個分區,則需要對多個消費者做負載均衡,但請注意,相同的消費者組中不能有比分區更多的消費者,否則多出的消費者一直處於空等待,不會收到消息。

kafka作爲一個存儲系統

所有發佈消息到消息隊列和消費分離的系統,實際上都充當了一個存儲系統(發佈的消息先存儲起來)。Kafka比別的系統的優勢是它是一個非常高性能的存儲系統。

寫入到kafka的數據將寫到磁盤並複製到集羣中保證容錯性。並允許生產者等待消息應答,直到消息完全寫入。

kafka的磁盤結構 - 無論你服務器上有50KB或50TB,執行是相同的。

client來控制讀取數據的位置。你還可以認爲kafka是一種專用於高性能,低延遲,提交日誌存儲,複製,和傳播特殊用途的分佈式文件系統。

kafka的流處理

僅僅讀,寫和存儲是不夠的,kafka的目標是實時的流處理。

在kafka中,流處理持續獲取輸入topic的數據,進行處理加工,然後寫入輸出topic。例如,一個零售APP,接收銷售和出貨的輸入流,統計數量或調整價格後輸出。

可以直接使用producer和consumer API進行簡單的處理。對於複雜的轉換,Kafka提供了更強大的Streams API。可構建聚合計算或連接流到一起的複雜應用程序。

助於解決此類應用面臨的硬性問題:處理無序的數據,代碼更改的再處理,執行狀態計算等。

Sterams API在Kafka中的核心:使用producer和consumer API作爲輸入,利用Kafka做狀態存儲,使用相同的組機制在stream處理器實例之間進行容錯保障。

拼在一起

消息傳遞,存儲和流處理的組合看似反常,但對於Kafka作爲流式處理平臺的作用至關重要。

像HDFS這樣的分佈式文件系統允許存儲靜態文件來進行批處理。這樣系統可以有效地存儲和處理來自過去的歷史數據。

傳統企業的消息系統允許在你訂閱之後處理未來的消息:在未來數據到達時處理它。

Kafka結合了這兩種能力,這種組合對於kafka作爲流處理應用和流數據管道平臺是至關重要的。

批處理以及消息驅動應用程序的流處理的概念:通過組合存儲和低延遲訂閱,流處理應用可以用相同的方式對待過去和未來的數據。它是一個單一的應用程序,它可以處理歷史的存儲數據,當它處理到最後一個消息時,它進入等待未來的數據到達,而不是結束。

同樣,對於流數據管道(pipeline),訂閱實時事件的組合使得可以將Kafka用於非常低延遲的管道;但是,可靠地存儲數據的能力使得它可以將其用於必須保證傳遞的關鍵數據,或與僅定期加載數據或長時間維護的離線系統集成在一起。流處理可以在數據到達時轉換它。

有關Kafka提供的保證,api和功能的更多信息,可繼續查閱本網。

Kafka的使用場景

下面是一些關於Apache kafka 流行的使用場景。這些領域的概述,可查看博客文章

消息

kafka更好的替換傳統的消息系統,消息系統被用於各種場景(解耦數據生產者,緩存未處理的消息,等),與大多數消息系統比較,kafka有更好的吞吐量,內置分區,副本和故障轉移,這有利於處理大規模的消息。

根據我們的經驗,消息往往用於較低的吞吐量,但需要低的端到端延遲,並需要提供強大的耐用性的保證。

在這一領域的kafka比得上傳統的消息系統,如的ActiveMQ或RabbitMQ的。

網站****活動追蹤

kafka原本的使用場景:用戶的活動追蹤,網站的活動(網頁遊覽,搜索或其他用戶的操作信息)發佈到不同的話題中心,這些消息可實時處理,實時監測,也可加載到Hadoop或離線處理數據倉庫。

每個用戶頁面視圖都會產生非常高的量。

指標

kafka也常常用於監測數據。分佈式應用程序生成的統計數據集中聚合。

日誌聚合

許多人使用Kafka作爲日誌聚合解決方案的替代品。日誌聚合通常從服務器中收集物理日誌文件,並將它們放在中央位置(可能是文件服務器或HDFS)進行處理。Kafka抽象出文件的細節,並將日誌或事件數據更清晰地抽象爲消息流。這允許更低延遲的處理並更容易支持多個數據源和分佈式數據消費。

流處理

kafka中消息處理一般包含多個階段。其中原始輸入數據是從kafka主題消費的,然後彙總,豐富,或者以其他的方式處理轉化爲新主題,例如,一個推薦新聞文章,文章內容可能從“articles”主題獲取;然後進一步處理內容,得到一個處理後的新內容,最後推薦給用戶。這種處理是基於單個主題的實時數據流。從0.10.0.0開始,輕量,但功能強大的流處理,就可以這樣進行數據處理了。

除了Kafka Streams,還有Apache Storm和Apache Samza可選擇。

事件採集

事件採集是一種應用程序的設計風格,其中狀態的變化根據時間的順序記錄下來,kafka支持這種非常大的存儲日誌數據的場景。

提交日誌

kafka可以作爲一種分佈式的外部日誌,可幫助節點之間複製數據,並作爲失敗的節點來恢復數據重新同步,kafka的日誌壓縮功能很好的支持這種用法,這種用法類似於Apacha BookKeeper項目。

1.Kafka適合用作數據存儲嗎,如果適合,那麼怎麼保證Consumer連接Kafka接收消息時對數據的不重複消費(就是當Consumer應用程序關閉後再打開消息重複接收了)。
2.Topic消息的生命週期最低可以配置多少?
3.那麼可以將每個Topic分別設置不同的有效時間嗎?例如Topic1的消息有效時間是5分鐘,Topic消息的有效時間是7天。

4.我將producer應用程序發送消息到Kafka完全設置爲異步非阻塞的,例如在C語言的producer接口中需要調用rd_kafka_flush()來等待完成producer請求,若果不等待,這樣是不是會有丟數據的風險?
5.另外Kafka方面怎麼保證數據完全接收到producer消息呢,是不是每發1條(或若干條)然後對producer進行確認?

解答:

1、比如默認保留7天消息,如果你磁盤夠大,你保留1年都可以,不重複消費是你自己配置的。比如auto.offset.reset= latest,就不會重複了,當你需要重新消費之前的數據,改成earliest就可以了。
2、topic消息的生活週期同上,看你保留多久。
3、消息是沒有狀態的,也就是說沒有有效時間,默認保留7天。但是你不能把保留時間設置5分鐘吧。那你還是用rabbitMQ做吧。kafka不合適。

4.5.c語言沒用過額,抱歉,但是默認kafka的客戶端發送是批量發送的,也就是說,消息並沒有馬上發送到kafka,而是先保留在緩存中,進行批量準備,然後發送,這也是kafka高效的原因之一,所以你要等待。
默認kafka異步發送可以通過異步回調通知來確保消息是否成功發送,c語言客戶端不知道有沒有提供,你可以關注下c語言版本的客戶端。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章