Kafka介紹、安裝及使用

Apache Kafka 企業級消息隊列

2.Apache Kafka是什麼

是什麼?有什麼用?怎麼用?

2.1簡介

1) Apache Kafka 是一個消息隊列(生產者消費者模式)

2) Apache Kafka 目標:構建企業中統一的、高通量的、低延時的消息平臺。

3) 大多的是消息隊列(消息中間件)都是基於JMS標準實現的,Apache Kafka 類似於JMS的實現。

ActiveMQ

2.2作用(重點)

1) 作爲緩衝,來異構、解耦系統。

  • 用戶註冊需要完成多個步驟,每個步驟執行都需要很長時間。代表用戶等待時間是所有步驟的累計時間。

  • 爲了減少用戶等待的時間,使用並行執行執行,有多少個步驟,就開啓多少個線程來執行。代表用戶等待時間是所有步驟中耗時最長的那個步驟時間。

  • 有了新得問題:開啓多線程執行每個步驟,如果以一個步驟執行異常,或者嚴重超時,用戶等待的時間就不可控了。

  • 通過消息隊列來保證。

    • 註冊時,立即返回成功。
    • 發送註冊成功的消息到消息平臺。
    • 對註冊信息感興趣的程序,可以消息消息。

3.Apache Kafka的基本架構

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-11Vt9Zzu-1591777000393)(/1544783011567.png)]

Kafka Cluster:由多個服務器組成。每個服務器單獨的名字broker(掮客)。

Kafka Producer:生產者、負責生產數據。

Kafka consumer:消費者、負責消費數據。

Kafka Topic: 主題,一類消息的名稱。存儲數據時將一類數據存放在某個topic下,消費數據也是消費一類數據。

​ 訂單系統:創建一個topic,叫做order。

​ 用戶系統:創建一個topic,叫做user。

​ 商品系統:創建一個topic,叫做product。

注意:Kafka的元數據都是存放在zookeeper中。

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-9jjkyEgQ-1591777000396)(/1546867191336.png)]

4.搭建Kafka集羣

4.1.準備3臺虛擬機

本機也要加

192.168.72.141 node01
192.168.72.142 node02
192.168.72.143 node03

4.2.初始化環境

1)安裝jdk、安裝zookeeper

2)安裝目錄

​ 安裝包存放的目錄:/export/software

​ 安裝程序存放的目錄:/export/servers

​ 數據目錄:/export/data

​ 日誌目錄:/export/logs

mkdir -p /export/servers/
mkdir -p /export/software/
mkdir -p /export/data/
mkdir -p /export/logs/ 

3)安裝用戶

​ 安裝hadoop,會創建一個hadoop用戶

​ 安裝kafka,創建一個kafka用戶

​ 或者 創建bigdata用戶,用來安裝所有的大數據軟件。

本例:使用root用戶

4)驗證環境

a) jdk環境

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-c3GiFZDj-1591777000400)(/1544866443419.png)]

b) zookeeper環境

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-YcSUbXxH-1591777000407)(/1544786940692.png)]

4.3.搭建Kafka集羣

4.3.1.準備安裝包

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-1kO6e8hB-1591777000409)(/1544787035414.png)]

由於kafka是scala語言編寫的,基於scala的多個版本,kafka發佈了多個版本。

其中2.11是推薦版本。

4.3.2.下載安裝包及解壓

tar -zxvf kafka_2.11-1.0.0.tgz -C /export/servers/
cd /export/servers/
mv kafka_2.11-1.0.0 kafka

1)刪除之前的安裝記錄

2)解壓文件

3)重命名

4.3.3.查看目錄及修改配置文件

4.3.3.1查看目錄

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-NG6i6T5r-1591777000411)(/1544787057518.png)]

4.3.3.2修改配置文件

進入配置目錄,查看server.properties文件

cat server.properties |grep -v “#”

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-EQ7qc9Fc-1591777000412)(/1544787073410.png)]

