使用KafkaUtil以direct方式获取kafka的数据时遇到的问题

1 篇文章 0 订阅
1 篇文章 0 订阅

使用KafkaUtil以direct方式获取kafka的数据时遇到的问题

报的是nio.channels.closeException类似的错误

原因是我的server.properties配置文件里面

zookeeper的端口配错了

正确的代码是

package kafkaTest


import kafka.serializer.StringDecoder
import org.apache.spark.streaming.dstream.{DStream, InputDStream}
import org.apache.spark.streaming.kafka.KafkaUtils
import org.apache.spark.streaming.{Seconds, StreamingContext}
import org.apache.spark.{SparkConf, SparkContext}

/**
  * Created by Administrator on 2018/5/13.
  */
object kafkaTest {
  def main(args: Array[String]): Unit = {
    val conf: SparkConf = new SparkConf().setAppName("kafkaTest").setMaster("local[2]")
    val sc = new SparkContext(conf)
    val scc = new StreamingContext(sc,Seconds(2))
    //checkpoint目录
    scc.checkpoint("hdfs://hadoop02:9000/sparkStreaming")
    val TOPIC=Set("sparkstream")
    //kafkaUtils创建direct dstream
    var kafkaParams=Map("metadata.broker.list"->"hadoop02:9092")

    val dstream: DStream[String] = KafkaUtils.createDirectStream[String, String, StringDecoder, StringDecoder](scc, kafkaParams, TOPIC)
      .map(_._2)
    dstream.flatMap(line=>line.split(",")).map(x=>(x,1)).reduceByKey(_+_).print()
    /**
      * 偏移量 数据 解码器 解码器
      * K: ClassTag,
    V: ClassTag,
    KD <: Decoder[K]: ClassTag,
    VD <: Decoder[V]: ClassTag
      *  ssc: StreamingContext,
      kafkaParams: Map[String, String],
      topics: Set[String]
      * */
    scc.start()
    scc.awaitTermination()
    scc.stop()
  }
}

在 Flink 1.11 中使用 Kafka Connector ,可以通过设置 `timestamp.extractor` 参数来指定消息时间戳的提方式。如果你想要获取 Kafka 消息的日志时间,可以使用 `LogAndSkipOnInvalidTimestamp` 提方式,并将 `timestamp.extractor.watermark.delay-ms` 参数设置为 0。 具体来说,你需要在创建 Kafka 数据设置 `timestamp.extractor` 和 `timestamp.extractor.watermark.delay-ms` 参数,示例如下: ```java import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment; import org.apache.flink.streaming.connectors.kafka.FlinkKafkaConsumer; import org.apache.flink.streaming.util.serialization.SimpleStringSchema; import org.apache.flink.api.common.serialization.DeserializationSchema; import org.apache.flink.api.common.typeinfo.Types; import org.apache.flink.streaming.api.functions.AssignerWithPunctuatedWatermarks; import org.apache.flink.streaming.api.watermark.Watermark; import org.apache.flink.streaming.connectors.kafka.KafkaDeserializationSchema; import org.apache.flink.streaming.connectors.kafka.KafkaDeserializationSchemaWrapper; import org.apache.flink.streaming.connectors.kafka.KafkaDeserializationSchema.DeserializationSchemaWrapper; import java.util.Properties; import java.util.regex.Pattern; public class KafkaSourceExample { public static void main(String[] args) throws Exception { final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(); env.setParallelism(1); Properties properties = new Properties(); properties.setProperty("bootstrap.servers", "localhost:9092"); properties.setProperty("group.id", "test"); FlinkKafkaConsumer<String> consumer = new FlinkKafkaConsumer<>( Pattern.compile("test-topic.*"), new LogAndSkipOnInvalidTimestamp<>(), // 设置 timestamp.extractor properties); consumer.setStartFromEarliest(); consumer.assignTimestampsAndWatermarks(new AssignerWithPunctuatedWatermarks<String>() { @Override public long extractTimestamp(String element, long previousTimestamp) { // 不需要实现,因为我们已经在 Kafka Consumer 中设置了 timestamp.extractor return 0; } @Override public Watermark checkAndGetNextWatermark(String lastElement, long extractedTimestamp) { // 不需要实现,因为我们已经在 Kafka Consumer 中设置了 timestamp.extractor.watermark.delay-ms return null; } }); env .addSource(consumer) .print(); env.execute("Kafka Source Example"); } public static class LogAndSkipOnInvalidTimestamp<T> extends DeserializationSchemaWrapper<T> { public LogAndSkipOnInvalidTimestamp() { super(new SimpleStringSchema()); } @Override public T deserialize(byte[] messageKey, byte[] message, String topic, int partition, long offset) throws Exception { try { // 提消息时间戳 Long timestamp = Long.valueOf(topic.split("-")[1]); // 构造一个带时间戳的元组 return (T) Tuple2.of(new String(messageKey), new String(message), timestamp); } catch (Exception e) { // 如果提时间戳失败,则打印一条日志并跳过该条消息 System.err.println("Skip invalid message: " + new String(message)); return null; } } } } ``` 上述示例代码中,我们通过自定义 `LogAndSkipOnInvalidTimestamp` 类来实现了 `KafkaDeserializationSchema` 接口,并在其中提Kafka 消息的日志时间戳。在 `deserialize` 方法中,我们将 Kafka 消息转换为一个带时间戳的元组,并在返回进行了类型转换。 在 `main` 函数中,我们通过 `new LogAndSkipOnInvalidTimestamp<>()` 来设置了 `timestamp.extractor` 参数,并将 `timestamp.extractor.watermark.delay-ms` 参数设置为 0。这样就可以在 Flink SQL 中使用时间戳的元组来进行数据处理了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值