Kafka高可用叢集部署與配置指南

jaymarco發表於2020-10-16

Kafka是最初由Linkedin公司開發,是一個分散式、分割槽的、多副本的、多訂閱者,基於zookeeper協調的分散式日誌系統(也可以當做MQ系統),常見可以用於web/nginx日誌、訪問日誌,訊息服務等等,Linkedin於2010年貢獻給了Apache基金會併成為頂級開源專案。

主要應用場景是:日誌收集系統和訊息系統。

Kafka主要設計目標如下:

1.    以時間複雜度為O(1)的方式提供訊息持久化能力,即使對TB級以上資料也能保證常數時間的訪問效能。

2.    高吞吐率。即使在非常廉價的商用機器上也能做到單機支援每秒100K條訊息的傳輸。

3.    支援Kafka Server間的訊息分割槽,及分散式消費,同時保證每個partition內的訊息順序傳輸。

4.    同時支援離線資料處理和實時資料處理。

5.    Scale out:支援線上水平擴充套件

的特性

·          高吞吐量、低延遲:kafka每秒可以處理幾十萬條訊息,它的延遲最低只有幾毫秒,每個topic可以分多個partition, consumer group 對partition進行consume操作。

·          可擴充套件性:kafka叢集支援熱擴充套件

·          永續性、可靠性:訊息被持久化到本地磁碟,並且支援資料備份防止資料丟失

·          容錯性:允許叢集中節點失敗(若副本數量為n,則允許n-1個節點失敗)

·          高併發:支援數千個客戶端同時讀寫

的使用場景

·          日誌收集:一個公司可以用Kafka可以收集各種服務的log,透過kafka以統一介面服務的方式開放給各種consumer,例如hadoop、Hbase、Solr等。

·          訊息系統:解耦和生產者和消費者、快取訊息等。

·          使用者活動跟蹤:Kafka經常被用來記錄web使用者或者app使用者的各種活動,如瀏覽網頁、搜尋、點選等活動,這些活動資訊被各個伺服器釋出到kafka的topic中,然後訂閱者透過訂閱這些topic來做實時的監控分析,或者裝載到hadoop、資料倉儲中做離線分析和挖掘。

·          運營指標:Kafka也經常用來記錄運營監控資料。包括收集各種分散式應用的資料,生產各種操作的集中反饋,比如報警和報告。

·          流式處理:比如spark streaming和storm

術語

術語含義

ZooKeeper

開源分散式應用程式協調服務

Broker

Kafka   叢集包含一個或多個伺服器,伺服器節點稱為broker

Topic

每條釋出到Kafka叢集的訊息都有一個類別,這個類別被稱為Topic

Partition

topic中的資料分割為一個或多個partition

Producer

生產者即資料的釋出者,該角色將訊息釋出到Kafka的topic中

Consumer

消費者可以從broker中讀取資料

Consumer   Group

每個Consumer屬於一個特定的Consumer Group

Leader

每個partition有多個副本,其中有且僅有一個作為Leader,Leader是當前負責資料的讀寫的partition

Follower

Follower跟隨Leader,所有寫請求都透過Leader路由,資料變更會廣播給所有Follower,Follower與Leader保持資料同步。如果Leader失效,則從Follower中選舉出一個新的Leader。當Follower與Leader掛掉、卡住或者同步太慢,leader會把這個follower從“in sync replicas”(ISR)列表中刪除,重新建立一個Follower。

Kafka叢集中包含若干Producer,若干broker(Kafka支援水平擴充套件,一般broker數量越多,叢集吞吐率越高),若干Consumer Group,以及一個Zookeeper叢集。Kafka透過Zookeeper管理叢集配置,選舉leader,以及在Consumer Group發生變化時進行rebalance。Producer使用push模式將訊息釋出到broker,Consumer使用pull模式從broker訂閱並消費訊息。

準備三臺虛擬機器用於部署zookeeper和Kafka 叢集,要求硬體配置標準一樣。

主機名

IP 地址

用途

192.168.56.129

Kafkanode1

Zookeeper, Kafka 節點1

