簡介
Apache Kafka由著名職業(yè)社交公司LinkedIn開發(fā)享幽,最初是被設(shè)計用來解決LinkedIn公司內(nèi)部海量日志傳輸?shù)葐栴}浇冰。Kafka使用Scala語言編寫仲吏,于2011年開源并進入Apache孵化器诅挑,2012年10月正式畢業(yè)返帕,現(xiàn)在為Apache頂級項目夫嗓。本文旨在使讀者對Kafka有一個較為基本和全面的認(rèn)識迟螺。
基本概念
Kafka是一個分布式數(shù)據(jù)流平臺,可以運行在單臺服務(wù)器上舍咖,也可以在多臺服務(wù)器上部署形成集群矩父。它提供了發(fā)布和訂閱功能,使用者可以發(fā)送數(shù)據(jù)到Kafka中排霉,也可以從Kafka中讀取數(shù)據(jù)(以便進行后續(xù)的處理)窍株。Kafka具有高吞吐、低延遲、高容錯等特點球订。下面介紹一下Kafka中常用的基本概念:
- Broker
消息隊列中常用的概念后裸,在Kafka中指部署了Kafka實例的服務(wù)器節(jié)點。 - Topic
用來區(qū)分不同類型信息的主題冒滩。比如應(yīng)用程序A訂閱了主題t1微驶,應(yīng)用程序B訂閱了主題t2而沒有訂閱t1,那么發(fā)送到主題t1中的數(shù)據(jù)將只能被應(yīng)用程序A讀到开睡,而不會被應(yīng)用程序B讀到因苹。 - Partition
每個topic可以有一個或多個partition(分區(qū))。分區(qū)是在物理層面上的篇恒,不同的分區(qū)對應(yīng)著不同的數(shù)據(jù)文件扶檐。Kafka使用分區(qū)支持物理上的并發(fā)寫入和讀取,從而大大提高了吞吐量胁艰。 - Record
實際寫入Kafka中并可以被讀取的消息記錄蘸秘。每個record包含了key、value和timestamp蝗茁。 - Producer
生產(chǎn)者醋虏,用來向Kafka中發(fā)送數(shù)據(jù)(record)。 - Consumer
消費者哮翘,用來讀取Kafka中的數(shù)據(jù)(record)颈嚼。 - Consumer Group
一個消費者組可以包含一個或多個消費者。使用多分區(qū)+多消費者方式可以極大提高數(shù)據(jù)下游的處理速度饭寺。
基本原理
Topic和數(shù)據(jù)日志
主題是同一類別的消息記錄(record)的集合阻课。在Kafka中,一個主題通常有多個訂閱者艰匙。對于每個主題限煞,Kafka集群維護了一個分區(qū)數(shù)據(jù)日志文件結(jié)構(gòu)如下:
每個partition都是一個有序并且不可變的消息記錄集合员凝。當(dāng)新的數(shù)據(jù)寫入時署驻,就被追加到partition的末尾。在每個partition中健霹,每條消息都會被分配一個順序的唯一標(biāo)識旺上,這個標(biāo)識被稱為offset,即偏移量糖埋。注意宣吱,Kafka只保證在同一個partition內(nèi)部消息是有序的,在不同partition之間瞳别,并不能保證消息有序征候。
Kafka可以配置一個保留期限杭攻,用來標(biāo)識日志會在Kafka集群內(nèi)保留多長時間。Kafka集群會保留在保留期限內(nèi)所有被發(fā)布的消息疤坝,不管這些消息是否被消費過兆解。比如保留期限設(shè)置為兩天,那么數(shù)據(jù)被發(fā)布到Kafka集群的兩天以內(nèi)卒煞,所有的這些數(shù)據(jù)都可以被消費。當(dāng)超過兩天叼架,這些數(shù)據(jù)將會被清空畔裕,以便為后續(xù)的數(shù)據(jù)騰出空間。由于Kafka會將數(shù)據(jù)進行持久化存儲(即寫入到硬盤上)乖订,所以保留的數(shù)據(jù)大小可以設(shè)置為一個比較大的值扮饶。
事實上乍构,在單個消費者層面上甜无,每個消費者保存的唯一的元數(shù)據(jù)就是它所消費的數(shù)據(jù)日志文件的偏移量。偏移量是由消費者來控制的哥遮,通常情況下岂丘,消費者會在讀取記錄時線性的提高其偏移量。不過由于偏移量是由消費者控制眠饮,所以消費者可以將偏移量設(shè)置到任何位置奥帘,比如設(shè)置到以前的位置對數(shù)據(jù)進行重復(fù)消費,或者設(shè)置到最新位置來跳過一些數(shù)據(jù)仪召。
容錯
每個topic的分區(qū)都可以分布在Kafka集群的不同服務(wù)器上寨蹋。比如topic A有partition 0,1,2,分別分布在Broker 1,2,3上面扔茅。每個服務(wù)器都可以處理分布在它上面的分區(qū)的寫入和讀取操作已旧。另外,每個分區(qū)也可以配置多個副本用來提高容錯性召娜。
每個partition有一個服務(wù)器充當(dāng)“l(fā)eader”运褪,零至多個服務(wù)器充當(dāng)“follower”。Leader會處理針對于這個分區(qū)的所有讀寫操作玖瘸,而follower只是被動的從leader中復(fù)制數(shù)據(jù)吐句。當(dāng)leader掛掉了,那么原有的follower會自動選舉出一個新的leader店读。每臺服務(wù)器都會作為一些分區(qū)的leader嗦枢,也會作為其他分區(qū)的follower,所以Kafka集群內(nèi)的負(fù)載會比較均衡屯断。
生產(chǎn)者
生產(chǎn)者可以將數(shù)據(jù)寫入到選定的主題文虏。生產(chǎn)者負(fù)責(zé)決定要將哪條記錄寫入到那個分區(qū)當(dāng)中侣诺。可以使用輪詢方式氧秘,即每次取一小段時間的數(shù)據(jù)寫入某個partition年鸳,下一小段的時間寫入下一個partition;也可以使用一些分區(qū)函數(shù)(比如哈希)丸相,根據(jù)record的key值將記錄寫入不同的分區(qū)搔确。
消費者
多個消費者實例可以組成一個消費者組,并用一個標(biāo)簽來標(biāo)識這個消費者組灭忠。一個消費者組中的不同消費者實例可以運行在不同的進程甚至不同的服務(wù)器上膳算。
如果所有的消費者實例都在同一個消費者組中,那么消息記錄會被很好的均衡的發(fā)送到每個消費者實例弛作。
如果所有的消費者實例都在不同的消費者組涕蜂,那么每一條消息記錄會被廣播到每一個消費者實例。
舉個例子机隙。如上圖所示,一個兩個節(jié)點的Kafka集群上擁有一個四個partition(P0-P3)的topic萨西。有兩個消費者組都在消費這個topic中的數(shù)據(jù)有鹿,消費者組A有兩個消費者實例,消費者組B有四個消費者實例谎脯。
從圖中我們可以看到印颤,在同一個消費者組中,每個消費者實例可以消費多個分區(qū)穿肄,但是每個分區(qū)最多只能被消費者組中的一個實例消費年局。也就是說,如果有一個4個分區(qū)的主題咸产,那么消費者組中最多只能有4個消費者實例去消費矢否,多出來的都不會被分配到分區(qū)。其實這也很好理解脑溢,如果允許兩個消費者實例同時消費同一個分區(qū)姜盈,那么就無法記錄這個分區(qū)被這個消費者組消費的offset了毅糟。如果在消費者組中動態(tài)的上線或下線消費者,那么Kafka集群會自動調(diào)整分區(qū)與消費者實例間的對應(yīng)關(guān)系。
使用場景
上面介紹了Kafka的一些基本概念和原理熙兔,那么Kafka可以做什么呢聪富?目前主流使用場景基本如下:
消息隊列(MQ)
在系統(tǒng)架構(gòu)設(shè)計中肝谭,經(jīng)常會使用消息隊列(Message Queue)——MQ纺铭。MQ是一種跨進程的通信機制,用于上下游的消息傳遞搏恤,使用MQ可以使上下游解耦违寿,消息發(fā)送上游只需要依賴MQ湃交,邏輯上和物理上都不需要依賴其他下游服務(wù)。MQ的常見使用場景如流量削峰藤巢、數(shù)據(jù)驅(qū)動的任務(wù)依賴等等搞莺。在MQ領(lǐng)域,除了Kafka外還有傳統(tǒng)的消息隊列如ActiveMQ和RabbitMQ等掂咒。
追蹤網(wǎng)站活動
Kafka最出就是被設(shè)計用來進行網(wǎng)站活動(比如PV才沧、UV、搜索記錄等)的追蹤绍刮∥略玻可以將不同的活動放入不同的主題,供后續(xù)的實時計算录淡、實時監(jiān)控等程序使用捌木,也可以將數(shù)據(jù)導(dǎo)入到數(shù)據(jù)倉庫中進行后續(xù)的離線處理和生成報表等油坝。
Metrics
Kafka經(jīng)常被用來傳輸監(jiān)控數(shù)據(jù)嫉戚。主要用來聚合分布式應(yīng)用程序的統(tǒng)計數(shù)據(jù),將數(shù)據(jù)集中后進行統(tǒng)一的分析和展示等澈圈。
日志聚合
很多人使用Kafka作為日志聚合的解決方案彬檀。日志聚合通常指將不同服務(wù)器上的日志收集起來并放入一個日志中心,比如一臺文件服務(wù)器或者HDFS中的一個目錄瞬女,供后續(xù)進行分析處理窍帝。相比于Flume和Scribe等日志聚合工具,Kafka具有更出色的性能诽偷。