轉(zhuǎn)自:https://www.cnblogs.com/qingyunzong/category/1212387.html
按照自己理解加粗了重點(diǎn)
一、前言,所謂消息隊(duì)列
一個(gè)消息系統(tǒng)負(fù)責(zé)將數(shù)據(jù)從一個(gè)應(yīng)用傳遞到另外一個(gè)應(yīng)用,應(yīng)用只需關(guān)注于數(shù)據(jù),無需關(guān)注數(shù)據(jù)在兩個(gè)或多個(gè)應(yīng)用間是如何傳遞的。
有兩種主要的消息傳遞模式:點(diǎn)對(duì)點(diǎn)傳遞模式、發(fā)布-訂閱模式。
點(diǎn)對(duì)點(diǎn)消息傳遞模式
在點(diǎn)對(duì)點(diǎn)消息系統(tǒng)中,消息持久化到一個(gè)隊(duì)列中。
此時(shí),將有一個(gè)或多個(gè)消費(fèi)者消費(fèi)隊(duì)列中的數(shù)據(jù)。
但是一條消息只能被消費(fèi)一次。
當(dāng)一個(gè)消費(fèi)者消費(fèi)了隊(duì)列中的某條數(shù)據(jù)之后,該條數(shù)據(jù)則從消息隊(duì)列中刪除。
生產(chǎn)者發(fā)送一條消息到queue,只有一個(gè)消費(fèi)者能收到。
該模式即使有多個(gè)消費(fèi)者同時(shí)消費(fèi)數(shù)據(jù),也能保證數(shù)據(jù)處理的順序。這種架構(gòu)描述示意圖如下:
發(fā)布-訂閱消息傳遞模式
在發(fā)布-訂閱消息系統(tǒng)中,消息被持久化到一個(gè)topic中。
與點(diǎn)對(duì)點(diǎn)消息系統(tǒng)不同的是,消費(fèi)者可以訂閱一個(gè)或多個(gè)topic,
消費(fèi)者可以消費(fèi)該topic中所有的數(shù)據(jù),同一條數(shù)據(jù)可以被多個(gè)消費(fèi)者消費(fèi),
數(shù)據(jù)被消費(fèi)后不會(huì)立馬刪除。
發(fā)布者發(fā)送到topic的消息,只有訂閱了topic的訂閱者才會(huì)收到消息。
在發(fā)布-訂閱消息系統(tǒng)中,消息的生產(chǎn)者稱為發(fā)布者,消費(fèi)者稱為訂閱者。該模式的示例圖如下:
二、消息隊(duì)列的優(yōu)點(diǎn)
-
解耦
在項(xiàng)目啟動(dòng)之初來預(yù)測(cè)將來項(xiàng)目會(huì)碰到什么需求,是極其困難的。
消息系統(tǒng)在處理過程中間插入了一個(gè)隱含的、基于數(shù)據(jù)的接口層,兩邊的處理過程都要實(shí)現(xiàn)這一接口。
這允許你獨(dú)立的擴(kuò)展或修改兩邊的處理過程,只要確保它們遵守同樣的接口約束。 -
冗余(副本)
有些情況下,處理數(shù)據(jù)的過程會(huì)失敗。除非數(shù)據(jù)被持久化,否則將造成丟失。
消息隊(duì)列把數(shù)據(jù)進(jìn)行持久化直到它們已經(jīng)被完全處理,通過這一方式規(guī)避了數(shù)據(jù)丟失風(fēng)險(xiǎn)。
許多消息隊(duì)列所采用的"插入-獲取-刪除"范式中,在把一個(gè)消息從隊(duì)列中刪除之前,
需要你的處理系統(tǒng)明確的指出該消息已經(jīng)被處理完畢,從而確保你的數(shù)據(jù)被安全的保存直到你使用完畢。 -
擴(kuò)展性
因?yàn)橄㈥?duì)列解耦了你的處理過程,所以增大消息入隊(duì)和處理的頻率是很容易的,
只要另外增加處理過程即可。
不需要改變代碼、不需要調(diào)節(jié)參數(shù)。擴(kuò)展就像調(diào)大電力按鈕一樣簡(jiǎn)單。 -
靈活性&峰值處理能力
在訪問量劇增的情況下,應(yīng)用仍然需要繼續(xù)發(fā)揮作用,但是這樣的突發(fā)流量并不常見;
如果為以能處理這類峰值訪問為標(biāo)準(zhǔn)來投入資源隨時(shí)待命無疑是巨大的浪費(fèi)。
使用消息隊(duì)列能夠使關(guān)鍵組件頂住突發(fā)的訪問壓力,而不會(huì)因?yàn)橥话l(fā)的超負(fù)荷的請(qǐng)求而完全崩潰。 -
可恢復(fù)性
系統(tǒng)的一部分組件失效時(shí),不會(huì)影響到整個(gè)系統(tǒng)。
消息隊(duì)列降低了進(jìn)程間的耦合度,
所以即使一個(gè)處理消息的進(jìn)程掛掉,加入隊(duì)列中的消息仍然可以在系統(tǒng)恢復(fù)后被處理。 -
順序保證
在大多使用場(chǎng)景下,數(shù)據(jù)處理的順序都很重要。
大部分消息隊(duì)列本來就是排序的,并且能保證數(shù)據(jù)會(huì)按照特定的順序來處理。
Kafka保證一個(gè)Partition內(nèi)的消息的有序性。 -
緩沖
在任何重要的系統(tǒng)中,都會(huì)有需要不同的處理時(shí)間的元素。
例如,加載一張圖片比應(yīng)用過濾器花費(fèi)更少的時(shí)間。
消息隊(duì)列通過一個(gè)緩沖層來幫助任務(wù)最高效率的執(zhí)行———寫入隊(duì)列的處理會(huì)盡可能的快速。
該緩沖有助于控制和優(yōu)化數(shù)據(jù)流經(jīng)過系統(tǒng)的速度。 -
異步通信
很多時(shí)候,用戶不想也不需要立即處理消息。
消息隊(duì)列提供了異步處理機(jī)制,允許用戶把一個(gè)消息放入隊(duì)列,但并不立即處理它。
想向隊(duì)列中放入多少消息就放多少,然后在需要的時(shí)候再去處理它們。
三、常用Message Queue對(duì)比
RabbitMQ
略
Redis
Redis是一個(gè)基于Key-Value對(duì)的NoSQL數(shù)據(jù)庫(kù),開發(fā)維護(hù)很活躍。
雖然它是一個(gè)Key-Value數(shù)據(jù)庫(kù)存儲(chǔ)系統(tǒng),但它本身支持MQ功能,所以完全可以當(dāng)做一個(gè)輕量級(jí)的隊(duì)列服務(wù)來使用。
對(duì)于RabbitMQ和Redis的入隊(duì)和出隊(duì)操作,各執(zhí)行100萬次,每10萬次記錄一次執(zhí)行時(shí)間。
測(cè)試數(shù)據(jù)分為128Bytes、512Bytes、1K和10K四個(gè)不同大小的數(shù)據(jù)。
實(shí)驗(yàn)表明:
入隊(duì)時(shí),當(dāng)數(shù)據(jù)比較小時(shí)Redis的性能要高于RabbitMQ,而如果數(shù)據(jù)大小超過了10K,Redis則慢的無法忍受;
出隊(duì)時(shí),無論數(shù)據(jù)大小,Redis都表現(xiàn)出非常好的性能,而RabbitMQ的出隊(duì)性能則遠(yuǎn)低于Redis。
ZeroMQ
略
ActiveMQ
ActiveMQ是Apache下的一個(gè)子項(xiàng)目。
類似于ZeroMQ,它能夠以代理人和點(diǎn)對(duì)點(diǎn)的技術(shù)實(shí)現(xiàn)隊(duì)列。
同時(shí)類似于RabbitMQ,它少量代碼就可以高效地實(shí)現(xiàn)高級(jí)應(yīng)用場(chǎng)景。
Kafka/Jafka
Kafka是Apache下的一個(gè)子項(xiàng)目,是一個(gè)高性能跨語言分布式發(fā)布/訂閱消息隊(duì)列系統(tǒng),而Jafka是在Kafka之上孵化而來的,即Kafka的一個(gè)升級(jí)版。
具有以下特性:
- 快速持久化,可以在O(1)的系統(tǒng)開銷下進(jìn)行消息持久化;
- 高吞吐,在一臺(tái)普通的服務(wù)器上既可以達(dá)到10W/s的吞吐速率;
- 完全的分布式系統(tǒng),Broker、Producer、Consumer都原生自動(dòng)支持分布式,自動(dòng)實(shí)現(xiàn)負(fù)載均衡;
- 支持Hadoop數(shù)據(jù)并行加載,對(duì)于像Hadoop的一樣的日志數(shù)據(jù)和離線分析系統(tǒng),但又要求實(shí)時(shí)處理的限制,這是一個(gè)可行的解決方案。Kafka通過Hadoop的并行加載機(jī)制統(tǒng)一了在線和離線的消息處理。
Apache Kafka相對(duì)于ActiveMQ是一個(gè)非常輕量級(jí)的消息系統(tǒng),除了性能非常好之外,還是一個(gè)工作良好的分布式系統(tǒng)。
四、Kafka中的術(shù)語解釋
在深入理解Kafka之前,先介紹一下Kafka中的術(shù)語。下圖展示了Kafka的相關(guān)術(shù)語以及之間的關(guān)系:
上圖中一個(gè)topic配置了3個(gè)partition。
Partition1有兩個(gè)offset:0和1。
Partition2有4個(gè)offset。
Partition3有1個(gè)offset。
副本的id和副本所在的機(jī)器的id恰好相同。
如果一個(gè)topic的副本數(shù)為3,那么Kafka將在集群中為每個(gè)partition創(chuàng)建3個(gè)相同的副本。
集群中的每個(gè)broker存儲(chǔ)一個(gè)或多個(gè)partition。多個(gè)producer和consumer可同時(shí)生產(chǎn)和消費(fèi)數(shù)據(jù)。
Broker
Kafka 集群包含一個(gè)或多個(gè)服務(wù)器,服務(wù)器節(jié)點(diǎn)稱為broker。
broker存儲(chǔ)topic的數(shù)據(jù)。
- 如果某topic有N個(gè)partition,集群有N個(gè)broker,那么每個(gè)broker存儲(chǔ)該topic的一個(gè)partition。
- 如果某topic有N個(gè)partition,集群有(N+M)個(gè)broker,那么其中有N個(gè)broker存儲(chǔ)該topic的一個(gè)partition,剩下的M個(gè)broker不存儲(chǔ)該topic的partition數(shù)據(jù)。
- 如果某topic有N個(gè)partition,集群中broker數(shù)目少于N個(gè),那么一個(gè)broker存儲(chǔ)該topic的一個(gè)或多個(gè)partition。在實(shí)際生產(chǎn)環(huán)境中,盡量避免這種情況的發(fā)生,這種情況容易導(dǎo)致Kafka集群數(shù)據(jù)不均衡。
Topic
每條發(fā)布到Kafka集群的消息都有一個(gè)類別,這個(gè)類別被稱為Topic。
(物理上不同Topic的消息分開存儲(chǔ),邏輯上一個(gè)Topic的消息雖然保存于一個(gè)或多個(gè)broker上,
但用戶只需指定消息的Topic即可生產(chǎn)或消費(fèi)數(shù)據(jù)而不必關(guān)心數(shù)據(jù)存于何處)
類似于數(shù)據(jù)庫(kù)的表名
Partition
topic中的數(shù)據(jù)分割為一個(gè)或多個(gè)partition。
每個(gè)topic至少有一個(gè)partition。
(多個(gè)partition的情況下,一條消息存儲(chǔ)在topic下的其中一個(gè)partition中)
每個(gè)partition中的數(shù)據(jù)使用多個(gè)segment文件存儲(chǔ)。
partition中的數(shù)據(jù)是有序的,不同partition間的數(shù)據(jù)丟失了數(shù)據(jù)的順序。
如果topic有多個(gè)partition,消費(fèi)數(shù)據(jù)時(shí)就不能保證數(shù)據(jù)的順序。
在需要嚴(yán)格保證消息的消費(fèi)順序的場(chǎng)景下,需要將partition數(shù)目設(shè)為1。
Producer
生產(chǎn)者即數(shù)據(jù)的發(fā)布者,該角色將消息發(fā)布到Kafka的topic中。
broker接收到生產(chǎn)者發(fā)送的消息后,broker將該消息追加到當(dāng)前用于追加數(shù)據(jù)的segment文件中。
生產(chǎn)者發(fā)送的消息,存儲(chǔ)到一個(gè)partition中,生產(chǎn)者也可以指定數(shù)據(jù)存儲(chǔ)的partition。
Consumer
消費(fèi)者可以從broker中讀取數(shù)據(jù)。消費(fèi)者可以消費(fèi)多個(gè)topic中的數(shù)據(jù)。
Consumer Group
每個(gè)Consumer屬于一個(gè)特定的Consumer Group
(可為每個(gè)Consumer指定group name,若不指定group name則屬于默認(rèn)的group)。
Leader
,其中有且僅有一個(gè)作為L(zhǎng)eader,
Leader是當(dāng)前負(fù)責(zé)數(shù)據(jù)的讀寫的partition。
Follower
Follower跟隨Leader,所有寫請(qǐng)求都通過Leader路由,
數(shù)據(jù)變更會(huì)廣播給所有Follower,F(xiàn)ollower與Leader保持?jǐn)?shù)據(jù)同步。
如果Leader失效,則從Follower中選舉出一個(gè)新的Leader。
當(dāng)Follower與Leader掛掉、卡住或者同步太慢,
leader會(huì)把這個(gè)follower從“in sync replicas”(ISR)列表中刪除,
重新創(chuàng)建一個(gè)Follower。
總結(jié)
五、Kafka的架構(gòu)
如上圖所示,
一個(gè)典型的Kafka集群中包含:
- 若干Producer(可以是web前端產(chǎn)生的Page View,或者是服務(wù)器日志,系統(tǒng)CPU、Memory等)
- 若干broker(Kafka支持水平擴(kuò)展,一般broker數(shù)量越多,集群吞吐率越高)
- 若干Consumer Group
- 一個(gè)Zookeeper集群
Kafka通過Zookeeper管理集群配置,選舉leader,以及在Consumer Group發(fā)生變化時(shí)進(jìn)行rebalance。
Producer使用push模式將消息發(fā)布到broker,
Consumer使用pull模式從broker訂閱并消費(fèi)消息。
六、Topics和Partition
Topic在邏輯上可以被認(rèn)為是一個(gè)queue,每條消費(fèi)都必須指定它的Topic,
可以簡(jiǎn)單理解為必須指明把這條消息放進(jìn)哪個(gè)queue里。
為了使得Kafka的吞吐率可以線性提高,物理上把Topic分成一個(gè)或多個(gè)Partition,
每個(gè)Partition在物理上對(duì)應(yīng)一個(gè)文件夾,該文件夾下存儲(chǔ)這個(gè)Partition的所有消息和索引文件。
創(chuàng)建一個(gè)topic時(shí),同時(shí)可以指定分區(qū)數(shù)目,分區(qū)數(shù)越多,其吞吐量也越大,
但是需要的資源也越多,同時(shí)也會(huì)導(dǎo)致更高的不可用性,
kafka在接收到生產(chǎn)者發(fā)送的消息之后,會(huì)根據(jù)均衡策略將消息存儲(chǔ)到不同的分區(qū)中。
因?yàn)槊織l消息都被append到該P(yáng)artition中,屬于順序?qū)懘疟P,因此效率非常高
(經(jīng)驗(yàn)證,順序?qū)懘疟P效率比隨機(jī)寫內(nèi)存還要高,這是Kafka高吞吐率的一個(gè)很重要的保證)。
- 對(duì)于傳統(tǒng)的message queue而言,一般會(huì)刪除已經(jīng)被消費(fèi)的消息,
- 而Kafka集群會(huì)保留所有的消息,無論其被消費(fèi)與否。
當(dāng)然,因?yàn)榇疟P限制,不可能永久保留所有數(shù)據(jù)(實(shí)際上也沒必要),
因此Kafka提供兩種策略刪除舊數(shù)據(jù)。
- 基于時(shí)間:例如可以通過配置$KAFKA_HOME/config/server.properties,讓Kafka刪除一周前的數(shù)據(jù)
- 基于Partition文件大小:在Partition文件超過1GB時(shí)刪除舊數(shù)據(jù)
配置如下所示:
# The minimum age of a log file to be eligible for deletion
log.retention.hours=168
# The maximum size of a log segment file. When this size is reached a new log segment will be created.
log.segment.bytes=1073741824
# The interval at which log segments are checked to see if they can be deleted according to the retention policies
log.retention.check.interval.ms=300000
# If log.cleaner.enable=true is set the cleaner will be enabled and individual logs can then be marked for log compaction.
log.cleaner.enable=false
因?yàn)镵afka讀取特定消息的時(shí)間復(fù)雜度為O(1),即與文件大小無關(guān),
所以這里刪除過期文件與提高Kafka性能無關(guān)。
選擇怎樣的刪除策略只與磁盤以及具體的需求有關(guān)。
另外,
Kafka會(huì)為每一個(gè)Consumer Group保留一些metadata信息——當(dāng)前消費(fèi)的消息的position,也即offset。
這個(gè)offset由Consumer控制。正常情況下Consumer會(huì)在消費(fèi)完一條消息后遞增該offset。
當(dāng)然,Consumer也可將offset設(shè)成一個(gè)較小的值,重新消費(fèi)一些消息。
因?yàn)閛ffet由Consumer控制,所以Kafka broker是無狀態(tài)的,它不需要標(biāo)記哪些消息被哪些消費(fèi)過,
也不需要通過broker去保證同一個(gè)Consumer Group只有一個(gè)Consumer能消費(fèi)某一條消息,
因此也就不需要鎖機(jī)制,這也為Kafka的高吞吐率提供了有力保障。
七、Producer消息路由
Producer發(fā)送消息到broker時(shí),會(huì)根據(jù)Paritition機(jī)制選擇將其存儲(chǔ)到哪一個(gè)Partition。
如果Partition機(jī)制設(shè)置合理,所有消息可以均勻分布到不同的Partition里,這樣就實(shí)現(xiàn)了負(fù)載均衡。
如果一個(gè)Topic對(duì)應(yīng)一個(gè)文件,那這個(gè)文件所在的機(jī)器I/O將會(huì)成為這個(gè)Topic的性能瓶頸,
而有了Partition后,不同的消息可以并行寫入不同broker的不同Partition里,極大的提高了吞吐率。
可以通過以下途徑來指定Topic的默認(rèn)Partition數(shù)量:
- (新建)在$KAFKA_HOME/config/server.properties中通過配置項(xiàng)num.partitions來指定
- (新建)在創(chuàng)建Topic時(shí)通過參數(shù)指定
- (創(chuàng)建之后)同時(shí)也可以在Topic創(chuàng)建之后通過Kafka提供的工具修改
在發(fā)送一條消息時(shí),可以指定這條消息的key,
Producer根據(jù)這個(gè)key和Partition機(jī)制來判斷應(yīng)該將這條消息發(fā)送到哪個(gè)Parition。
Paritition機(jī)制可以通過指定Producer的paritition.class這一參數(shù)來指定,
該class必須實(shí)現(xiàn)kafka.producer.Partitioner接口。
八、Consumer Group
使用Consumer high level API時(shí),
同一Topic的一條消息只能被同一個(gè)Consumer Group內(nèi)的一個(gè)Consumer消費(fèi),
但多個(gè)Consumer Group可同時(shí)消費(fèi)這一消息。
這是Kafka用來實(shí)現(xiàn)一個(gè)Topic消息的廣播(發(fā)給所有的Consumer)和單播(發(fā)給某一個(gè)Consumer)的手段。
一個(gè)Topic可以對(duì)應(yīng)多個(gè)Consumer Group。
如果需要實(shí)現(xiàn)廣播,只要每個(gè)Consumer有一個(gè)獨(dú)立的Group就可以了。
要實(shí)現(xiàn)單播只要所有的Consumer在同一個(gè)Group里。
用Consumer Group還可以將Consumer進(jìn)行自由的分組而不需要多次發(fā)送消息到不同的Topic。
實(shí)際上,Kafka的設(shè)計(jì)理念之一就是同時(shí)提供離線處理和實(shí)時(shí)處理。
根據(jù)這一特性,
- 可以使用Storm這種實(shí)時(shí)流處理系統(tǒng)對(duì)消息進(jìn)行實(shí)時(shí)在線處理,
- 同時(shí)使用Hadoop這種批處理系統(tǒng)進(jìn)行離線處理,
- 還可以同時(shí)將數(shù)據(jù)實(shí)時(shí)備份到另一個(gè)數(shù)據(jù)中心,
只需要保證這三個(gè)操作所使用的Consumer屬于不同的Consumer Group即可。
九、Push vs. Pull
作為一個(gè)消息系統(tǒng),Kafka遵循了傳統(tǒng)的方式,
選擇由Producer向broker push消息,
由Consumer從broker pull消息。
一些logging-centric system,比如Facebook的Scribe和Cloudera的Flume,采用push模式。
事實(shí)上,push模式和pull模式各有優(yōu)劣。
- push模式很難適應(yīng)消費(fèi)速率不同的消費(fèi)者,因?yàn)橄l(fā)送速率是由broker決定的。
push模式的目標(biāo)是盡可能以最快速度傳遞消息,但是這樣很容易造成Consumer來不及處理消息,
典型的表現(xiàn)就是拒絕服務(wù)以及網(wǎng)絡(luò)擁塞。 - 而pull模式則可以根據(jù)Consumer的消費(fèi)能力以適當(dāng)?shù)乃俾氏M(fèi)消息。
對(duì)于Kafka而言,pull模式更合適。
pull模式可簡(jiǎn)化broker的設(shè)計(jì),Consumer可自主控制消費(fèi)消息的速率,
同時(shí)Consumer可以自己控制消費(fèi)方式——即可批量消費(fèi)也可逐條消費(fèi),
同時(shí)還能選擇不同的提交方式從而實(shí)現(xiàn)不同的傳輸語義。
十、Kafka delivery guarantee
有這么幾種可能的delivery guarantee:
At most once 消息可能會(huì)丟,但絕不會(huì)重復(fù)傳輸
At least one 消息絕不會(huì)丟,但可能會(huì)重復(fù)傳輸
Exactly once 每條消息肯定會(huì)被傳輸一次且僅傳輸一次,很多時(shí)候這是用戶所想要的。
當(dāng)Producer向broker發(fā)送消息時(shí),一旦這條消息被commit,因數(shù)replication的存在,它就不會(huì)丟。
但是如果Producer發(fā)送數(shù)據(jù)給broker后,遇到網(wǎng)絡(luò)問題而造成通信中斷,
那Producer就無法判斷該條消息是否已經(jīng)commit。
雖然Kafka無法確定網(wǎng)絡(luò)故障期間發(fā)生了什么,但是Producer可以生成一種類似于主鍵的東西,發(fā)生故障時(shí)冪等性的重試多次,這樣就做到了Exactly once。
接下來討論的是消息從broker到Consumer的delivery guarantee語義。(僅針對(duì)Kafka consumer high level API)。Consumer在從broker讀取消息后,可以選擇commit,
該操作會(huì)在Zookeeper中保存該Consumer在該P(yáng)artition中讀取的消息的offset。
該Consumer下一次再讀該P(yáng)artition時(shí)會(huì)從下一條開始讀取。
如未commit,下一次讀取的開始位置會(huì)跟上一次commit之后的開始位置相同。
當(dāng)然可以將Consumer設(shè)置為autocommit,即Consumer一旦讀到數(shù)據(jù)立即自動(dòng)commit。
如果只討論這一讀取消息的過程,那Kafka是確保了Exactly once。
但實(shí)際使用中應(yīng)用程序并非在Consumer讀取完數(shù)據(jù)就結(jié)束了,
而是要進(jìn)行進(jìn)一步處理,而數(shù)據(jù)處理與commit的順序在很大程度上決定了消息從broker和consumer的delivery guarantee semantic。
Kafka默認(rèn)保證At least once,并且
允許通過設(shè)置Producer異步提交來實(shí)現(xiàn)At most once。而
Exactly once要求與外部存儲(chǔ)系統(tǒng)協(xié)作,幸運(yùn)的是Kafka提供的offset可以非常直接非常容易得使用這種方式。
十一、下載、安裝與配置
- 下載地址:
http://kafka.apache.org/downloads.html
http://mirrors.hust.edu.cn/apache/ - 安裝前提(安裝ZK):
參考http://www.cnblogs.com/qingyunzong/p/8634335.html#_label4_0 - 安裝(以版本kafka_2.11-0.8.2.0.tgz為例)
tar -zxvf kafka_2.11-0.8.2.0.tgz -C apps
cd apps/
ln -s kafka_2.11-0.8.2.0/ kafka
- 配置(部分配置為0.8之前的配置)
cd apps/kafka/config/
vi server.properties
//當(dāng)前機(jī)器在集群中的唯一標(biāo)識(shí),和zookeeper的myid性質(zhì)一樣
broker.id=0
//當(dāng)前kafka對(duì)外提供服務(wù)的端口默認(rèn)是9092
port=9092
//這個(gè)參數(shù)默認(rèn)是關(guān)閉的,在0.8.1有個(gè)bug,DNS解析問題,失敗率的問題。
host.name=hadoop1
//這個(gè)是borker進(jìn)行網(wǎng)絡(luò)處理的線程數(shù)
num.network.threads=3
//這個(gè)是borker進(jìn)行I/O處理的線程數(shù)
num.io.threads=8
//發(fā)送緩沖區(qū)buffer大小,數(shù)據(jù)不是一下子就發(fā)送的,先回存儲(chǔ)到緩沖區(qū)了到達(dá)一定的大小后在發(fā)送,能提高性能
socket.send.buffer.bytes=102400
//kafka接收緩沖區(qū)大小,當(dāng)數(shù)據(jù)到達(dá)一定大小后在序列化到磁盤
socket.receive.buffer.bytes=102400
//這個(gè)參數(shù)是向kafka請(qǐng)求消息或者向kafka發(fā)送消息的請(qǐng)請(qǐng)求的最大數(shù),這個(gè)值不能超過java的堆棧大小
socket.request.max.bytes=104857600
//消息存放的目錄,這個(gè)目錄可以配置為“,”逗號(hào)分割的表達(dá)式,上面的num.io.threads要大于這個(gè)目錄的個(gè)數(shù)這個(gè)目錄,
//如果配置多個(gè)目錄,新創(chuàng)建的topic他把消息持久化的地方是,當(dāng)前以逗號(hào)分割的目錄中,那個(gè)分區(qū)數(shù)最少就放那一個(gè)
log.dirs=/home/hadoop/log/kafka-logs
//默認(rèn)的分區(qū)數(shù),一個(gè)topic默認(rèn)1個(gè)分區(qū)數(shù)
num.partitions=1
//每個(gè)數(shù)據(jù)目錄用來日志恢復(fù)的線程數(shù)目
num.recovery.threads.per.data.dir=1
//默認(rèn)消息的最大持久化時(shí)間,168小時(shí),7天
log.retention.hours=168
//這個(gè)參數(shù)是:因?yàn)閗afka的消息是以追加的形式落地到文件,當(dāng)超過這個(gè)值的時(shí)候,kafka會(huì)新起一個(gè)文件
log.segment.bytes=1073741824
//每隔300000毫秒去檢查上面配置的log失效時(shí)間
log.retention.check.interval.ms=300000
//是否啟用log壓縮,一般不用啟用,啟用的話可以提高性能
log.cleaner.enable=false
//設(shè)置zookeeper的連接端口
zookeeper.connect=192.168.1.10:2181,192.168.1.11:2181,192.168.1.12:2181
//設(shè)置zookeeper的連接超時(shí)時(shí)間
zookeeper.connection.timeout.ms=6000
vi producer.properties
bootstrap.servers=192.168.1.1:9092,192.168.1.2:9092,192.168.1.3:9092
#bootstrap.servers= 是0.9之后的配置參數(shù),0.8及之前用metadata.broker.list=
vi consumer.properties
bootstrap.servers=192.168.1.4:9092,192.168.1.5:9092,192.168.1.6:9092
#bootstrap.servers= 是0.9之后的配置參數(shù),0.8及之前用zookeeper.connect=
- 將kafka的安裝包分發(fā)到其他節(jié)點(diǎn)
scp -r kafka_2.11-0.8.2.0/ hadoop2:$PWD
scp -r kafka_2.11-0.8.2.0/ hadoop3:$PWD
scp -r kafka_2.11-0.8.2.0/ hadoop4:$PWD
- 建軟聯(lián)
ln -s kafka_2.11-0.8.2.0/ kafka
- 修改環(huán)境變量
vi .bashrc
#Kafka
export KAFKA_HOME=/home/hadoop/apps/kafka
export PATH=$PATH:$KAFKA_HOME/bin
source ~/.bashrc
十二、啟動(dòng)
- 首先啟動(dòng)zookeeper集群
所有zookeeper節(jié)點(diǎn)都需要執(zhí)行
zkServer.sh start
- 啟動(dòng)Kafka集群服務(wù)(所有,分別到各個(gè)集群(hadoop1~4)啟動(dòng))
bin/kafka-server-start.sh config/server.properties
十三、創(chuàng)建的topic
- 創(chuàng)建
例:
通過kafka-topics.sh腳本來創(chuàng)建一個(gè)名為topic-test1并且副本數(shù)為3、分區(qū)數(shù)為3的topic
bin/kafka-topics.sh --create --zookeeper hadoop1:2181 --replication-factor 3 --partitions 3 --topic topic-test1
- 查看topic副本信息
bin/kafka-topics.sh --describe --zookeeper hadoop1:2181 --topic topic-test1
- 查看已經(jīng)創(chuàng)建的topic信息
bin/kafka-topics.sh --list --zookeeper hadoop1:2181
- 生產(chǎn)者發(fā)送消息
bin/kafka-console-producer.sh --broker-list hadoop1:9092 --topic topic-test1
hadoop1顯示接收到消息
- 消費(fèi)者消費(fèi)消息
在hadoop2上消費(fèi)消息
bin/kafka-console-consumer.sh --zookeeper hadoop1:2181 --from-beginning --topic topic-test1