192.168.56.130

Kafkanode2

Zookeeper, Kafka 節點2

192.168.56.131

Kafkanode3

Zookeeper, Kafka 節點3

DK 軟體部署規劃

JDK安裝部署規劃如下表:

I P 地址

部署目錄

192.168.56.129

/opt/jdk1.8.0_221

192.168.56.130

/opt/jdk1.8.0_221

192.168.56.131

/opt/jdk1.8.0_221

環境部署規劃

Zookeeper叢集部署前規劃出訊息埠、通訊埠和部署目錄如下:

I P 地址

訊息埠

通訊埠

ServerID 標識

部署目錄

192.168.56.129

2181

2888:3888

1

/opt/zookeeper

192.168.56.130

2181

2888:3888

2

/opt/zookeeper

192.168.56.131

2181

2888:3888

3

/opt/zookeeper

環境部署規劃

Kafka叢集部署前規劃出叢集通訊埠、協議通訊埠、控制檯埠、叢集名和部署目錄如下:

I P 地址

監聽埠

節點目錄

192.168.56.129

PLAINTEXT://192.168.58.129:9092

/opt/kafka_cluster/node1

192.168.56.130

PLAINTEXT://192.168.58.130:9092

/opt/kafka_cluster/node2

192.168.56.131

PLAINTEXT://192.168.58.131:9092

/opt/kafka_cluster/node3

Kafka叢集部署是各節點需要安裝的軟體分佈如下:

Ip 地址

軟體名

192.168.56.129

jdk1.8.0_221    zookeeper-3.4.14    kafka-2.5.0

192.168.56.130

jdk1.8.0_221    zookeeper-3.4.14    kafka -2.5.0

192.168.56.131

jdk1.8.0_221    zookeeper-3.4.14    kafka -2.5.0

Kafka叢集部署所需要軟體來源下載地址如下:

軟體名

版本號

來源地址

JDK

1.8.0_242

zookeeper

3.4.14

kafka

5.15.12

ZooInspector


https://issues.apache.org/jira/secure/attachment/12436620/ZooInspector.zip

軟體安裝

分別在3臺Kafka節點/opt目錄下面安裝JDK軟體,將JDK軟體包直接解壓到目標安裝路徑下,配置好環境變數並讓其變數生效成功。

cd /opt 目錄下解壓軟體

tar xvf jdk-8u221-linux-x64.tar.gz

 

最後需要修改環境變數,透過命令vim /etc/profile vim 編輯器來編輯profile 檔案,在檔案末尾新增一下內容:

export JAVA_HOME=/opt/jdk1.8.0_221

export JRE_HOME=${JAVA_HOME}/jre

export   CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib:$CLASSPATH

export JAVA_PATH=${JAVA_HOME}/bin:${JRE_HOME}/bin

export PATH=$PATH:${JAVA_PATH}

 

執行如下命令生效jdk 環境變數

source /etc/profile

 

[root@node1 opt]# java -version

openjdk version "1.8.0_242"

OpenJDK Runtime Environment (build   1.8.0_242-b08)

OpenJDK 64-Bit Server VM (build   25.242-b08, mixed mode)

 

到此JDK 軟體安裝成功!

叢集搭建

軟體安裝

分別在3臺Kafka節點/opt目錄下面安裝zookeeper軟體,將zk軟體包直接解壓到目標安裝路徑下,配置好環境變數並讓其變數生效成功。

tar zxvf zookeeper-3.4.14.tar.gz   -C /opt

cd /opt && mv zookeeper-3.4.8   zookeeper

cd zookeeper

cp conf/zoo_sample.cfg conf/zoo.cfg

 

# zookeeper 加入到環境變數,3 臺主機都需要執行

echo -e "# append zk_env\nexport   PATH=$PATH:/opt/zookeeper/bin" >> /etc/profile

 

3 臺主機上面執行生效命令

Source /etc/profile

叢集配置

1、 配置檔案修改

修改節點1上面的zk配置檔案zoo.cfg,詳細配置引數內容如下:

tickTime=2000

initLimit=10

