Kafka简单入门

1 介绍Kafka

1.1 什么是事件流式处理?

从技术上讲,“事件流”是以事件 流的形式从数据库、传感器、移动设备、云服务和软件应用程序等事件产生源实时捕获数据的做法。

  • 持久化存储这些数据流,可以提供给以后进行检索
  • 实时和回顾性地操作、处理和响应事件流
  • 并根据需要将数据流路由到不同的平台或者处理程序中

所以事件流确保了数据的连续流动和解释,以便在正确的时间将正确的信息放在正确的位置

流式处理平台的特性

  • 可以让你发布和订阅流式的记录,这一方面与消息队列或者企业消息系统类似
  • 可以存储流式的记录,并且有较好的容错性
  • 可以在流式记录产生时就进行处理
    Kafka结合了三个关键功能
  • 发布(写入)和订阅(读取)事件流,包括从其他系统连续导入/导出数据
  • 可以可靠的持久化事件流
  • 能够处理实时产生的事件流或者回溯处理历史的事件流

并且这些功能都可以以分布式、高度可扩展、弹性、容错和安全的方式提供,且可以部署在裸机硬、虚拟机和容器上,也可以部署在本地和云中,自行选择

1.2 Kafka的一些概念和术语

  • Kafka是一个分布式系统,服务端和客户端通过高性能TCP网络协议进行通信
    • 服务端:作为一个或多个服务器集群运行,具有高度可扩展性和容错性:能够在发生故障时,其他服务器接管工作保证继续运行且不丢失数据
    • 客户端:通过编写分布式应用和微服务,在网络问题或计算机故障时也能以容错的方式并行、大规模读取、写入和处理事件流,且提供了多语言客户端,java、Scala等
  • Kafka作为一个集群,运行在一台或者多台服务器上.
  • Kafka 通过 topic 对存储的流数据进行分类,且消费者和生产者是完全解耦的——高扩展性的关键因素
  • 一个topic可以有0——多个生产和消费者
  • topic存在分区概念-partition,且分区可以有副本分布在不同的kafka节点中
    • 为了数据的容错性和高可用性,可以复制每个主题,甚至可以跨地理区域或数据中心进行复制,以防出现问题后没有数据副本导致数据丢失
    • 一般的复制因子为3,始终有3个数据副本,且复制是在topic-partition基本执行的
  • 每条记录中包含一个key,一个value和一个timestamp(时间戳)。

1.3 Kafka的四个核心API

  • The Producer API 允许一个应用程序发布一串流式的数据到一个或者多个Kafka topic。
  • The Consumer API 允许一个应用程序订阅一个或多个 topic ,并且对发布给他们的流式数据进行处理。
  • The Streams API 允许一个应用程序作为一个_流处理器_,消费一个或者多个topic产生的输入流,然后生产一个输出流到一个或多个topic中去,在输入输出流中进行有效的转换。
  • The Connector API 允许构建并运行可重用的生产者或者消费者,将Kafka topics连接到已存在的应用程序或者数据系统。比如,连接到一个关系型数据库,捕捉表(table)的所有变更内容。
    在这里插入图片描述

1.4 Topic、日志和消费者

topic和其日志

kafka的核心概念就是:提供一串流式的记录-topic

  • topic就是数据主题,是数据记录发布的地方,不同的topic可以区分业务系统
  • 每个topic的partition都有一个日志文件,对应的消息会存入其中,且默认存在两天
  • offset由消费者控制,通常以线性的方式增加offset
  • partition可以通过扩展从而达到扩大单个topic的容量,可以作为并行的单元集被同时消费
  • 每个partition都有一个leader,处理partition的读写,对其他的follwers同步
    消费者
  • 每个实例都是分区唯一的消费者。维护消费组中的消费关系由Kafka协议动态处理。
    • 如果新的实例加入组,他们将从组中其他成员处接管一些 partition 分区
    • 如果一个实例消失,拥有的分区将被分发到剩余的实例。
  • Kafka 只保证分区内的记录是有序的,而不保证主题中不同分区的顺序。
    • 每个 partition 分区按照key值排序足以满足大多数应用程序的需求。
  • Kafka保证发送到特定主题和分区的消息,如果越先发送,那么在日志中的偏移值就越低

1.5 Kafka的能力

