1.Kafka
Kafka是一个分布式发布——订阅消息传递系统。Kafka快速、可扩展且耐用。它保留主题中的消息源。生产者将数据写入主题,消费者从主题中读取数据。
Zookeeper需要覆盖Kafka生态系统,因此有必要下载它,更改其属性并最终设置环境。在运行Zookeeper之后,应该下载Kafka,然后开发人员可以借助一些指令创建代理,集群和主题
2.什么是消息系统?
数据工程中最具挑战性的部分之一是如何从不同点收集和传输大量数据到分布式系统进行处理和分析。需要通过消息队列正确地分离大量数据,因为如果一部分数据无法传送,则可以在系统恢复时传输和分析其他数据。有两种消息排队,对于上述目的,它们都是可靠的和异步的。点对点(Point to point)和发布者——订阅者(publisher-subscriber)。
3.点对点
在点对点或一对一中,有一个发件人和正在监听发件人的多个消费者。当一个消费者从队列收到消息时,该特定消息将从队列中消失,而其他消费者无法获得该消息
4.发布和订阅系统
在发布者——订阅者中,发布者向同时收听发布者的多个消费者或订阅者发送消息,并且每个订阅者可以获得相同的消息。数据应通过数据管道传输,数据管道负责整合来自数据源的数据。
5.术语介绍
Broker : Kafka集群包含一个或多个服务器,这种服务器被称为broker
Topic : 每条发布到Kafka集群的消息都有一个类别,这个类别被称为Topic。(物理上不同Topic的消息分开存储,逻辑上一个Topic的消息虽然保存于一个或多个broker上但用户只需指定消息的Topic即可生产或消费数据而不必关心数据存于何处)
Partition : Partition是物理上的概念,每个Topic包含一个或多个Partition.
Producer : 负责发布消息到Kafka broker
Consumer : 消息消费者,向Kafka broker读取消息的客户端。
Consumer Group : 每个Consumer属于一个特定的Consumer Group(可为每个Consumer指定group name,若不指定group name则属于默认的group)。
kafka结构
1.什么是Kafka结构?
Kafka是分布式发布者——订阅者,具有高吞吐量,可以处理大量数据。Kafka是实时数据流,每秒可处理200万次写入。
主题和发布者
有一个发布者发送消息。消息根据主题进行分类,每个主题都有一个或多个分区,并有自己的偏移地址。例如,如果我们为一个主题分配复制因子= 2,那么Kafka将为每个分区创建两个相同的副本并在群集中找到它。
集群和Brokers
Kafka集群包括代理——服务器或节点,每个代理可以位于不同的机器中,并允许订户选择消息。因此,复制就像备份分区一样,这意味着Kafka是持久的,这有助于容错。
Zookeeper
Kafka集群不保留其自身生态系统的元数据,因为它是无状态的。因此,Kafka依赖于Zookeeper来跟踪元数据。Zookeeper应该首先启动。实际上,Zookeeper是brokers和consumers之间的接口,它的存在是容错的必要条件。Kafka代理负责负载平衡,假设该主题有一个主题和多个分区,每个分区都有一个领导者,定期确认其与Zookeeper的偏移量。因此,如果一个节点或代理失败,Kafka可以从Zookeeper请求的最后一个偏移地址继续操作,因此Zookeeper在崩溃情况下在Kafka恢复中起着至关重要的作用。
eg:
package com.example.kafkademo.controller;
import org.springframework.web.bind.annotation.RestController;
import org.apache.kafka.clients.consumer.*;
import java.io.InputStream;
import java.util.Collections;
import java.util.Properties;
@RestController
public class kafkaText {
public static void main(String[] args) throws Exception {
try {
Properties props = new Properties();
//连接Kafka集群的地址,多个地址以逗号分隔
props.put("bootstrap.servers", "*,*,*");
//消费者所属消费组的唯一标识
props.put("group.id", "g_xinhuankeji");
//consumer提交方式设置,设置是否自动提交
props.put("enable.auto.commit", "true");
//当消费者读取偏移量无效的情况下,需要重置消费起始位置,默认为latest(从消费者启动后生成的记录),另外一个选项值是 earliest,将从有效的最小位移位置开始消费
props.put("auto.offset.reset", "latest");
//定期提交消费offset到kafka
props.put("auto.commit.interval.ms", "1000");
//消息中key反序列化类,需要和Producer中key序列化类相对应
props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
//消息中value的反序列化类,需要和Producer中Value序列化类相对应
props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
props.put("security.protocol", "SASL_PLAINTEXT");
props.put("sasl.mechanism", "PLAIN");
String setProperty = System.setProperty("java.security.auth.login.config", "D:\\project\\kafkademo\\src\\main\\resources\\kafka_client_jaasecs.conf");
System.out.println("create KafkaConsumer");
System.out.println("receive data");
KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props);
consumer.subscribe(Collections.singletonList("user_subject_2420574847862784"));
while (true) {
ConsumerRecords<String, String> records = consumer.poll(100);
for (ConsumerRecord<String, String> record : records) {
System.out.printf("consumer:>>>>>offset = %d, key= %s , value = %s\n", record.offset(),record.key(), record.value());
}
}
} catch (Exception ex) {
ex.printStackTrace();
System.out.println("when calling kafka output error." + ex.getMessage());
}
}
}