Kafka API

引用致谢:

https://www.cnblogs.com/xuwujing/p/8432984.html

一、概念

1.什么是Kafka?
Kafka是一种高吞吐量的分布发布-订阅消息系统,专为超高吞吐量的实时日志采集、实时数据同步、实时数据计算等场景来设计
2.主要分为
生产者API
消费者API

在这里插入图片描述
3.流处理架构

在这里插入图片描述

4.离散数据流(DStream)
DStream代表了一系列连续的RDDs

每个RDD都包含一个时间间隔内的数据
DStream既是输入的数据流,也是转换处理过的数据流
对DStream的转换操作即是对具体RDD操作

在这里插入图片描述

二、生产者API

这里在idea中使用kafka

1.添加 pom.xml文件依赖

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

2.具体实现类Demo01_KafkaProducer

package cn.kgc.kafka

import java.util.Properties

import org.apache.kafka.clients.producer.{KafkaProducer, ProducerRecord}

/**
  * Created by wangchunhui on 2021/1/19 8:59
  * 第一步:创建test topic
  * 第二步:启动消费者控制台 kafka-console-consumer.sh --bootstrap-server singleNode:9092 --topic test
  * 第三部:执行程序, 查看控制台输出 hello world
  */
object Demo01_KafkaProducer {
  def main(args: Array[String]): Unit = {
    // 创建配置
    val props = new Properties()
    // 设置Kafka集群
    props.put("bootstrap.servers", "nodefour:9092")
    // 设置ack
    // 0: 不需要leader partition确认接收成功, 将消息发送到leader partition即可
    // 1:需要等待leader partition确认接收成功
    // -1(all): 需要等待leader partition以及ISR列表中的follower都确认接收成功
    props.put("acks", "all")
    // 设置key和value的序列化
    props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer")
    props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer")

    // 创建一个Kafka的生产者
    val producer = new KafkaProducer[String,String](props)
    // 发送消息 三个参数: ①topic, ②key, ③value
    producer.send(new ProducerRecord[String,String]("test","1001","zhangsan"))
    // 关闭资源
    producer.close()
  }
}

3.在虚拟机中操作

kafka-console-consumer.sh  --bootstrap-server hadoop100:9092 --topic abc --from-beginning  --property print.key=true

三、消费者API

1.实现类Demo02_KafkaConsumer

package cn.kgc.kafka

import java.util
import java.util.Properties

import org.apache.kafka.clients.consumer.{ConsumerRecord, ConsumerRecords, KafkaConsumer}

/**
  * Created by wangchunhui on 2021/1/19 9:34
  */
object Demo02_KafkaConsumer {
  def main(args: Array[String]): Unit = {
    // 创建一个配置
    val props = new Properties()
    // 配置Kafka集群的ip和端口号
    props.put("bootstrap.servers", "nodefour:9092")
    // 设置消费者组的id, 如果有多个相同id的消费者程序, 那么他们将在一个组当中
    props.put("group.id", "testGroup1")
    // 开启自动提交[默认就是开启]
    props.put("enable.auto.commit", "true")
    // 每隔5000ms提交一次
    props.put("auto.commit.interval.ms", "1000") //默认值5000
    // key和value的序列化
    props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer")
    props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer")
    // 创建一个Consumer客户端
    val consumer = new KafkaConsumer[String, String](props)
    // consumer消费
    val topics = new util.ArrayList[String]()
    topics.add("test2")
    // 订阅topic
    consumer.subscribe(topics)
    // 为了能够一直从Kafka中消费数据, 使用 while true 死循环
    while (true) {
      // 设置超时时间, 单位是毫秒, 返回一些条数据
      val records: ConsumerRecords[String, String] = consumer.poll(1000)
      // 对这些数据进行遍历输出
      val iter: util.Iterator[ConsumerRecord[String, String]] = records.iterator()
      while (iter.hasNext) {
        val next: ConsumerRecord[String, String] = iter.next()
        println(s"partition = ${next.partition()}, offset=${next.offset()}\nkey = ${next.key()}, value = ${next.value()}")
      }
    }
  }
}

2.手动提交Offset
为什么要设置手动提交?
(1)自动提交是在kafka拉取到数据之后就直接提交,这样很容易丢失数据
(2)很多情况下我们需要从kafka成功拉取数据之后,对数据进行相应的处理之后再进行提交
具体实现类Demo03_KafkaConsumerManualOffset

package cn.kgc.kafka

import java.util
import java.util.Properties

import org.apache.kafka.clients.consumer.{ConsumerRecord, ConsumerRecords, KafkaConsumer}

/**
  * Created by wangchunhui on 2021/1/19 10:16
  */
object Demo03_KafkaConsumerManualOffset {
  def main(args: Array[String]): Unit = {
    // 创建一个配置
    val props = new Properties()
    // 配置Kafka集群的ip和端口号
    props.put("bootstrap.servers", "nodefour:9092")
    // 设置消费者组的id, 如果有多个相同id的消费者程序, 那么他们将在一个组当中
    props.put("group.id", "testGroup1")
    // 关闭自动提交[默认就是开启]
    props.put("enable.auto.commit", "false")
    // key和value的反序列化
    props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer")
    props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer")
    // 创建一个Consumer客户端
    val consumer = new KafkaConsumer[String, String](props)
    // consumer消费
    val topics = new util.ArrayList[String]()
    topics.add("test2")
    // 订阅topic
    consumer.subscribe(topics)
    // 创建一个集合, 用来存放消息的个数
    val buffer = new util.ArrayList[ConsumerRecord[String, String]]()
    // 为了能够一直从Kafka中消费数据, 使用 while true 死循环
    while (true) {
      // 设置超时时间, 单位是毫秒, 返回一些条数据
      val records: ConsumerRecords[String, String] = consumer.poll(1000)
      // 对这些数据进行遍历输出
      val iter: util.Iterator[ConsumerRecord[String, String]] = records.iterator()
      while (iter.hasNext) {
        val next: ConsumerRecord[String, String] = iter.next()
        println(s"partition = ${next.partition()}, offset=${next.offset()}\nkey = ${next.key()}, value = ${next.value()}")
        buffer.add(next)
      }
      if(buffer.size()>5){
        // 手动提交offset有两种, 一种是同步阻塞方式, 一种是异步非阻塞方式
        consumer.commitAsync()
        // consumer.commitSync()
        buffer.clear()
      }

    }
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值