消息系统能力
相比传统的消息系统,Kafka的消息被读取后还可以被保存在日志中,以便新的消费者从头消费,且可以广播给多个消费组
Kafka有更严格的顺序保证,因为传统消息系统,消息会被异步的传递,可能无序到达导致无序消费
Kafka可以让一个分区对应一个消费者来并行消费,且提供顺序保证和负载均衡
持久化能力
kafka作为消息的中间数据存储系统,能够通过备份保证容错,也就是消息到来后可以通过完全写入和写入副本后才被认为完成写入
使用磁盘结构,50kb和50TB的数据表现都是一致的,通过offset来控制读取位置,是一种高性能、低延迟、具备日志存储、备份和传播的分布式文件系统
流处理能力
Kafka最终目的是为了能够实时的流处理,可以将整个kafka看作是一个stream管道,不同的topic就是不同的节点,对stream中的数据流做不同的操作,对java的stream流也是这种概念
Kafka提供了Stream API去对一些复杂的数据变换,比如流数据的聚合或join,如果是简单的操作,那就用消费者呗
Stream API建立在kafka核心之上,使用消费者和生产者的API作为输入,在kafka中流转,且利用消费组的一些机制保证容错

2 使用的一些案例

消息传递

Kafka可以替代传统的消息代理,因为有更好的吞吐量、内置分区、复制、容错、持久化能力

活动跟踪

通过用户的页面访问活动,将不同的行为发布到不同的中心主题,可以被实时处理,实时监控,以及Hadoop或者离线数仓进行离线分析

指标

kafka可以通过各个topic的数据聚合或者数据处理后的结果产生监控数据,实时监控各项指标

日志聚合

kafka可以替代日志聚合解决方案的替代品,kafka不需要从服务器收集物理日志并放在中心位置处理,而是抽象了文件的详细信息,将日志或事件数据作为消息流进行实时低延迟的处理,且支持多个数据源和多个消费者统一处理

流处理

kafka可以将多个主题的管道 组成 “流处理的步骤管道”,原始输入数据从kafka主题中消费,聚合、转换为其他主题进一步处理的流。

事件溯源

由于kafka的offset和分区以及消息的时序性有保证,所以可以通过这个特性满足一系列操作的时间线,从而去完成各个事件的溯源

提交日志

Kafka 可以充当分布式系统的一种外部提交日志。日志有助于在节点之间复制数据,并充当故障节点恢复数据的重新同步机制,日志压缩功能有助于这种行为

3 快速入门

第一步:获取kafka

下载 最新的 Kafka 版本并解压:

$ tar -xzf kafka_2.13-3.5.0.tgz
$ cd kafka_2.13-3.5.0
第二步:启动环境

Kafka 可以使用 ZooKeeper 或 KRaft 启动

Kafka和ZooKeeper的环境
启动zookeeper

# Start the ZooKeeper service 启动zookeeper
$ bin/zookeeper-server-start.sh config/zookeeper.properties

在另一个终端启动kafka

# Start the Kafka broker service
$ bin/kafka-server-start.sh config/server.properties

Kafka和Kraft的环境
生成集群 UUID

$ KAFKA_CLUSTER_ID="$(bin/kafka-storage.sh random-uuid)"

设置日志目录格式

$ bin/kafka-storage.sh format -t $KAFKA_CLUSTER_ID -c config/kraft/server.properties

启动Kafka服务器

$ bin/kafka-server-start.sh config/kraft/server.properties
第三步:创建主题存储事件

如果想要发送一个事件或者消息,必须要在主题的基础上,也就是必须要向一个主题发送消息和事件

创建topic名称为quickstart-events,指定本机的9092端口的kafka

$ bin/kafka-topics.sh --create --topic quickstart-events --bootstrap-server localhost:9092

显示主题的分区计数等详细信息

$ bin/kafka-topics.sh --describe --topic quickstart-events --bootstrap-server localhost:9092
Topic: quickstart-events        TopicId: NPmZHyhbR9y00wMglMH2sg PartitionCount: 1       ReplicationFactor: 1    Configs:
    Topic: quickstart-events Partition: 0    Leader: 0   Replicas: 0 Isr: 0
第四步:将事件写入主题(生产)

Kafka 客户端通过网络与 Kafka 代理进行通信以写入(或读取)事件,一旦收到,代理将以持久且容错的方式存储事件,只要您需要,甚至永远存储。

$ bin/kafka-console-producer.sh --topic quickstart-events --bootstrap-server localhost:9092
This is my first event
This is my second event