通過以上命令,查看到了默認的配置文件,對默認的文件進行修改。

修改三個地方

vi server.properties

1) Borker.id

2) 數據存放的目錄,注意目錄如果不存在,需要新建下。

3) zookeeper的地址信息

#broker.id 標識了kafka集羣中一個唯一broker。
broker.id=0
num.network.threads=3
num.io.threads=8
socket.send.buffer.bytes=102400
socket.receive.buffer.bytes=102400
socket.request.max.bytes=104857600

#存放生產者生產的數據 數據一般以topic的方式存放 
log.dirs=/export/data/kafka
num.partitions=1
num.recovery.threads.per.data.dir=1
offsets.topic.replication.factor=1
transaction.state.log.replication.factor=1
transaction.state.log.min.isr=1
log.retention.hours=168
log.segment.bytes=1073741824
log.retention.check.interval.ms=300000

#zk的信息
zookeeper.connect=node01:2181,node02:2181,node03:2181
zookeeper.connection.timeout.ms=6000
group.initial.rebalance.delay.ms=0

#可選配置
delete.topic.enable=true
host.name=192.168.72.141

4.3.4.分發配置文件及修改brokerid

將修改好的配置文件,分發到node02,node03上。

先在node02、node03上刪除以往的安裝記錄

# 創建一個數據存放目錄   /export/data/kafka  
mkdir -p /export/data/kafka

分發安裝包

scp -r /export/servers/kafka/ node02:/export/servers/   
scp -r /export/servers/kafka/ node03:/export/servers/    

修改node02上的broker.id

vi /export/servers/kafka/config/server.properties   

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-Er16x018-1591777000414)(/1544787262549.png)]

修改node03上的broker.id

vi /export/servers/kafka/config/server.properties

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-MKoOTjAm-1591777000415)(/1544787309119.png)]

4.3.4.啓動集羣

cd /export/servers/kafka/bin
nohup ./kafka-server-start.sh /export/servers/kafka/config/server.properties 2>&1 &

4.3.5.查看Kafka集羣

由於kafka集羣並沒有UI界面可以查看。

需要藉助外部工具,來查看kafka的集羣

這個工具是一個java程序,必須要安裝好JDK

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-M7qM7MdS-1591777000416)(/1544787326910.png)]

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-zNjY7bmb-1591777000417)(/1544787370274.png)]

5.操作集羣的兩種方式

需求:訂單系統,需要發送消息。 後面後3個程序需要接受這個消息,並做後續的處理。

5.1.使用控制檯運行

1) 創建一個訂單的topic。

./kafka-topics.sh --create --zookeeper node01:2181 --replication-factor 1 --partitions 1 --topic order   

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-R3M3am6C-1591777000419)(/1544787440943.png)]

2) 編寫代碼啓動一個生產者,生產數據

./kafka-console-producer.sh --broker-list node01:9092 --topic order

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-FwtPuN9h-1591777000421)(/1544787445692.png)]

3) 編寫代碼啓動一個消費者,消費數據

./kafka-console-consumer.sh --zookeeper node01:2181 --from-beginning --topic order

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-DNBFYJkT-1591777000422)(/1544787451882.png)]

5.2.使用Java api運行

1)java工程-maven,依賴。

<dependency>     
    <groupId>org.apache.kafka</groupId>     
    <artifactId>kafka-clients</artifactId>     
    <version>0.11.0.1</version>   
</dependency>

2) 編寫代碼-寫生產者的代碼

/**
 * 訂單的生產者代碼
 */