syncLimit=5

dataDir=/opt/zookeeper/data

dataLogDir=/opt/zookeeper/logs

clientPort=2181

autopurge.purgeInterval=24

autopurge.snapRetainCount=500

server.1= 192.168.58.129:2888:3888

server.2= 192.168.58.130:2888:3888

server.3= 192.168.58.131:2888:3888

 

並將節點1配置檔案zoo.cfg複製到節點2和節點3上面。

在三臺節點上面建立如下目錄

mkdir -p /opt/zookeeper/{logs,data}

 

2、 ZK 配置引數說明

n   tickTime:Client-Server通訊心跳時間

Zookeeper 伺服器之間或客戶端與伺服器之間維持心跳的時間間隔,也就是每個 tickTime 時間就會傳送一個心跳。tickTime以毫秒為單位。

n   initLimit:Leader-Follower初始通訊時限
叢集中的follower伺服器(F)與leader伺服器(L)之間初始連線時能容忍的最多心跳數(tickTime的數量)。
initLimit=5

n   syncLimit:Leader-Follower同步通訊時限

叢集中的 follower 伺服器與 leader 伺服器之間請求和應答之間能容忍的最多心跳數( tickTime 的數量)。
syncLimit=2

n   dataDir:資料檔案目錄

Zookeeper 儲存資料的目錄,預設情況下, Zookeeper 將寫資料的日誌檔案也儲存在這個目錄裡。 dataDir= /opt/zookeeper/data

n   clientPort:客戶端連線埠

客戶端連線 Zookeeper 伺服器的埠, Zookeeper 會監聽這個埠,接受客戶端的訪問請求。 clientPort=2181

n   6.伺服器名稱與地址:叢集資訊(伺服器編號,伺服器地址,LF通訊埠,選舉埠)

這個配置項的書寫格式比較特殊,規則如下:
server.N=YYY:A:B

server.1=zknode01:2888:3888
server.2= zknode02:2888:3888
server.3= zknode03:2888:3888

 

3、 ZK 服務建立 ServerID 標識

在三個虛擬機器下的data資料夾下建立三個myid檔案,並且三個檔案裡面分別寫入1,2,3

#192.168.58.129 節點1 上面建立myid 1

echo "1" >   /opt/zookeeper/data/myid

#192.168.58.130 節點1 上面建立myid 2

echo "2" >   /opt/zookeeper/data/myid

#192.168.58.131 節點1 上面建立myid 3

echo "3" > /opt/zookeeper/data/myid

叢集啟動

l   啟動 ZK 節點

/opt/zookeeper/bin/zkServer.sh start

l   停止 ZK 節點

/opt/zookeeper/bin/zkServer.sh stop

l   檢視 ZK 狀態

/opt/zookeeper/bin/zkServer.sh status

l   日誌路徑

/opt/zookeeper/logs

叢集測試

模擬ZK叢集切換,停掉Leader節點讓ZK自動發生選舉到其它節點。

上圖Leader節點在192.168.58.130,其它兩個節點都是follower狀態。

模擬將192.168.58.130節點leader服務發生故障當機,觀察ZK叢集是否會自動選舉到其它兩個follower節點之一作為leader節點。當leader服務主節點已經被停止後,ZK最終選舉了follower節點192.168.58.131為leader,選舉成功,ZK叢集正常工作。後面再將當機的那臺主機恢復回來後,此節點ZK的狀態就變成了被選舉狀態follower。至此說明ZK叢集切換成功。

叢集搭建

Kafka叢集安裝採集節點克隆安裝,先將kafka安裝到其中一個節點,然後將配置修改後,直接將節點1上面的kafka以克隆方式COPY到其他兩個節點。

軟體安裝

選擇節點一臺kafka主機伺服器節點/opt目錄下面安裝kafka軟體,安裝完後並配置好環境變數並讓其變數生效成功。

選擇其中一臺kafkanode1 部署

mkdir   /opt/kafka-cluster/

tar zxvf kafka_2.12-2.5.0.tgz -C /opt/kafka-cluster/