一般来说开启producer后,每一行都是一个单独的事件,CTRL-C可以推出

第五步:阅读事件(消费)

打开另一个终端会话并运行控制台消费者客户端来读取刚刚创建的事件

$ bin/kafka-console-consumer.sh --topic quickstart-events --from-beginning --bootstrap-server localhost:9092
This is my first event
This is my second event

Ctrl-C可以随时停止消费者客户端。

  • 24
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 下面是一个简单的 Flink 应用程序,将 Kafka 主题中的数据读取并写入到另一个 Kafka 主题: ```java import org.apache.flink.api.common.serialization.SimpleStringSchema; import org.apache.flink.streaming.api.datastream.DataStream; import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment; import org.apache.flink.streaming.connectors.kafka.FlinkKafkaConsumer; import org.apache.flink.streaming.connectors.kafka.FlinkKafkaProducer; import org.apache.flink.streaming.connectors.kafka.KafkaSerializationSchema; import org.apache.kafka.clients.producer.ProducerRecord; import org.apache.kafka.common.serialization.StringSerializer; import java.util.Properties; public class KafkaToFlinkToFlinkKafka { public static void main(String[] args) throws Exception { // set up the execution environment final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(); // configure Kafka consumer Properties consumerProps = new Properties(); consumerProps.setProperty("bootstrap.servers", "localhost:9092"); consumerProps.setProperty("group.id", "test-group"); // create a Kafka consumer data source FlinkKafkaConsumer<String> consumer = new FlinkKafkaConsumer<>("input-topic", new SimpleStringSchema(), consumerProps); // read from Kafka DataStream<String> stream = env.addSource(consumer); // configure Kafka producer Properties producerProps = new Properties(); producerProps.setProperty("bootstrap.servers", "localhost:9092"); // create a Kafka producer sink FlinkKafkaProducer<String> producer = new FlinkKafkaProducer<>("output-topic", new KafkaSerializationSchema<String>() { @Override public ProducerRecord<byte[], byte[]> serialize(String s, Long aLong) { return new ProducerRecord<>("output-topic", s.getBytes()); } }, producerProps, FlinkKafkaProducer.Semantic.EXACTLY_ONCE); // write to Kafka stream.addSink(producer); // execute the Flink job env.execute("Kafka to Flink to Kafka"); } } ``` 在上面的代码中,我们首先创建了一个 `StreamExecutionEnvironment` 对象,然后使用 Kafka 的消费者API读取一个名为 `input-topic` 的 Kafka 主题中的数据,并将其转换为 Flink 数据流。接下来,我们创建一个 Kafka 生产者,并将数据流写入名为 `output-topic` 的 Kafka 主题。最后,我们调用 `env.execute()` 来启动 Flink 作业。 请注意,上面的代码只是一个简单入门级示例。在生产环境中,您可能需要更复杂的逻辑来处理数据并将其写入 Kafka 主题。 ### 回答2: Flink是一个流处理框架,它可以处理流式数据,并且可以与Kafka等消息队列相结合,实现数据的实时处理和分析。下面是一个使用Flink将Kafka数据写入Kafka入门级示例。 首先,我们需要引入Flink和Kafka的相关依赖包,并创建一个Flink程序入口。 ``` import org.apache.flink.api.common.serialization.SimpleStringSchema; import org.apache.flink.streaming.api.datastream.DataStream; import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment; import org.apache.flink.streaming.connectors.kafka.FlinkKafkaConsumer; import org.apache.flink.streaming.connectors.kafka.FlinkKafkaProducer; import org.apache.kafka.clients.consumer.ConsumerConfig; import org.apache.kafka.clients.producer.ProducerConfig; import java.util.Properties; public class KafkaToKafkaDemo { public static void main(String[] args) throws Exception { // 创建Flink程序入口 StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(); // 设置Kafka的相关配置 Properties properties = new Properties(); properties.setProperty(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "kafka1:9092,kafka2:9092,kafka3:9092"); properties.setProperty(ConsumerConfig.GROUP_ID_CONFIG, "flink-consumer"); properties.setProperty(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "kafka1:9092,kafka2:9092,kafka3:9092"); // 创建Kafka消费者 FlinkKafkaConsumer<String> kafkaConsumer = new FlinkKafkaConsumer<>("input-topic", new SimpleStringSchema(), properties); // 添加Kafka消费者到Flink程序中 DataStream<String> input = env.addSource(kafkaConsumer); // 创建Kafka生产者 FlinkKafkaProducer<String> kafkaProducer = new FlinkKafkaProducer<>("output-topic", new SimpleStringSchema(), properties); // 将输入数据写入Kafka input.addSink(kafkaProducer); // 执行Flink程序 env.execute("Kafka to Kafka Demo"); } } ``` 上述代码中,我们首先创建了一个Flink程序入口,然后设置了连接Kafka所需的配置信息。之后,我们创建了一个Kafka消费者,并将其添加到Flink程序中。接着,我们创建了一个Kafka生产者,并将输入的数据写入到Kafka中。最后,我们执行了Flink程序。 需要注意的是,在上述代码中,我们需要将`kafka1:9092,kafka2:9092,kafka3:9092`替换为实际的Kafka集群地址,`input-topic`和`output-topic`替换为实际的输入和输出主题名称。 这是一个简单入门级示例,演示了如何使用Flink将Kafka数据写入Kafka。你可以根据自己的需求,在此基础上进行更复杂的流处理操作。 ### 回答3: Flink是一个流计算引擎,可以用来处理大规模的实时数据流。而Kafka是一种高吞吐量的分布式消息队列,常用于构建数据流处理平台。那么如果想要将Kafka中的数据写入到另一个Kafka集群中,可以使用Flink来实现。下面是一个入门级的示例代码,演示了如何使用Java编写一个简单的Flink作业来实现将Kafka数据写入到另一个Kafka集群中。 首先,需要在项目的pom.xml文件中添加Flink和Kafka相关的依赖: ```xml <dependencies> <dependency> <groupId>org.apache.flink</groupId> <artifactId>flink-streaming-java_2.12</artifactId> <version>1.11.2</version> </dependency> <dependency> <groupId>org.apache.flink</groupId> <<artifactId>flink-connector-kafka_2.12</artifactId> <version>1.11.2</version> </dependency> </dependencies> ``` 接下来,可以编写一个简单的Flink作业,该作业从一个Kafka主题中消费数据,并将其写入到另一个Kafka主题中: ```java import org.apache.flink.api.common.serialization.SimpleStringSchema; import org.apache.flink.streaming.api.datastream.DataStream; import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment; import org.apache.flink.streaming.connectors.kafka.FlinkKafkaConsumer; import org.apache.flink.streaming.connectors.kafka.FlinkKafkaProducer; import org.apache.flink.streaming.connectors.kafka.internals.KafkaSerializationSchemaWrapper; import org.apache.kafka.clients.consumer.ConsumerConfig; import org.apache.kafka.clients.consumer.ConsumerRecord; import java.util.Properties; public class KafkaToFlinkToFlinkKafkaDemo { public static void main(String[] args) throws Exception { // 创建执行环境 StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(); // 设置Kafka消费者的配置 Properties consumerProps = new Properties(); consumerProps.setProperty(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "kafka_source:9092"); consumerProps.setProperty(ConsumerConfig.GROUP_ID_CONFIG, "flink-consumer"); // 创建一个从Kafka读取数据的数据流 DataStream<String> kafkaSource = env .addSource(new FlinkKafkaConsumer<>("input_topic", new SimpleStringSchema(), consumerProps)); // 设置Kafka生产者的配置 Properties producerProps = new Properties(); producerProps.setProperty("bootstrap.servers", "kafka_target:9092"); // 创建一个写入Kafka的数据流 // 注意:这里将消息序列化为字符串,所以消费者也需要使用相同的字符串序列化器来读取数据 DataStream<String> kafkaSink = kafkaSource .addSink(new FlinkKafkaProducer<>("output_topic", new KafkaSerializationSchemaWrapper<>(new SimpleStringSchema()), producerProps)); // 执行作业并等待任务完成 env.execute("Kafka to Flink to Kafka Demo"); } } ``` 在上述代码中,首先通过FlinkKafkaConsumer创建一个从Kafka中读取数据的数据流,然后通过FlinkKafkaProducer创建一个将数据写入到Kafka中的数据流。注意,需要为消费者和生产者配置正确的Kafka集群地址和主题名称。 以上就是一个简单的使用Flink将Kafka数据写入到另一个Kafka集群的示例。当然,实际应用中还需要考虑更多的业务需求和数据转换操作。希望对您有帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值