kafka原理解析

什麼是消息系統:
用來處理消息隊列的系統;
什麼是消息隊列:
是用於進程間通信或同一進程內的線程間通信的軟件工程組件;
他們使用一個隊列來傳播消息----這裏傳播的消息就是-->傳遞控制或者內容;

這裏面有個問題:
消息隊列是用來提高性能,加速消息傳輸的嗎?
答案,顯然不是,消息隊列雖然提供了數據上的冗餘,但它不是一種緩存。
如果你想加速,直接把消費者和生產者結合在一起寫,中間自己加一個全內存的
queue,沒有了持久化,沒有了網絡傳輸,這樣豈不是更快;
消息隊列,最好的詮釋就是,“fire and forget”,英譯就是“解耦”,它實現了生產者與
消費者的有效解耦,降低了系統複雜性;
作爲一個生產者,它主要關心的應該就是自己的生產工作,它不應該關心自己生產的東西,到底
被誰消費,如何消費。它應該就是簡單的把生產好的東西,往一個倉庫一放(即fire),然後就可
以不管了(forget),毫無心理負擔。至於後面的事,消息如何交付給消費者,這種交付方式是不
是會丟失消息之類的可靠性問題一概不管(這也就是爲什麼消息隊列不僅是一箇中間結果存放區
的原因)。這個作爲中間倉庫,負責與消費者打交道,同時保證後續交付可靠性的角色,就是消
息隊列來擔當的。

kafka將消息以topic爲單位進行歸納;
將向kafka topic發佈消息的程序稱爲:producers;
將預訂topics並消費消息的程序稱爲consumer;
kafka以集羣的方式運行,可以由一個或多個服務組成,每個服務叫做一個broker;
producers通過網絡將消息發送到kafka集羣,集羣向消費者提供消息;

消息隊列的分類:

點對點的消息隊列queue:
一個消息只能被一個消費者消費,但是queue支持有多個消費者。
消息被消費後,queue中不再存儲,就是一個消息被消費後,其他消費者不能再消費。

發佈與訂閱的消息隊列topic:kafka
一個消息可以被多個消費者消費,實現消息共享;

爲什麼要搭建kafka:
活動數據的採集:
網站用戶相關行爲數據,如:PV,UV等
運營數據
監控核心系統性能指標

這些數據的特點:
數據不可變
數據量龐大
需實時處理

kafka是一個分佈式的消息系統(集羣):
負載均衡+失敗遷移

消息系統的基本結構:

broker是接收消息的機制;每臺消息服務器可以有多個broker,多臺服務器組成消息系統的分佈式集羣;
zookeeper作爲協調者,broker註冊到zookeeper上,zookeeper同步信息給其他broker;
kafka使用zookeeper存儲消息的元信息;

基本概念:
1.topic:特製kafka處理的消息源,代表kafka中的消息;
2.partition(分區):topic消息物理上的分組;一個topic可以有多個partition,每個partition是一個有序的隊列,partition每一個消息都會被分配給有序的id;
3.message:指的是具體的消息,是通信的基本單位,每個生產者可以向topic發送主題;
4.producer:生產者,向kafka的一個topic發佈消息的過程叫做生產;
5.consumer:消費者,訂閱topic並處理其發佈的消息的過程叫做消費;
6.broker:緩存代理,kafka集羣中的一臺或者多臺服務器,負責真正的接收消息和處理消息;

kafka的應用場景:
message(消息系統)
websit activity tracking(網站活性追蹤)
log aggregation(日誌收集中心)

首先, Partition對上層應用不透明. 用戶可以指定產生的消息pull到那個paritition.
topic之下分partition的原因負載均衡. 不考慮消息的順序, 單個Topic可以用多個Partition, leader均勻分散在全體broker上, 緩解單個broker過熱問題.
還有一個原因是, 每個.log文件(segment)對應的index文件中, offset爲32bit, 如果單個Partition的record數目超過4GB, 應該怎麼呢? 使用多Partition.
如果hdd大小是8TB, ssd大小爲1TB, 一個topic下產生的消息超過了磁盤大小,怎麼辦呢?
如果一個服務器配置24/36塊盤, 把topic分成partition, 粒度小一下, 單機磁盤的負載也會根據均衡.
如果一個topic數據, 太大, 必然有partitioning的需要.