public class OrderProducer {
    public static void main(String[] args) throws InterruptedException {
        /* 1、連接集羣,通過配置文件的方式
         * 2、發送數據-topic:order,value
         */
        Properties props = new Properties();
        props.put("bootstrap.servers", "node01:9092");
        props.put("acks", "all");
        props.put("retries", 0);
        props.put("batch.size", 16384);
        props.put("linger.ms", 1);
        props.put("buffer.memory", 33554432);
        props.put("key.serializer",
                  "org.apache.kafka.common.serialization.StringSerializer");
        props.put("value.serializer",
                  "org.apache.kafka.common.serialization.StringSerializer");
        KafkaProducer<String, String> kafkaProducer = new KafkaProducer<String, String>(props);
        for (int i = 0; i < 1000; i++) {
            // 發送數據 ,需要一個producerRecord對象,最少參數 String topic, V value
            kafkaProducer.send(new ProducerRecord<String, String>("order", "訂單信息!"+i));
            Thread.sleep(100);
        }
    }
}

3) 編寫代碼-寫消費者的代碼

/**
 * 消費訂單數據--- javaben.tojson
 */
public class OrderConsumer {
    public static void main(String[] args) {
        // 1、連接集羣
        Properties props = new Properties();
        props.put("bootstrap.servers", "node01:9092");
        props.put("group.id", "test");
        props.put("enable.auto.commit", "true");
        props.put("auto.commit.interval.ms", "1000");
        props.put("key.deserializer",
                  "org.apache.kafka.common.serialization.StringDeserializer");
        props.put("value.deserializer",
                  "org.apache.kafka.common.serialization.StringDeserializer");
        KafkaConsumer<String, String> kafkaConsumer = new KafkaConsumer<String, String>(props);
        //2、發送數據 發送數據需要,訂閱下要消費的topic。  order
        kafkaConsumer.subscribe(Arrays.asList("order"));
        while (true) {
            ConsumerRecords<String, String> consumerRecords = kafkaConsumer.poll(100);// jdk queue offer插入、poll獲取元素。 blockingqueue put插入原生,take獲取元素
            for (ConsumerRecord<String, String> record : consumerRecords) {
                System.out.println("消費的數據爲:" + record.value());
            }
        }
    }
}      

如果本機沒有修改hosts ,用命令的方式可以發送和接收數據,用java代碼發送接收不了

6.Apache Kafka原理

6.1.Apache Kafka原理-分片與副本機制

bin/kafka-topics.sh --create --zookeeper node01:2181 --replication-factor 2 --partitions 3 --topic order

分片:solrcloud中有提及到。

​ 當數據量非常大的時候,一個服務器存放不了,就將數據分成兩個或者多個部分,存放在多臺服務器上。每個服務器上的數據,叫做一個分片。

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-x8Tyhczg-1591777000423)(/1544789688464.png)]

副本:solrcloud中有提及到。

​ 當數據只保存一份的時候,有丟失的風險。爲了更好的容錯和容災,將數據拷貝幾份,保存到不同的機器上。

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-4q1FKuLn-1591777000424)(/1544789701790.png)]

6.2.Apache Kafka原理-消息存儲及查詢機制

6.2.1.文件存儲機制

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-7M7VdPKn-1591777000425)(/1544795613584.png)]

​ segment段中有兩個核心的文件一個是log,一個是index。 當log文件等於1G時,新的會寫入到下一個segment中。

​ 通過下圖中的數據,可以看到一個segment段差不多會存儲70萬條數據。

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-JzIFV44F-1591777000427)(/1544795630398.png)]

6.2.2.文件查詢機制

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-yMZBa8RZ-1591777000428)(/1544795642211.png)]

6.3.Apache Kafka原理-生產者數據分發策略

kafka在數據生產的時候,有一個數據分發策略。默認的情況使用DefaultPartitioner.class類。

這個類中就定義數據分發的策略。

1) 如果是用戶制定了partition,生產就不會調用DefaultPartitioner.partition()方法

​ 數據分發策略的時候,可以指定數據發往哪個partition。

​ 當ProducerRecord 的構造參數中有partition的時候,就可以發送到對應partition上

/**
 * Creates a record to be sent to a specified topic and partition
 *
 * @param topic The topic the record will be appended to
 * @param partition The partition to which the record should be sent
 * @param key The key that will be included in the record
 * @param value The record contents
 */
