Kafka學習筆記-- 1 入門知識和使用場景

目錄

 

1 Kafka入門

1.1 主流mq框架對比

1.2 kafka主要特性

1.3 AMQP協議

1.4 Kafka整體架構

1.5 核心概念

broker

topic

partition

record

replication

1.6 kafaka  核心API

概述

producer

consumer

3 consumer的commit offset

4 consumer的數據獲取方式

2 kafka使用場景

2.1 消息系統

2.2 存儲系統

2.3 日誌聚合

2.4 跟蹤網站活動(其實就是埋點)

2.5 流處理


1 Kafka入門

1.1 主流mq框架對比

主流mq組件對比
  ActiveMQ   RabbitMQ Kafka 
吞吐量 1w 1w 10w
支持的協議 OpenMessage, AMQP, MQTT, STOMP AMQP 仿AMQP
事務 支持 支持 支持
集羣 支持(不良好) 支持(不良好) 支持
負載均衡 支持 支持 支持
動態擴展 不支持 不支持 支持
編寫語言 Java Erlang Scala

這三個MQ組件中, ActiveMQ的功能最豐富, 支持的協議最多。 吞吐量上, 一般情況下Kafka > RabbitMQ > ActiveMQ; 可靠性上, 一般情況下RabbitMQ > ActiveMQ > Kafka。

動態擴展, 是指可以向運行中的集羣添加新的節點, 而不影響已有節點的使用。 之所以說ActiveMQ對集羣的支持不良好, 其中一個原因是 ActiveMQ的節點只能是主從模式, 只有再master節點上纔可以發佈和消費消息, 這樣的話對併發量的提升相對較弱。

1.2 kafka主要特性

消息系統: 可以發佈和訂閱消息, 類似於消息隊列或企業級消息系統。

存儲: 提供容錯的方式來存儲流數據。 存儲在kafka中的數據, 都會落到磁盤上, 只要不手動刪除, 將一直存在, 不像其他消息中間件, 當消息消費後, 會對消息進行刪除。

流處理: 可以在一個流的數據產生時, 就對它進行處理, 即流處理。這個特性是kafka的streams api來支持的,需要在客戶端上編碼, 實質上是讀取現有的流數據, 將處理的結果推到結果的流上。 但主流的還是採用fink, storm sreams, spark等批處理框架來進行流處理。 kafka更多的是充當一個流數據的存儲角色。

總的來說, Kafka不僅僅是一個消息系統, 還是一個數據存儲。

 

1.3 AMQP協議

AMQP是由金融業的摩根大通公司主導制定的消息協議, 是一個應用層的協議。 

AMQP簡單示例

在Kafka中, 生產者push,消費者poll,都是客戶端主動發起數據請求。kafka都是以多個broker集羣的方式對外提供服務。

1.4 Kafka整體架構

1.5 核心概念

broker

一個Kafka示例, 一般情況下, Kafka都是以集羣的方式部署的。

topic

消息的一種分類, 一個主題的消息可以視爲一個數據流。主題中的消息不一定按照發布的順序消費。

partition

一個主題可以分爲多個partition,每一個partition都是順序存儲在磁盤的。 每個partition的消息有自己的id,  對於消費者, partion有自己對應的commit offset。partition的意義: 其一, 如果通過將一個主題分隔成多個partition, 部署到多個broker上來提升io的速度, 甚至通過這種方式, 獲得和內存相近的吞吐量; 其二, partition可以分佈在多個broker上, 可以避免一次性丟失所有數據的情況。

partition中的消息是會按照發布的順序消費的。 

record

每條記錄都有key, value和timestamp三個數據。 其中具有相同key的消息, 可以保證落到同一個partition中。 

replication

每一個partition可以有多個副本, 副本分佈在不同的broker上, 通過這種冗餘, 可以保證數據的安全性, 只要不是所有的副本都丟失, 那麼partition中的數據就是安全的。 副本的數量(replication-factor)不能超過broker的數量, 因爲將同樣的副本存在同一臺機器上, 對於數據安全性,沒有作用。 

replication

replication有一下的特性:

  • 同一個partition的多個replication不允許在同一個broker中;(在配置中, replication-factor不能超過broker的數量)
  • 同一個parition的多個replication中, 有一個leader, 0個或多個follower;
  • 消息的讀寫只能發生在leader節點上, follower只是被動的複製;
  • 當leader節點宕機時, 集羣會選舉出新的leader節點;

 

注意: 這裏的leader和follower是replication級別的, Kafka的broker節點之間沒有主次之分, 它們是完全同等的。 

 

1.6 kafaka  核心API

概述

  • producer, 向topic發佈消息的應用。
  • consumer, 從broker中接收消息, 進行處理的應用。
  • streams api, 一個流處理的api, 從一個或多個主題接收消息,進行處理後, 將處理結果放到一個或多個主題中。
  • connector, 可重用的producer或consumer。 用於將已有系統, 如數據庫等的數據集成到kafka上。 

這四種API, 用來構建四種類型的Kafka客戶端, 如下:

 

producer

使用代碼示例:

// 設置producer的配置
Properties settings = new Properties();
settings.put("batch.size", 16 * 1024); // 緩衝區大小, 默認16k
settings.put("linger.ms", 1000); // 發送前, 等待的時間, 默認爲0
settings.put("acks", "all"); // 多少個broker 確認才認爲成功。 0, 
settings.put("retries", 1 ); // 重試的次數

