Kafka是分布式流平臺危虱。
一個流平臺有3個主要特征:
- 發(fā)布和訂閱消息流,這一點與傳統的消息隊列相似。
- 以容災持久化方式的消息流存儲镣煮。
- 在消息流發(fā)生時處理消息流。
Kafka通常使用在兩大類應用中:
- 在系統或應用之間鄙麦,構建實時典唇、可靠的消息流管道。
- 構建實時流應用程序胯府,用于轉換或響應數據流
Kafka的幾個基本概念:
- Kafka可以作為一個集群運行在跨越多個數據中心的多個服務上介衔。
- Kafka集群按照分類存儲的消息流叫做topic。
- 每一個消息由一個主鍵骂因、一個值炎咖、和一個時間戳組成。
Kafka有4個核心的API:
- Producer API允許應用向一個或多個topic發(fā)送信息流。
- Consumer API允許應用訂閱一個或多個topic并處理產生的信息流乘盼。
-
Streams API允許應用扮演一個流處理器升熊,從一個或多個topic消費輸入流,并向一個或多個topic生產輸出流绸栅。
實際上是轉換輸入流到輸出流级野。 - Connector API構建和運行連接Kafka的可復用的生產者或消費者,到已存在的應用或數據系統粹胯。例如:連接一個關系型數據庫捕獲表中的每一次變化蓖柔。
在Kafka中,客戶端和服務器之間的通信是通過一種簡單的风纠,高性能的渊抽,語言不可知的TCP協議完成的。
Topics 和 Logs
我們了解一下Kafka為消息流提供的核心抽象——topic议忽。
一個topic是一個消息發(fā)布時的分類懒闷。Kafka中的topic總是有0個、1個栈幸、或多個消費者訂閱寫入其中的數據愤估。
對于每一個topic,Kafka集群保存著分區(qū)日志:
每一個partition是一個有序的不可改變的消息隊列速址, 它可以持續(xù)的追加——結構化的提交日志玩焰。partitions中的每一個記錄都會分配
一個有序的id,這個id叫做偏移量——每一個partition中的一個消息的唯一標識符芍锚。
Kafka集群通過配置保留時間持久化所有發(fā)布的消息昔园,不管它是否被消費。例如:設置保留時間為2天并炮,一個消息發(fā)布后的2天內默刚,它可以被消費,超過2天逃魄,它將被丟棄以釋放空間荤西。
實際上,保存在每一個消費者基礎上的唯一元數據是偏移量(offset)或者說是日志中消費者的位置伍俘。偏移量(offset)時候被消費者控制的:
正常情況下邪锌,一個消費者在讀取數據時,線性增加它的偏移量癌瘾,但實際上觅丰,消費者控制位置,它可以按照任何順序處理和消費消息妨退。例如:消費者可以重置一個老的偏移量妇萄,重新
處理過去的數據蜕企,也可以跳到最新的數據,從“現在時刻”起嚣伐,消費數據糖赔。
這些特性意味著消費者是十分廉價的萍丐,他們可以來去自如轩端,不會和集群中的其他消費者沖突。例如:你可以到任何topic的消息末尾逝变,而不影響正在消費這個topic的其他消費者基茵。
日志中的partitions服務著幾個目的:首先,它們允許日志的大小超出適合單個服務器的大小壳影。每一個單獨的partition必須適合于自己的服務器拱层。但是一個topic可以有許多個partition
,所以它可以處理任意數量規(guī)模的數據宴咧。其次它扮演著平行的單位根灯。
分布式
日志的partitions分布在Kafka集群中的服務上,每一個服務處理partitions中的一份掺栅。每一個partition可以通過配置服務的數量進行復制烙肺,以達到容災的目的。
每一個partition都有一個服務扮演著"leader"的角色氧卧,0個或多個服務扮演著"followers"的角色桃笙。"leader"處理partition所有的讀寫請求,"followers"通過"leader"進行數據備份沙绝。
如果"leader"失敗了搏明,"followers"中的一個會自動變成"leader"。
異地同步
Kafka的MirrorMaker為集群提供異地同步支持闪檬,使用MirrorMaker星著,消息可以跨越多個數據中心或云區(qū)域進行復制。你可以用主-被模式進行數復制和恢復粗悯,也可以用主-主模式
把數據置于離用戶更新的地方强饮。
生產者
生產者發(fā)布數據到他們選擇的topic,生產者負責選擇哪一個消息分配到topic中的哪一個partition为黎。它可以通過輪詢的方式簡單的實現負載均衡邮丰,或者通過消息主鍵進行語義分區(qū)。
消費者
消費者用消費組名稱標志著他們自己铭乾。發(fā)布到topic的每一個消息都會傳送到每一個訂閱的消費組中的一個消費實例上剪廉。消費實例可以按照進程分割,也可以按照機器分割炕檩。
如果所有的消費實例在一個消費組下斗蒋,消息實際上是在消費實例上進行負載均衡捌斧。
如果所有的實例在不同的消費組下,每一個消息都會廣播到每一個消費實例泉沾。
兩個服務器Kafka集群托管四個分區(qū)(P0-P3)和兩個消費者組捞蚂。消費者組A有兩個消費者實例,而組B有四個消費者實例跷究。
通常情況下姓迅,我們發(fā)現topic都有一個小量的消費組,每一個“邏輯訂閱者”都有一個俊马。每一個消費組都由許多消費實例組成丁存,為了擴展和容災。
這僅僅在生產-訂閱語義上柴我,訂閱者由一個消費集群代替了單一的進程解寝。
Kafka消費的實現方式是通過消費實例分割日志中的partition,所以艘儒,在任何時間點聋伦,每一個實例都是partition合理份額中的專一消費者。
組內保持關系的進程被Kafka協議動態(tài)的處理界睁。如果一個新的實例加入了組觉增,它會從組內的其他成員分配一些partition。如果一個實例死掉了晕窑, partitions會分配到剩余的實例中抑片。
Kafka僅提供partition內的消息排序,不是topic內不同partition之間的杨赤。按分區(qū)排序與按鍵分區(qū)數據的能力相結合敞斋,足以滿足大多數應用程序的需求〖采可是植捎,
如果你需要消息的整體排序,它可以用一個topic只有一個partition來完成阳柔,這意味著一個消費組中焰枢,只有一個消費實例處理數據。
多租戶
你可以用多租戶方案部署Kafka集群舌剂。多租戶可以通過配置啟用哪些topic可以生產或消費數據济锄。還有配額操作的支持。管理員可以根據請求定義和執(zhí)行配額以控制客戶端使用的代理資源霍转。
擔保
作為高級別的Kafka荐绝,給出了一下的擔保:
- 被發(fā)送到topic partition的消息會按照他們發(fā)送的順序追加。如果M1被相同的生產者作為M2發(fā)送避消,M1先發(fā)送低滩,M1有一個較低的offset召夹,并且在日志中先與M2出現。
- 消費者按照日志中的順序發(fā)現消息恕沫。
- 對于具有復制因子N的主題监憎,我們將容忍多達N-1個服務器故障,而不會丟失任何提交給日志的記錄婶溯。
Kafka作為消息系統
Kafka的流概念與傳統企業(yè)消息系統如何比較鲸阔?
傳統的消息有連個模型:隊列和發(fā)布-訂閱。在隊列中爬虱,每一個消息會分配到消費者中的一個隶债,在發(fā)布-訂閱模式下腾它,每一個消息會廣播到所有的消費者跑筝。
這兩者中的每一個都有優(yōu)點和缺點。隊列的優(yōu)點是可以通過多個消費者實例分割數據的處理瞒滴,這可以擴展你的處理進程曲梗。不幸的是,隊列不能有多個訂閱者妓忍,一旦一個進程
讀取了數據虏两,它就消失了。發(fā)布-訂閱允許你廣播數據到多個進程世剖,消息去了每一個消費者定罢,你沒有方式去擴展它。
Kafka消費組的概念整合了這兩個概念旁瘫。作為隊列祖凫,消費組可以通過進程集合(消費組中的成員)分割處理。作為發(fā)布-訂閱酬凳,Kafka允許你發(fā)布消息到所有的消費組惠况。
Kafka模型的優(yōu)點是每一個topic都有這兩個屬性,它可以擴展處理和有多個訂閱者宁仔,不需要選擇其中的一種稠屠。
Kafka比傳統的消息系統有更強的排序保障。
傳統的隊列在服務端保存消息的順序翎苫,如果多個消費者從隊列中消費數據权埠,服務按照存儲的順序分發(fā)消息〖宓可是攘蔽,雖然服務按照順序分發(fā)數據,數據時異步的傳遞給消費者粱快,
所以他們到達不同的消費者時是不能保證順序的秩彤。這實際上意味著消息的順序在平行消費面前是丟失的叔扼。消息系統為了解決這樣的問題,通常有一個“專用消費者”的概念漫雷,
它只允許一個消費者從隊列消費數據瓜富,這意味著沒有平行處理。
Kafka可以更好的解決這個問題降盹。通過有一個在topic內的平行partition的概念与柑,Kafka既可以提供消息順序的保障,又可以通過消費處理池進行負載均衡蓄坏。
這是通過將topic中的partition分配給消費組中的消費者來實現的价捧,以便每一個分區(qū)被組中的一個確定的消費者消費。通過這樣做涡戳,我們確保了一個消費者
是partition的唯一讀取者结蟋,并按照順序消費數據。由于有多個partition渔彰,仍然可以通過多個消費者均衡負載嵌屎。記住,組中消費者的數量不能大于partition的數量恍涂。
Kafka作為存儲系統
任何允許發(fā)布消息并解耦消費的消息隊列實際上都扮演著一個消息的存儲系統宝惰。卡夫卡的不同之處在于它是一個非常好的存儲系統再沧。
寫入Kafka的數據寫入磁盤并進行復制以實現容錯尼夺。Kafka允許生產者等待確認,以便寫入在完全復制之前不會被認為是完成的炒瘸,并且即使寫入的服務器失敗也能保證持續(xù)淤堵。
Kafka磁盤結構使用的規(guī)模很大 - 無論您在服務器上有50 KB還是50 TB的持久性數據,Kafka都會執(zhí)行相同的操作什燕。作為認真考慮存儲并允許客戶端控制其讀取位置的結果粘勒,您可以將Kafka視為一種專用于高性能,低延遲提交日志存儲屎即,復制和傳播的專用分布式文件系統庙睡。
Kafka作為流處理
僅讀取,寫入和存儲數據流是不夠的技俐,目標是啟用流的實時處理乘陪。
在Kafka中,流處理器是指從輸入主題獲取連續(xù)數據流雕擂,對該輸入執(zhí)行一些處理并生成連續(xù)數據流以輸出主題的任何內容啡邑。
例如,零售應用程序可能會接受銷售和裝運的輸入流井赌,并輸出一系列重新排序和對這些數據計算出的價格調整谤逼。
可以直接使用生產者API和消費者API進行簡單的處理贵扰。然而,對于更復雜的轉換流部,Kafka提供完全集成的Streams API戚绕。這允許構建應用程序進行非平凡的處理,從而計算聚合關閉流或將流連接在一起枝冀。
這個工具有助于解決這類應用程序面臨的難題:處理無序數據舞丛,重新處理代碼更改的輸入,執(zhí)行有狀態(tài)的計算等果漾。
流API基于Kafka提供的核心原語構建:它使用生產者API和消費者API輸入球切,使用Kafka進行有狀態(tài)存儲,并在流處理器實例之間使用相同的組機制來實現容錯绒障。