分佈式消息隊列Kafka的集羣部署 原 薦

1 概述

Apache Kafka 是一個分佈式高吞吐量的流消息系統,Kafka建立在ZooKeeper同步服務之上。它與Apache Storm和Spark完美集成,用於實時流數據分析,與其他消息傳遞系統相比,Kafka具有更好的吞吐量,內置分區,數據副本和高度容錯功能,因此非常適合大型消息處理應用場景。

Kafka架構簡介請查看:https://my.oschina.net/feinik/blog/1806488

2 部署圖

3 Kafka集羣部署前環境準備

3.1 安裝Java

推薦安裝Java 8,請自行安裝。

3.2 部署Zookeeper集羣

3.2.1 下載Zookeeper安裝包

這裏部署的zk版本是:zookeeper-3.4.9.tar.gz

3.2.2 安裝

1、首先在server1中安裝

(1)解壓:tar -zxvf zookeeper-3.4.9.tar.gz

(2)cd zookeeper-3.4.9/conf

(3)cp zoo_sample.cfg zoo.cfg

(4)修改zoo.cfg配置文件,內容如下

tickTime=2000

# zk數據目錄
dataDir=/home/hadoop/app/zookeeper/data

# 客戶端連接端口配置
clientPort=2181

initLimit=10

syncLimit=5

# 服務地址,2888爲集羣內個節點通信的端口,3888爲leader選舉時使用的端口
server.1=slave1:2888:3888

server.2=slave2:2888:3888

server.3=slave3:2888:3888

注:配置完後,要在dataDir配置屬性值的目錄下創建myid文件,用作集羣的節點標識,內容爲server.id屬性指定的值,如這裏server.id中的id的值爲1,所以myid文件內容爲1,其他zk節點分別爲2、3

2 、拷貝相同的一份zookeeper-3.4.9到server2、server3服務器中

3、 配置Zookeeper的環境變量並分別啓動即可完成zk集羣的部署

4 部署Kafka集羣

4.1 安裝並配置

這裏安裝的版本爲:kafka_2.12-1.1.0.tgz

注:先在server1中安裝,然後在拷貝一份至server2、server3服務器中

(1)解壓

$tar -zxvf kafka_2.12-1.1.0.tgz -C /home/app

(2)重命名

$mv kafka_2.12-1.1.0 kafka

(3)配置Kafka的環境變量

(4)修改Kafka配置文件server.properties,修改如下配置項

  • 修改broker(代理)id標識,集羣中需要保證唯一

        broker.id=1

  •   修改日誌存儲目錄配置

        log.dirs=/home/app/kafka/log-data

  • 修改Zookeeper的連接地址,Kafka自帶了Zookeeper,但是這裏我們配置成自己的zk集羣地址

        zookeeper.connect=server1:2181,server2:2181,server3:2181

(5)拷貝server1中部署好的kafka包到server2、server3服務器中

(6)修改server2中kafka的server.properties配置文件

        broker.id=2

(7)修改server3中kafka的server.properties配置文件

        broker.id=3

5 啓動集羣

5.1 先啓動Zookeeper集羣

分別在server1、server2、server3中使用如下命令啓動

$zkServer.sh start

注:也可以通過腳本來啓動Zookeeper集羣,前提是需要配置無密登錄,腳本內容如下

#!/bin/bash
if(( $# != 1 )) ; then
   echo "Usage: zk.sh {start|stop}";
   exit;
fi

cuser=`whoami`;

for i in {server1,server2,server3};
do
   echo ---------- $i---------------;
   ssh $cuser@$i "cd /home/app/zookeeper; ./bin/zkServer.sh $@";
done

 

 

5.2 啓動Kafka集羣

分別在server1、server2、server3中使用如下命令啓動

$kafka-server-start.sh -daemon /home/app/kafka/config/server.properties

注:也可以通過腳本來啓動Kafka集羣,腳本內容如下

#!/bin/bash
cuser=`whoami`;

for i in {server1,server2,server3};
do
   echo ---------- $i--------------;
   ssh $cuser@$i "/home/app/kafka/bin/kafka-server-start.sh -daemon /home/app/kafka/config/server.properties";
   echo "start complate!"
done

 

5.3 查看集羣啓動情況

通過jps命令來查看服務啓動進程,server1、server2、server3都包含Kafka、QuorumPeerMain服務進程表示集羣啓動成功

$jps
5506 Kafka
5733 Jps
5212 QuorumPeerMain

6 Kafka Java API訪問

6.1 生產者發送消息

public class ProducerClient {

    private Producer<String, String> producer;

    @Before
    public void init() {
        Properties props = new Properties();
        /**
         * broker地址列表,無需指定集羣中的所有broker地址,Producer會從給定的broker中找到其他broker的地址信息,
         * 推薦這裏配置兩個,可以防止broker宕機產生無法連接的問題
         */
        props.put("bootstrap.servers", "server1:9092,server2:9092");
        /**
         * 指定key的序列化方式,Kafka 默認提供了常用的幾種Java對象類型的序列化類
         */
        props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
        props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
        producer = new KafkaProducer<>(props);
    }


    @Test
    public void send() throws Exception {
 //此處未指定key,那麼發送的多條消息會被均勻的分佈在Topic的所有可用分區中
        ProducerRecord<String, String> record = new ProducerRecord<>("test",
                "hello word");
//消息的異步發送
        producer.send(record, new Callback() {
            @Override
            public void onCompletion(RecordMetadata metadata, Exception exception) {
                System.out.println("消息發送完成!");
            }
        });
    }

    @After
    public void close() {
        producer.close();
    }
}

注:消息的發送有三種方式:同步發送、異步發送、fire-and-forget(發送完並不關心發送結果)

同步發送:調用send方法後,返回Future對象,通過調用Future的get方法來同步等待消息的發送結果。

異步發送:調用send方法的時候指定一個回調函數,broker在接收成功消息後會回調該函數

fire-and-forget:調用send方法後並不關心發送的結果處理

6.2 消費者訂閱並消費消息

public class ConsumerClient {

    private Consumer<String, String> consumer;

    @Before
    public void init() {
        Properties props = new Properties();
        props.put("bootstrap.servers", "server1:9092,server2:9092");
        //指定消費者羣組標識
        props.put("group.id", "g1");
        //key與value的反序列化器
        props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
        props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
        consumer = new KafkaConsumer<>(props);
    }

    @Test
    public void consume() {
        //訂閱主題爲test的消息
        consumer.subscribe(Collections.singletonList("test"));
        while (true) {
            ConsumerRecords<String, String> records = consumer.poll(100);
            for (ConsumerRecord<String, String> record : records) {
                String value = record.value();
                System.out.println("接收到消息:" + value);
            }
        }
    }

    @After
    public void close() {
        consumer.close();
    }
}

7 總結

本文主要介紹了Kafka的分佈式集羣部署方式,以及Kafka依賴的第三方組件Zookeeper的集羣部署,最後通過Kafka Java API來演示了生產者發送消息與消費者消費消息的示例代碼,關於Kafka的其他使用細節,請查閱官網:http://kafka.apache.org/

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章