cd /opt/ kafka-cluster/ && mv kafka node1

配置修改

修改kafka配置檔案/opt/kafka-cluster/node1/config/server.properties ,注意只需要修改如下三項配置,broker.id listeners zookeeper.connect

broker.id=1

listeners=PLAINTEXT://192.168.58.129:9092

zookeeper.connect=192.168.56.129:2181,192.168.58.130:2181,192.168.58.131:2181

 

注意:以上kafka節點1已經配置完成。

kafka 節點

1 、克隆 kafka 節點 2

將kafka節點1上面的kafka安裝軟體目錄遠端複製到遠端節點2

#從節點1上面複製kafka軟體到節點2

scp -r /opt/kafka-cluster/   192.168.58.130:/opt

cd    /opt/kafka-cluster/

mv   node1 node2

 

# 修改配置檔案server.properties ,只需要修改broker.id listeners 兩個引數

原來如下:

###############################################

broker.id=1

listeners=PLAINTEXT://192.168.58.129:9092

###############################################

 

修改為:

###############################################

broker.id=2

listeners=PLAINTEXT://192.168.58.130:9092

###############################################

 

2 、克隆 kafka 節點 3

將kafka節點1上面的kafka安裝軟體目錄遠端複製到遠端節點3

#從節點1上面複製kafka軟體到節點3

scp -r /opt/kafka-cluster/   192.168.58.131:/opt

cd    /opt/kafka-cluster/

mv   node1 node3

 

# 修改配置檔案server.properties ,只需要修改broker.id listeners 兩個引數

原來如下:

###############################################

broker.id=1

listeners=PLAINTEXT://192.168.58.129:9092

###############################################

 

修改為:

###############################################

broker.id=3

listeners=PLAINTEXT://192.168.58.131:9092

###############################################

 

到此kafka 叢集已經配置完成!

叢集啟動

分別在三臺kafka節點上面用命令去啟停服務

l   啟動kafka服務

./kafka-server-start.sh -daemon  ../config/server.properties

l   停止kafka服務

./kafka-server-stop.sh  -daemon  ../config/server.propertiesp

l   檢視kafka日誌

/opt/kakfa-cluster/node1/logs/kafkaServer.out

待補充


8          Kafka 效能調優

8.1      Broker 引數配置

1、網路和io操作執行緒配置最佳化

#   broker處理訊息的最大執行緒數(預設為3)

num.network.threads=cpu核數+1

#   broker處理磁碟IO的執行緒數

num.io.threads=cpu核數*2

2、log資料檔案刷盤策略  

#   每當producer寫入10000條訊息時,刷資料到磁碟

log.flush.interval.messages=10000

#   每間隔1秒鐘時間,刷資料到磁碟

log.flush.interval.ms=1000

3、日誌保留策略配置

#   保留三天,也可以更短   (log.cleaner.delete.retention.ms)

log.retention.hours=72

#   段檔案配置1GB,有利於快速回收磁碟空間,重啟kafka載入也會加快(如果檔案過小,則檔案數量比較多,kafka啟動時是單執行緒掃描目錄(log.dir)下所有資料檔案

log.segment.bytes=1073741824

4、Replica相關配置

default.replication.factor:3

#   這個引數指新建立一個topic時,預設的Replica數量,Replica過少會影響資料的可用性,太多則會白白浪費儲存資源,一般建議在2~3為宜。

8.2      Java API 調優

1、zookeeper.session.timeout.ms

解釋:配置的超時時間太短,Zookeeper沒有讀完Consumer的資料,連線就被Consumer斷開了!

引數:5000

2、zookeeper.sync.time.ms

解釋:ZooKeeper叢集中leader和follower之間的同步的時間

引數:2000

3、auto.commit.enable=true

解釋:注意offset資訊並不是每消費一次訊息就向zk提交一次,而是現在本地儲存(記憶體),並定期提交  

4、auto.commit.interval.ms

解釋:自動提交offset到zookeeper的時間間隔

引數:1000

5、zookeeper.connection.timeout.ms

解釋:確認zookeeper連線建立操作客戶端能等待的最長時間