public ProducerRecord(String topic, Integer partition, K key, V value) {
    this(topic, partition, null, key, value, null);
}

2) 當用戶指定key,使用hash算法。如果key一直不變,同一個key算出來的hash值是個固定值。如果是固定值,這種hash取模就沒有意義。

Utils.toPositive(Utils.murmur2(keyBytes)) % numPartitions

​ 如果生產者沒有指定partition,但是發送消息中有key,就key的hash值。

/**
 * Create a record to be sent to Kafka
 * 
 * @param topic The topic the record will be appended to
 * @param key The key that will be included in the record
 * @param value The record contents
 */
public ProducerRecord(String topic, K key, V value) {
    this(topic, null, null, key, value, null);
}       

3) 當用既沒有指定partition也沒有key。

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-JegZyeLy-1591777000429)(/1544795702853.png)]

​ 既沒有指定partition,也沒有key的情況下如何發送數據。

​ 使用輪詢的方式發送數據。

/**
 * Create a record with no key
 * 
 * @param topic The topic this record should be sent to
 * @param value The record contents
 */
public ProducerRecord(String topic, V value) {
    this(topic, null, null, null, value, null);
}   

6.4.Apache Kafka原理-消費者的負載均衡機制

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-wJDlqlbk-1591777000430)(/1544795787490.png)]

一個partition只能被一個組中的成員消費。

所以如果消費組中有多於partition數量的消費者,那麼一定會有消費者無法消費數據。

6.5.Apache Kafka原理-消息不丟失機制

6.5.1.生產者端消息不丟失

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-qkDI4do7-1591777000431)(/1544789762719.png)]

1) 消息生產分爲同步模式和異步模式

2) 消息確認分爲三個狀態

​ a) 0:生產者只負責發送數據

​ b) 1:某個partition的leader收到數據給出響應

​ c) -1:某個partition的所有副本都收到數據後給出響應

3) 在同步模式下

​ a) 生產者等待10S,如果broker沒有給出ack響應,就認爲失敗。

​ b) 生產者重試3次,如果還沒有響應,就報錯。

4) 在異步模式下

​ a) 先將數據保存在生產者端的buffer中。Buffer大小是2萬條。

​ b) 滿足數據閾值或者數量閾值其中的一個條件就可以發送數據。

​ c) 發送一批數據的大小是500條。

如果broker遲遲不給ack,而buffer又滿了。

開發者可以設置是否直接清空buffer中的數據。

6.5.2.Borker端消息不丟失

broker端的消息不丟失,其實就是用partition副本機制來保證。

Producer ack -1. 能夠保證所有的副本都同步好了數據。其中一臺機器掛了,並不影像數據的完整性。

6.5.3.消費者端消息不丟失

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-3pKJOTVq-1591777000432)(/1544795493081.png)]

只要記錄offset值,消費者端不會存在消息丟失的可能。只會重複消費。

-1:某個partition的所有副本都收到數據後給出響應

3) 在同步模式下

​ a) 生產者等待10S,如果broker沒有給出ack響應,就認爲失敗。

​ b) 生產者重試3次,如果還沒有響應,就報錯。

4) 在異步模式下

​ a) 先將數據保存在生產者端的buffer中。Buffer大小是2萬條。

​ b) 滿足數據閾值或者數量閾值其中的一個條件就可以發送數據。

​ c) 發送一批數據的大小是500條。

如果broker遲遲不給ack,而buffer又滿了。

開發者可以設置是否直接清空buffer中的數據。

6.5.2.Borker端消息不丟失

broker端的消息不丟失,其實就是用partition副本機制來保證。

Producer ack -1. 能夠保證所有的副本都同步好了數據。其中一臺機器掛了,並不影像數據的完整性。

6.5.3.消費者端消息不丟失

[外鏈圖片轉存中…(img-3pKJOTVq-1591777000432)]

只要記錄offset值,消費者端不會存在消息丟失的可能。只會重複消費。

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