....

Producer<String, String> producer = new KafkaProducer(settings);
// 發送消息
ProducerRecord<String, String> record = new ProducerRecord<>("my-topic", "key", "value");
producer.send(record);

producer.close();

producer發送消息時, 並不是直接發送到broker中的, 而是先放在本地內存中的一個緩衝區,當緩衝區大小達到最大大小或緩衝區中的消息達到停留時間時, 才進行發送。 如下:

producer有三個重要的配置:

  • batch.size:  緩衝區大小, 默認16k
  • linger.ms: 發送前, 等待的時間, 默認爲0
  • acks: 多少個broker 確認才認爲消息發佈成功, 可選值爲0, 1, all。 0, 是發送之後就認爲是成功了, 不去考慮這個消息是否交付到kafka中; 1, 當leader節點確認成功, 就認爲已經成功的交付到kafka中了, 這種情況下, 如果leader節點宕機, 而又沒有來得即將消息同步到follower上, 那麼就會出現消息丟失; all, 只有當所有的broker都ack之後, 才認爲一個消息發送成功。 

一旦達到batch.size或linger.ms其中一個條件, 緩衝區的消息就會被立刻發送。 

 

consumer

1 simple consumer API

每次消費消息時, 都需要提供topic, partition, offset, feichSize等四個參數, 不提供負載均衡和容錯的特性。 

非常基礎, 但是基於可以定義實現所有的功能。 

2 high level consumer API

消費時只需要指定topic, 客戶端透明地切換consumer的partition, 實現consumer group級別的負載均衡。 如下圖:

 

consumer group有如下的特性:

  • 一個topic可以有多個consumer group,  每一個consumer group都可以接收到所有的topic中的數據。 
  • consumer group中可以有一個或多個consumer, 每個consumer處理主題中的一個或多個partition。 
  • 一個group中的一個partition只能被一個consumer處理。

 

可以通過consumer group來實現隊列和廣播:

  • 隊列: 當所有的消費者都在一個group中時, 那麼每個消息都只會被消費一次。
  • 廣播(主題): 當所有的消費者都分屬不同的消費者, 那麼每個消費者都會接收到topic中的所有消息。

 

consumer 什麼時候會退出group?

  • consumer在很長的一段時間內沒有心跳時;
  • 當consumer很久沒有poll數據時;


3 consumer的commit offset

consumer可以通過commit, 來告訴服務器, 當前已經消費了的消息, 當consumer因爲某種原因重啓時, 會從最新提交的offset的下一個消息開始消費。 默認的情況下, Consumer是自動提交的, 每當poll數據時, 就會提交上一條數據。 

除了這個存在kafka的commit offset, 還有一個consumer自己持有的offset, 來指向下一個消息。

 

4 consumer的數據獲取方式

kafka中,消費者是隻能通過主動poll的方式來獲取數據的。 

push和poll兩種方式的難點:

  • push, 難點是請求的壓力可能落到consumer上: 消息隊列可能無法起到緩衝區的作用, 無法進行削峯(這是在消息中間件服務端完全不做控制的情況);
  • poll, 難點是poll時間間隔的取捨, 隔一段時間去獲取一次數據, 這個時間的間隔如果太短, 服務器的壓力就會比較大, 如果過小, 那麼數據就不夠實時;

poll時間間隔的解決方案--- long polling:

consumer poll數據時, 如果當前數據不夠, 那麼這個poll請求會阻塞, 等待有足夠多的數據或者到達等待時間時才返回。 

2 kafka使用場景

2.1 消息系統

原因: 高可用; 根據經驗, 通常對消息傳遞對吞吐量的要求比較低, 但是要求較低的端到端延遲, 並且要有可靠的durable機制(kafka是一個持久化的消息隊列);高吞吐量;

 

對於消息順序的保證, 從某種角度來說, kafka會比較好。因爲即使是RabbitMQ和ActiveMQ, 當有多個消費者進行消費時, 其實我們沒有辦法保證哪個消費者先消費完, 其實順序也會丟失。 

kafka實現順序消費的方法:

  • 使用相同的key, 讓消息只發送到一個partition中, 而一個partition只會被消費者組內的一個消費者所使用;
  • topic內只有一個消費者;

 

2.2 存儲系統

高性能, 低延遲, 高可用的日誌提交存儲。 

 

2.3 日誌聚合

日誌處理的流程: 收集, 清洗(一般是使用正則來清洗), 聚合,存儲, 展示

可能不能作爲一個完全的日誌解決方案, ELK的日誌解決方案更加有優勢。 (ELK的缺點: 聚合節點Logstash可能會成爲系統瓶頸)

 

爲什麼要進行日誌的聚合?

如果是分佈式系統, 那麼一個程序的多個實例的日誌需要進行聚合。 一個請求在上下游的日誌也需要聚合。 

 

2.4 跟蹤網站活動(其實就是埋點)

kafka在LinkedIn中就因此而生。

 

2.5 流處理

Kafka StreamAPIs 可以進行流處理, 但是如果要使用複雜的流處理功能, 還是使用flink, spark streaming等框架。 

爲什麼需要流處理?

和流處理相對的是批處理, 批處理有很大的延遲, 比如說前一天去跑一些統計數據。 而流處理, 是一有新的數據就馬上計算更新結果的處理方式。 

 

 

 

 

 

 

 

 

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