引數:10000

6、rebalance.backoff.ms

解釋:消費均衡兩次重試之間的時間間隔

引數:2000

7、rebalance.max.retries

解釋:消費均衡的重試次數

引數:10

 

客戶端配置

<!-- 定義producer的引數 -->

    <bean   id="producerProperties" class="java.util.HashMap">  

        <constructor-arg>  

            <map>

                <!-- 配置kafka的broke -->

                <entry   key="bootstrap.servers" value="192.168.172.129:9092"/>  

                <!-- 配置組-->

                <entry   key="group.id" value="group1"/>

                <entry   key="acks" value="all"/>

                 <entry   key="retries" value="10"/>

                <entry   key="batch.size" value="16384"/>

                <entry   key="linger.ms" value="1"/>

                <entry   key="buffer.memory" value="33554432"/>

                <entry key="key.serializer"   value="org.apache.kafka.common.serialization.StringSerializer"/>  

                <entry   key="value.serializer"   value="org.apache.kafka.common.serialization.StringSerializer"/>  

            </map>

        </constructor-arg>  

    </bean>

 

    <!-- 建立kafkatemplate需要使用的producerfactory bean -->

    <bean   id="producerFactory"   class="org.springframework.kafka.core.DefaultKafkaProducerFactory">  

        <constructor-arg>  

            <ref   bean="producerProperties"/>

        </constructor-arg>  

    </bean>

 

    <!-- 建立kafkatemplate   bean,使用的時候,只需要注入這個bean,即可使用template的send訊息方法 -->

    <bean   id="kafkaTemplate"   class="org.springframework.kafka.core.KafkaTemplate">

        <constructor-arg   ref="producerFactory"/>

        <constructor-arg   name="autoFlush" value="true"/>

        <property   name="defaultTopic" value="test1"/>

    </bean>

  9.2      客戶端配置

<!-- 定義consumer的引數 -->

    <bean id="consumerProperties"   class="java.util.HashMap">

        <constructor-arg>  

            <map>

                <!-- 配置kafka的broke -->

                <entry   key="bootstrap.servers" value="192.168.172.129:9092"/>  

                <!-- 配置組-->

                 <entry   key="group.id" value="group1"/>

                <entry   key="enable.auto.commit" value="true"/>

                <entry   key="auto.commit.interval.ms" value="1000"/>

                <entry   key="session.timeout.ms" value="30000"/>

                <entry   key="key.deserializer"   value="org.apache.kafka.common.serialization.StringDeserializer"/>  

                <entry   key="value.deserializer"   value="org.apache.kafka.common.serialization.StringDeserializer"/>  

            </map>

         </constructor-arg>  

    </bean>

 

    <!-- 建立consumerFactory   bean -->

    <bean   id="consumerFactory"   class="org.springframework.kafka.core.DefaultKafkaConsumerFactory">  

        <constructor-arg>  

            <ref   bean="consumerProperties"/>

        </constructor-arg>  

    </bean>

 

    <!-- 實際執行訊息消費的類 -->

    <bean   id="messageListernerConsumerService"   class="com.netease.hdone.repay.vo.ConsumerListener"/>

 

    <!-- 消費者容器配置資訊 -->

    <bean   id="containerProperties" class="org.springframework.kafka.listener.config.ContainerProperties">  

        <!-- 重要!配置topic   -->

        <constructor-arg   value="test1"/>

        <property   name="messageListener"   ref="messageListernerConsumerService"/>

    </bean>

 

    <!-- 建立kafkatemplate   bean,使用的時候,只需要注入這個bean,即可使用template的send訊息方法 -->

    <bean   id="messageListenerContainer"   class="org.springframework.kafka.listener.KafkaMessageListenerContainer"   init-method="doStart">

        <constructor-arg   ref="consumerFactory"/>

        <constructor-arg   ref="containerProperties"/>

    </bean>

 

 

有需要的朋友可以關注我的公眾號,文章每日一更



來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/28833846/viewspace-2727299/,如需轉載,請註明出處,否則將追究法律責任。

相關文章