【Flink】Flink_Kakfa自定义输出分区

  • 在我们将消息写入kafka的topic时,我们可以通过FlinkkafkaPartitioner指定写入topic的哪个分区。
  • 在不指定的情况下,默认的分区器会将每个数据任务映射到一个单独的kafka分区中,即单个任务的所有记录都会发往同一分区。
  • 如果任务数多余分区数,则每个分区可能会包含多个任务发来的记录。 而如果任务数小于分区数,则默认配置会导致有些分区收不到数据。
    若此时恰好有使用事件时间的Flink应用消费了该Topic,那么可能会导致问题;
    • 导致问题的原因
      • Flink_Kafka为了利用Kafka各个分区的保序性特征,分配器会在每个分区上定义水位线,然后再对各个分区之间的水位线进行合并。
      • 因此,如果某一分区变成非活跃状态且不再提供消息,那么这个数据源任务的水位线将无法前进,继而导致整个应用的水位线都不会前进。因此单个非活跃的分区会导致整个应用停止运行。

示例:Flink自定义kakfa输出分区

object addSink_kafka_并自定义序列化和分区 extends App {

  import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment

  val streamLocal = StreamExecutionEnvironment.createLocalEnvironment(3)

  import org.apache.flink.api.scala._ //如果数据是有限的(静态数据集)可以引入这个包
  val dataStream: DataStream[(String, Int)] = streamLocal.fromElements(("flink_er", 3), ("f", 1), ("c", 2), ("c", 1), ("d", 5))

  val properties = new Properties()
  properties.setProperty("bootstrap.servers", "master:9092")
  val flinkKafkaProducer = new FlinkKafkaProducer(
    "ceshi01",
    new MySchema(),
    properties,
    Optional.of(new FlinkKafkaPartitioner[(String, Int)] {
      /**
        * @param record      正常的记录
        * @param key         KeyedSerializationSchema中配置的key
        * @param value       KeyedSerializationSchema中配置的value
        * @param targetTopic targetTopic
        * @param partitions  partition列表[0, 1, 2, 3, 4]
        * @return partition
        */
      override def partition(record: (String, Int), key: Array[Byte], value: Array[Byte], targetTopic: String, partitions: Array[Int]): Int = {
        Math.abs(new String(key).hashCode() % partitions.length)
      }
    })
  )
  dataStream.addSink(flinkKafkaProducer)

  streamLocal.execute()
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值