可用的內存和分區數:Brokers會爲每個分區分配replica.fetch.max.bytes參數指定的內存空間,假設replica.fetch.max.bytes=1M,且有1000個分區,則需要差不多1G的內存,確保 分區數最大的消息不會超過服務器的內存,否則會報OOM錯誤。同樣地,消費端的fetch.message.max.bytes指定了最大消息需要的內存空間,同樣,分區數最大需要內存空間 不能超過服務器的內存。所以,如果你有大的消息要傳送,則在內存一定的情況下,只能使用較少的分區數或者使用更大內存的服務器。

1 什麼是消費者組
consumer group是kafka提供的可擴展且具有容錯性的消費者機制。既然是一個組,那麼組內必然可以有多個消費者或消費者實例(consumer instance),它們共享一個公共的ID,即group ID。組內的所有消費者協調在一起來消費訂閱主題(subscribed topics)的所有分區(partition)。當然,每個分區只能由同一個消費組內的一個consumer來消費。
consumer group組的三個特性:
● consumer group下可以有一個或多個consumer instance,consumer instance可以是一個進程,也可以是一個線程
● group.id是一個字符串,唯一標識一個consumer group
● consumer group下訂閱的topic下的每個分區只能分配給某個group下的一個consumer(當然該分區還可以被分配給其他group)
消費者位置(consumer position)
消費者在消費的過程中需要記錄自己消費了多少數據,即消費位置信息。在Kafka中這個位置信息有個專門的術語:位移(offset)。很多消息引擎都把這部分信息保存在服務器端(broker端)。這樣做的好處當然是實現簡單,但會有三個主要的問題:1. broker從此變成有狀態的,會影響伸縮性;2. 需要引入應答機制(acknowledgement)來確認消費成功。3. 由於要保存很多consumer的offset信息,必然引入複雜的數據結構,造成資源浪費。而Kafka選擇了不同的方式:每個consumer group保存自己的位移信息,那麼只需要簡單的一個整數表示位置就夠了;同時可以引入checkpoint機制定期持久化,簡化了應答機制的實現。
3 位移管理(offset management)
3.1 自動VS手動
Kafka默認是定期幫你自動提交位移的(enable.auto.commit = true),你當然可以選擇手動提交位移實現自己控制。另外kafka會定期把group消費情況保存起來,做成一個offset map,如下圖所示:

上圖中表明瞭test-group這個組當前的消費情況。

3.2 位移提交
老版本的位移是提交到zookeeper中的,圖就不畫了,總之目錄結構是:/consumers/<group.id>/offsets/<topic>/<partitionId>,但是zookeeper其實並不適合進行大批量的讀寫操作,尤其是寫操作。因此kafka提供了另一種解決方案:增加consumeroffsets topic,將offset信息寫入這個topic,擺脫對zookeeper的依賴(指保存offset這件事情)。consumer_offsets中的消息保存了每個consumer group某一時刻提交的offset信息。依然以上圖中的consumer group爲例,格式大概如下:

consumers_offsets topic配置了compact策略,使得它總是能夠保存最新的位移信息,既控制了該topic總體的日誌容量,也能實現保存最新offset的目的。compact的具體原理請參見:Log Compaction
至於每個group保存到__consumers_offsets的哪個分區,如何查看的問題請參見這篇文章:Kafka 如何讀取offset topic內容 (
consumer_offsets)

kafka的原理:
kafka的設計理念:
持久化
約束是吞吐量而不是功能
已經被使用了的狀態信息保存爲數據使用者的一部分,而不是保存在服務器上
分佈式系統

kafka在zookeeper的存儲結構:
kafka會在zookeeper存儲元信息,會有多個目錄,目錄結構如下:
consumer獲取消息是通過zookeeper處理髮送到broker,kafka集羣隨機分配請求道broker服務器上;

kafka的部署方式:
1.單Broker部署:一臺message server上部署一個broker服務;
2.單機多broker部署(僞分佈式):一臺message server上部署多個broker服務;
3.多機多broker部署(真正的分佈式):
多臺物理message server,每臺message server上部署一個或多個broker服務;
每個broker有個獨立的id,這個id在創建broker時進行定義;
broker id按順序排列;

單broker部署:

單機多broker部署:

jps命令查看kafka的broker信息;
kafka啓動報錯:UseCompressedOps,修改bin/kafka-run-class.sh,去掉此選項;

kafka的配置文件和demo演示:

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