Kafka是一個(gè)能夠支持高并發(fā)以及流式消息處理的消息中間件,并且Kafka天生就是支持集群的,今天就主要來介紹一下如何搭建Kafka集群。
Kafka目前支持使用Zookeeper模式搭建集群以及KRaft模式(即無Zookeeper)模式這兩種模式搭建集群,這兩種模式各有各的好處,今天就來分別介紹一下這兩種方式。
我們首先需要了解一下,一個(gè)Kafka集群是由下列幾種類型的節(jié)點(diǎn)構(gòu)成的,它們充當(dāng)著不同的作用:
Broker節(jié)點(diǎn):即代理節(jié)點(diǎn),是Kafka中的工作節(jié)點(diǎn),充當(dāng)消息隊(duì)列的角色,負(fù)責(zé)儲(chǔ)存和處理消息,每個(gè)Broker都是一個(gè)獨(dú)立的Kafka服務(wù)器,可以在不同的機(jī)器上運(yùn)行,除此之外Broker還負(fù)責(zé)分區(qū)(partition)的管理,將主題(topic)劃分為多個(gè)分區(qū),并分布在集群的不同Broker上
Controller節(jié)點(diǎn):即控制器節(jié)點(diǎn),是集群中的特殊節(jié)點(diǎn),負(fù)責(zé)儲(chǔ)存和管理整個(gè)集群元數(shù)據(jù)和狀態(tài),它能夠監(jiān)控整個(gè)集群中的Broker,在需要時(shí)還能夠進(jìn)行平衡操作
混合節(jié)點(diǎn):即同時(shí)擔(dān)任Broker和Controller節(jié)點(diǎn)角色的節(jié)點(diǎn)
接下來,我就來介紹一下兩種模式的集群架構(gòu)和搭建方式,即Zookeeper模式集群和KRaft模式集群。
這是一種比較簡(jiǎn)單,相對(duì)“傳統(tǒng)”的搭建方式了!在這種模式下,每個(gè)Kafka節(jié)點(diǎn)都是依賴于Zookeeper的,使用Zookeeper存儲(chǔ)集群中所有節(jié)點(diǎn)的元數(shù)據(jù)。
只要所有的Kafka節(jié)點(diǎn)連接到同一個(gè)Zookeeper上面(或者同一個(gè)Zookeeper集群),這些Kafka節(jié)點(diǎn)就構(gòu)成了一個(gè)集群。所以說就算是只有一個(gè)Kafka節(jié)點(diǎn)在運(yùn)行,這一個(gè)節(jié)點(diǎn)也可以稱作一個(gè)集群。
在Zookeeper模式集群中,Zookeeper節(jié)點(diǎn)(或者集群)就充當(dāng)了Controller的角色,而所有的Kafka節(jié)點(diǎn)就充當(dāng)著Broker的角色。
下面就來介紹一下搭建過程,這里我在4臺(tái)Linux虛擬機(jī)上分別運(yùn)行Zookeeper和Kafka來模擬一個(gè)集群,一共一個(gè)Zookeeper節(jié)點(diǎn)和三個(gè)Kafka節(jié)點(diǎn)構(gòu)成,如下:
上述地址例如kafka1等等,是通過修改虛擬機(jī)的主機(jī)名(hostname)實(shí)現(xiàn)的,這樣虛擬機(jī)之間可以直接通過這些主機(jī)名相互訪問,這個(gè)主機(jī)名我們就可以視作實(shí)際在服務(wù)器上面搭建時(shí),服務(wù)器的外網(wǎng)地址或者域名,這里就不再贅述如何修改虛擬機(jī)的主機(jī)名了,需要保證上述所有虛擬機(jī)在一個(gè)虛擬機(jī)網(wǎng)段中并且能夠互相ping通,即上述所有虛擬機(jī)需要兩兩之間可以通過網(wǎng)絡(luò)互相訪問。
運(yùn)行Kafka和Zookeeper都需要Java 8及其以上運(yùn)行環(huán)境,大家要首先在虛擬機(jī)中安裝并配置好。
首先我們要運(yùn)行起一個(gè)Zookeeper節(jié)點(diǎn),這里就不再贅述Zookeeper節(jié)點(diǎn)如何搭建了!搭建可以查看 官方文檔,或者使用 Docker的方式搭建。
搭建完成并運(yùn)行Zookeeper之后,我們會(huì)把所有的Kafka節(jié)點(diǎn)都配置到這一個(gè)Zookeeper節(jié)點(diǎn)上。
首先去 Kafka官網(wǎng)下載最新版并解壓,然后將解壓出來的Kafka分別復(fù)制到三臺(tái)虛擬機(jī)中。
然后修改每臺(tái)虛擬機(jī)的Kafka目錄中的配置文件,配置文件位于解壓的Kafka文件夾中的config/server.properties,使用文本編輯器打開,并找到下列配置項(xiàng)進(jìn)行配置:
注意上述advertised.listeners這個(gè)配置項(xiàng)默認(rèn)情況下是被注釋掉了的,大家需要去仔細(xì)找一下并去掉注釋(開頭的#)然后再進(jìn)行配置。
三臺(tái)虛擬機(jī)配置完成后,分別使用終端進(jìn)入到Kafka目錄下并啟動(dòng),執(zhí)行下列命令:
bin/kafka-server-start.sh config/server.properties
在上述三臺(tái)虛擬機(jī)上面都通過這個(gè)命令啟動(dòng)Kafka,如圖則啟動(dòng)成功:
到此,整個(gè)集群就搭建完成了!大家需要保證上述三臺(tái)虛擬機(jī)中的終端不被關(guān)閉。
我們先在kafka1的虛擬機(jī)上面再開一個(gè)終端并進(jìn)入Kafka目錄,執(zhí)行下列命令創(chuàng)建Topic:
bin/kafka-server-start.sh config/server.properties
然后去kafka2的虛擬機(jī)上面再開一個(gè)終端并進(jìn)入Kafka目錄,執(zhí)行下列命令列出Topic:
bin/kafka-topics.sh --list --bootstrap-server localhost:9092
可見我們?cè)诘谝粋€(gè)節(jié)點(diǎn)上創(chuàng)建了話題,但是在第二個(gè)節(jié)點(diǎn)上仍然可以獲取這個(gè)話題,說明集群創(chuàng)建成功,數(shù)據(jù)在集群之間可以共享。
在上述傳統(tǒng)方案中,Kafka需要依賴Zookeeper完成元數(shù)據(jù)存放和共享,這樣也就暴露出了一些問題:
搭建Kafka集群時(shí)還需要額外搭建Zookeeper,增加了運(yùn)維成本
Zookeeper是強(qiáng)一致性的組件(符合CP理論),如果集群中數(shù)據(jù)發(fā)生變化,那么必須要等到其它節(jié)點(diǎn)都同步,至少超過一半同步完成,這樣節(jié)點(diǎn)數(shù)多性能差
那么KRaft模式是新版本Kafka中推出的集群模式,這種模式下就完全不需要Zookeeper了!只需要數(shù)個(gè)Kafka節(jié)點(diǎn)就可以直接構(gòu)成集群,在這時(shí)集群中的Kafka節(jié)點(diǎn)既有可能是Controller節(jié)點(diǎn)也可能是Broker節(jié)點(diǎn),在這個(gè)模式中,我們不僅可以手動(dòng)配置某個(gè)節(jié)點(diǎn)的角色(是Controller還是Broker),還可以使其同時(shí)擔(dān)任Broker和Controller角色(混合節(jié)點(diǎn))。
在KRaft模式中,集群的節(jié)點(diǎn)會(huì)通過投票選舉的方式,選擇出一個(gè)主要的Controller節(jié)點(diǎn),這個(gè)節(jié)點(diǎn)也稱作領(lǐng)導(dǎo)者,它將負(fù)責(zé)維護(hù)整個(gè)集群的元數(shù)據(jù)和狀態(tài)信息,那么其它的Controller節(jié)點(diǎn)或者混合節(jié)點(diǎn)就稱之為追隨者,它們會(huì)從領(lǐng)導(dǎo)者同步集群元數(shù)據(jù)和狀態(tài)信息。如果領(lǐng)導(dǎo)者宕機(jī)了,所有的節(jié)點(diǎn)會(huì)重新投票選舉一個(gè)新的領(lǐng)導(dǎo)者。
在選舉過程中,所有的節(jié)點(diǎn)都會(huì)參與投票過程,而候選節(jié)點(diǎn)只會(huì)是Controller節(jié)點(diǎn)或者混合節(jié)點(diǎn)(即Broker節(jié)點(diǎn)不會(huì)被選舉為領(lǐng)導(dǎo)者)。
需要注意的是,在默認(rèn)情況下Kafka集群中的Broker節(jié)點(diǎn)和Controller節(jié)點(diǎn)通常會(huì)監(jiān)聽不同的端口:
所以需要根據(jù)實(shí)際情況配置網(wǎng)絡(luò)設(shè)置和防火墻規(guī)則,以確保Kafka集群中的節(jié)點(diǎn)能夠在正確的端口上進(jìn)行通信。上述提到的兩種端口也是可以修改的,當(dāng)然不建議修改。
同樣地,就算是你只是搭建了一個(gè)Kafka節(jié)點(diǎn),這一個(gè)節(jié)點(diǎn)也仍然被視為一個(gè)Kafka集群,并且KRaft模式下如果只需要建立一個(gè)節(jié)點(diǎn),那么這個(gè)節(jié)點(diǎn)必須是混合節(jié)點(diǎn)。
下面同樣是開啟三臺(tái)虛擬機(jī),搭建三個(gè)Kafka節(jié)點(diǎn)構(gòu)成的KRaft模式集群如下:
這里就不再贅述下載Kafka的過程了!
在KRaft模式下,配置文件位于Kafka目錄中的config/kraft/server.properties,使用文本編輯器打開并找到下列配置以修改:
node.id 表示這個(gè)節(jié)點(diǎn)的id,一個(gè)集群中每個(gè)節(jié)點(diǎn)id不能重復(fù),需要是不小于1的整數(shù),這里三臺(tái)虛擬機(jī)的配置分別為1,2和3(類似上述Zookeeper的broker.id配置)
controller.quorum.voters 設(shè)定投票者列表,即需要配置所有的Controller節(jié)點(diǎn)id及其地址端口,配置格式為節(jié)點(diǎn)1的id@節(jié)點(diǎn)1地址:節(jié)點(diǎn)1端口,節(jié)點(diǎn)2的id@節(jié)點(diǎn)2地址:節(jié)點(diǎn)2端口,節(jié)點(diǎn)3的id@節(jié)點(diǎn)3地址:節(jié)點(diǎn)3端口...,這里的端口需要是控制器端口,默認(rèn)都是9093,上面也提到過了,默認(rèn)不需要修改,我這里三臺(tái)虛擬機(jī)的都配置為1@kafka1:9093,2@kafka2:9093,3@kafka3:9093(實(shí)際在服務(wù)器上搭建時(shí)替換為服務(wù)器的外網(wǎng)地址或者域名)
advertised.listeners 表示這個(gè)Kafka節(jié)點(diǎn)的外網(wǎng)地址,這里分別配置為PLAINTEXT://kafka1:9092,PLAINTEXT://kafka2:9092和PLAINTEXT://kafka3:9092(和上述Zookeeper模式中的一樣,實(shí)際在服務(wù)器上搭建時(shí)替換為服務(wù)器的外網(wǎng)地址或者域名)
上述是必須要進(jìn)行配置的,還有下面配置是可以選擇性配置的:
process.roles 表示設(shè)定這個(gè)節(jié)點(diǎn)的類型,設(shè)定為broker表示設(shè)定這個(gè)節(jié)點(diǎn)為Broker節(jié)點(diǎn),同樣地設(shè)定controller表示設(shè)定為Controller節(jié)點(diǎn),默認(rèn)是broker,controller表示這個(gè)節(jié)點(diǎn)會(huì)自動(dòng)切換節(jié)點(diǎn)類型,這里先保持默認(rèn)不變,下面再來詳細(xì)討論
在KRaft模式下,一個(gè)集群需要設(shè)定一個(gè)id,我們可以使用自帶的命令生成,先進(jìn)入上述任意一臺(tái)虛擬機(jī)并使用終端進(jìn)入Kafka目錄中,執(zhí)行下列命令生成一個(gè)UUID:
bin/kafka-storage.sh random-uuid
我們這里記錄下這個(gè)ID以備用。
這個(gè)集群ID事實(shí)上是一個(gè)長(zhǎng)度16位的字符串通過Base64編碼后得來的,因此你也可以不使用上述命令,直接自定義一個(gè)16位長(zhǎng)度的純英文和數(shù)字組成的字符串,然后將這個(gè)字符串編碼為Base64格式作為這個(gè)集群ID也可以??梢允褂?nbsp;菜鳥工具中的在線Base64編碼工具。
然后在上述三臺(tái)虛擬機(jī)中,都使用終端進(jìn)入Kafka目錄后,執(zhí)行下列命令:
bin/kafka-storage.sh format -t 生成的集群ID -c config/kraft/server.properties
這樣,三個(gè)Kafka節(jié)點(diǎn)都使用了這一個(gè)ID完成了集群元數(shù)據(jù)配置,表示這三個(gè)Kafka節(jié)點(diǎn)構(gòu)成一個(gè)集群。
同樣地,在三臺(tái)虛擬機(jī)中,都使用終端進(jìn)入Kafka目錄后,執(zhí)行下列命令:
bin/kafka-server-start.sh config/kraft/server.properties
三臺(tái)虛擬機(jī)全部啟動(dòng)后,這個(gè)集群才啟動(dòng)完畢。
同樣地,現(xiàn)在第一個(gè)虛擬機(jī)的Kafka目錄下執(zhí)行下列命令:
bin/kafka-topics.sh --create --topic my-topic-kraft --bootstrap-server localhost:9092
然后在第二個(gè)虛擬機(jī)的Kafka目錄下查看話題:
bin/kafka-topics.sh --list --bootstrap-server localhost:9092
可見集群節(jié)點(diǎn)之間可以互相通信。
無論是在虛擬機(jī)還是服務(wù)器上,都要保證9092和9093端口開放,且所有虛擬機(jī)/服務(wù)器之間都能夠兩兩互相訪問(網(wǎng)絡(luò)連通)!
無論是那種模式的集群,我們都涉及到了許多配置項(xiàng),大家通過上述的搭建示例也能夠了解到每個(gè)配置項(xiàng)的意義,這里就專門來著重介紹一下,Kafka中一些重要的配置項(xiàng)。
這個(gè)配置項(xiàng)用于指定Kafka服務(wù)器監(jiān)聽客戶端連接的地址和端口,當(dāng) Kafka 服務(wù)器啟動(dòng)時(shí),它將監(jiān)聽listeners配置項(xiàng)中指定的地址和端口,等待客戶端的連接請(qǐng)求。
一般情況下這個(gè)配置以PLAINTEXT://或者CONTROLLER://開頭,意義如下:
這個(gè)配置項(xiàng)通常不需要修改,下面給出幾個(gè)配置示例:
這個(gè)配置容易和listeners混淆,事實(shí)上它們是有較大的區(qū)別的。
該配置項(xiàng)指定Kafka服務(wù)器廣播給客戶端的地址和端口,通常配置為Kafka所在服務(wù)器的外網(wǎng)地址。
當(dāng)客戶端(生產(chǎn)者或消費(fèi)者)嘗試連接到Kafka服務(wù)器時(shí),它首先會(huì)獲取Kafka服務(wù)器廣播的地址和端口,也就是advertise.listeners配置所指定的地址和端口,然后才會(huì)使用advertise.listeners配置所指定的地址和端口來建立與Kafka服務(wù)器的連接。
相信這時(shí)大家會(huì)有個(gè)疑問:既然客戶端要連接Kafka(例如Spring Boot集成Kafka客戶端),那一定是已經(jīng)知道了Kafka對(duì)外的地址端口了,那為什么連接的時(shí)候還需要獲取一下廣播的地址端口再進(jìn)行連接呢?這樣是不是有一些多此一舉?
事實(shí)上,Kafka設(shè)計(jì)這個(gè)配置是為了解決下面較為復(fù)雜的網(wǎng)絡(luò)場(chǎng)景:
總之,這個(gè)配置設(shè)置為Kafka服務(wù)器所在的外網(wǎng)地址即可!例如PLAINTEXT://69.54.112.239:9092。
這是KRaft模式下專門的配置,用于配置這個(gè)節(jié)點(diǎn)的類型,可以配置為下列值:
如果沒有配置這個(gè)選項(xiàng),則Kafka會(huì)以Zookeeper模式運(yùn)行。
這里有下列注意事項(xiàng):
則不能配置advertised.listeners,可以將其注釋掉或者刪掉
listeners需要配置為CONTROLLER://開頭,建議配置為CONTROLLER://:9093
則需要配置advertised.listeners為服務(wù)器外網(wǎng)地址和端口,這和Zookeeper模式中相同
listeners需要配置為PLAINTEXT://開頭,建議配置為PLAINTEXT://:9092
同樣需要配置advertised.listeners為服務(wù)器外網(wǎng)地址和端口
listeners需要同時(shí)配置CONTROLLER://和PLAINTEXT://,建議配置為PLAINTEXT://:9092,CONTROLLER://:9093
在開發(fā)環(huán)境或者小規(guī)模集群,可以全部使用混合節(jié)點(diǎn),如果是生產(chǎn)環(huán)境就建議設(shè)定好每個(gè)節(jié)點(diǎn)的類型了!并且通常需要先啟動(dòng)Controller節(jié)點(diǎn)再啟動(dòng)Broker節(jié)點(diǎn)。
事實(shí)上,我們發(fā)現(xiàn)Kafka的KRaft配置目錄config/kraft下有三個(gè)配置文件,其中server.properties是混合節(jié)點(diǎn)的配置模板,而broker.properties和controller.properties分別是Broker節(jié)點(diǎn)和Controller節(jié)點(diǎn)的配置模板,大家如果要設(shè)定節(jié)點(diǎn)類型,可以直接使用對(duì)應(yīng)的配置文件,將對(duì)應(yīng)配置文件需要修改的部分修改一下,然后將上述格式化數(shù)據(jù)目錄命令和啟動(dòng)命令中的配置文件路徑改變一下即可,這樣可以省略我們?cè)O(shè)定process.roles和listeners或者控制器節(jié)點(diǎn)刪除advertise.listeners配置的操作。
該配置項(xiàng)用于配置集群中Controller節(jié)點(diǎn)選舉過程中的投票者,集群中所有的Controller節(jié)點(diǎn)都需要被羅列在這個(gè)配置項(xiàng)中,其配置格式為id1@host1:port1,id2@host2:port2,id3@host3:port3...。
有的同學(xué)可能認(rèn)為這里需要把集群中所有節(jié)點(diǎn)都寫進(jìn)去,事實(shí)上這是錯(cuò)誤的,這里只需要寫所有的Controller節(jié)點(diǎn)和混合節(jié)點(diǎn)的id、地址和端口即可,這個(gè)配置中配置的端口當(dāng)然是控制器端口。
上述集群搭建的例子中,由于所有的節(jié)點(diǎn)都是混合節(jié)點(diǎn),因此就全部寫在其中了!如果我們手動(dòng)設(shè)定每個(gè)節(jié)點(diǎn)的類型,例如:
那么所有節(jié)點(diǎn)的controller.quorum.voters都需要配置為1@kafka1:9093。
事實(shí)上,所有的節(jié)點(diǎn)都是通過這個(gè)配置中的節(jié)點(diǎn)列表,來得知所有的控制器節(jié)點(diǎn)信息(以獲取集群元數(shù)據(jù))并得到投票候選者的,因此集群中所有節(jié)點(diǎn),不論是Broker還是Controller,還是混合節(jié)點(diǎn),都需要配置這一項(xiàng)。
除了上述我們涉及到的一些配置之外,還有下列配置大家可以進(jìn)行修改:
上述無論是哪個(gè)模式的集群,都可以在配置文件中找到這些配置,如果找不到可手動(dòng)加入。除了修改配置文件之外,我們還可以在啟動(dòng)Kafka的命令中指定配置和值,例如:
bin/kafka-server-start.sh config/server.properties --override zookeeper.connect=127.0.0.1:2181 --override broker.id=1
上述命令在啟動(dòng)時(shí)通過命令指定了zookeeper.connect配置值為127.0.0.1:2181,以及broker.id為1,可見在后面追加--override 配置名=值即可,注意命令行中指定的配置值會(huì)覆蓋掉配置文件中的配置值!
本文鏈接:http://www.tebozhan.com/showinfo-26-17888-0.htmlKafka兩種集群詳解和搭建教程
聲明:本網(wǎng)頁內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。郵件:2376512515@qq.com
上一篇: 平臺(tái)工程團(tuán)隊(duì)的架構(gòu)和設(shè)計(jì)注意事項(xiàng)
下一篇: SpringCloud OpenFeign整合Ribbon實(shí)現(xiàn)負(fù)載均衡及源碼分析