標籤:負載 ref 時間 orb ntc 相同 html name scribe
前言
最新項目中要用到訊息佇列來做訊息的傳輸,之所以選著 Kafka 是因為要配合其他 java 項目中,所以就對 Kafka 瞭解了一下,也算是做個筆記吧。
本篇不談論 Kafka 和其他的一些訊息佇列的區別,包括效能及其使用方式。
簡介
Kafka 是一個實現了分布式的、具有分區、以及複製的日誌的一個服務。它通過一套獨特的設計提供了訊息系統中介軟體的功能。它是一種發布訂閱功能的訊息系統。
一些名詞
如果要使用 Kafka ,那麼在 Kafka 中有一些名詞需要知道,文本不討論這些名詞是否在其他訊息佇列中具有相同的含義。所有名詞均是針對於 Kafka。
Message
訊息,就是要發送的內容,一般封裝成一個訊息對象。
Topic
通俗來講的話,就是放置“訊息”的地方,也就是說訊息投遞的一個容器。假如把訊息看作是信封的話,那麼 Topic 就是一個郵筒,如所示:
Partition && Log
Partition 分區,可以理解為一個邏輯上的分區,像是我們電腦的磁碟 C:, D:, E: 盤一樣,
Kafka 為每個分區維護著一份日誌Log檔案。
每個分區是一個有序的,不可修改的,訊息組成的隊列。 當訊息過來的時候,會被追加到記錄檔中,這個追加是根據 commit 命令來執行的。
分區中的每一條訊息都有一個編號,叫做 offset id,這個 id 在當前分區中是唯一的,並且是遞增的。
日誌,就是用來記錄分區中接收到的訊息,因為每一個 Topic 可以同時向一個或者多個分區投遞訊息,所以實際在儲存日誌的時候,每個分區會對應一個日誌目錄,其命名規則一般為 <topic_name>-<partition_id>, 目錄中就是一個分區的一份 commit log 記錄檔。
Kafka 叢集會儲存一個時間段內所有被發布出來的資訊,無論這個訊息是否已經被消費過,這個時間段是可以配置的。比如日誌儲存時間段被設定為2天,那麼2天以內發布的訊息都是可以消費的;而之前的訊息為了釋放空間將會拋棄掉。Kafka的效能與資料量不相干,所以儲存大量的訊息資料不會造成效能問題。
對日誌進行分區主要是為了以下幾個目的:第一、這可以讓log的伸縮能力超過單台伺服器上線,每個獨立的partition的大小受限於單台伺服器的容積,但是一個topic可以有很多partition從而使得它有能力處理任意大小的資料。第二、在平行處理方面這可以作為一個獨立的單元。
生產者 Producers
和其他訊息佇列一樣,生產者通常都是訊息的產生方。
在 Kafka 中它決定訊息發送到指定Topic的哪個分區上。
消費者 Consumers
消費者就是訊息的使用者,在消費者端也有幾個名詞需要區分一下。
一般訊息佇列有兩種模式的消費方式,分別是 隊列模式 和 訂閱模式。
隊列模式:一對一,就是一個訊息只能被一個消費者消費,不能重複消費。一般情況隊列支援存在多個消費者,但是對於一個訊息,只會有一個消費者可以消費它。
訂閱模式:一對多,一個訊息可能被多次消費,訊息生產者將訊息發布到Topic中,只要是訂閱改Topic的消費者都可以消費。
Consumer && Subscriber
Group: 組,是一個消費者的集合,每一組都有一個或者多個消費者,Kafka 中在一個組內,訊息只能被消費一次。
在發布訂閱模式中,消費者是以組的方式進行訂閱的,就是Consumer Group,他們的關係如:
每個發布到Topic上的訊息都會被投遞到每個訂閱了此Topic的消費者組中的某一個消費者,也就是每個組都會被投遞,但是每個組都只會有一個消費者消費這個訊息。
開頭介紹了Kafka 是 發布-訂閱 功能的訊息佇列,所以在Kafka中,隊列模式是通過單個消費者組實現的,也就是整個結構中只有一個消費者組,消費者之間負載平衡。
Kafka 叢集
Borker: Kafka 叢集有多個伺服器組成,每個伺服器稱做一個 Broker。同一個Topic的訊息按照一定的key和演算法被分區儲存在不同的Broker上。
引用自:http://blog.csdn.net/lizhitao
因為 Kafka 的叢集它是通過將分區散布到各個Server的實現的,也就是說叢集中每個伺服器他們都是彼此共用分區的資料和請求,每個分區的記錄檔被複製成指定分數,分散在各個叢集機器,這樣來實現的容錯移轉。
對於每一個分區都會有一個伺服器作為它的 "leader" 並且有零個或者多個伺服器作為"followers" 。leader 伺服器負責處理關於這個 partition 所有的讀寫請求, followers 伺服器則被動的複製 leader 伺服器。如果有 leader 伺服器失效,那麼 followers 伺服器將有一台被自動選舉成為新的 leader 。每個伺服器作為某些 partition 的 leader 的同時也作為其它伺服器的 follower ,從而實現了叢集的負載平衡。
.NET Core Kafka 用戶端
在 .NET Core 中,有相對應的開源 kafka sdk 項目,就是 Rdkafka。它同時支援 .NET 4.5,並且支援跨平台,可以運行於Linux,macOS 和 Windows。
RdKafka Github :https://github.com/ah-/rdkafka-dotnet
RdKafka Nuget :Install-Package RdKafka
生產者 API
// Producer 接受一個或多個 BrokerListusing (Producer producer = new Producer("127.0.0.1:9092"))//發送到一個名為 testtopic 的Topic,如果沒有就會建立一個using (Topic topic = producer.Topic("testtopic")) { //將message轉為一個 byte[] byte[] data = Encoding.UTF8.GetBytes("Hello RdKafka"); DeliveryReport deliveryReport = await topic.Produce(data); Console.WriteLine($"發送到分區:{deliveryReport.Partition}, Offset 為: {deliveryReport.Offset}");}
消費者 API
由於 Kafka 是以消費者組的形式進行消費的,所以需要指定一個GroupId。
在內部實現上,消費者是通過一個輪詢機制來實現的對 Topic 訊息的監控,這也是Kafka推薦的方式,在 Rdkafka 中輪詢的間隔為 1 秒鐘。
//配置消費者組var config = new Config() { GroupId = "example-csharp-consumer" };using (var consumer = new EventConsumer(config, "127.0.0.1:9092")) { //註冊一個事件 consumer.OnMessage += (obj, msg) => { string text = Encoding.UTF8.GetString(msg.Payload, 0, msg.Payload.Length); Console.WriteLine($"Topic: {msg.Topic} Partition: {msg.Partition} Offset: {msg.Offset} {text}"); }; //訂閱一個或者多個Topic consumer.Subscribe(new[] { "testtopic" }); //啟動 consumer.Start(); Console.WriteLine("Started consumer, press enter to stop consuming"); Console.ReadLine();}
本文地址:http://www.cnblogs.com/savorboard/p/dotnetcore-kafka.html
作者部落格:Savorboard
歡迎轉載,請在明顯位置給出出處及連結
分類: .NET
Kafka及 .NET Core 用戶端