1.Flink一览

Flink一览

什么是Flink

Apache Flink is a framework and distributed processing engine for stateful computations over unbounded and bounded data streams. Apache Flink 是一个框架和分布式处理引擎,用于在无边界和有边界数据流上进行有状态的计算。Flink 能在所有常见集群环境中运行,并能以内存速度和任意规模进行计算。

  • 状态是对数据的保存,比如上网时的chche就是状态
  • 实时性要求高的一般是流处理批,处理能做的,流处理都可以做
  • Flink可以处理的流有无界流和有界流

有界数据和无界数据

无界流有开始没有结束,对于无界数据在收取后必须立即做出处理,使用流处理的方式处理无界数据 流处理的特点是无界、实时, 无需针对整个数据集执行操作,而是对通过系统传输的每个数据项执行操作,一般用于实时统计。

有界流有开始有结束,区间确定,采用批处理的方式处理 批处理的特点是有界、持久、大量,非常适合需要访问全套记录才能完成的计算工作,一般用于离线统计

这两个概念在The Dataflow Model: A Practical Approach to BalancingCorrectness, Latency, and Cost in Massive-Scale,Unbounded, Out-of-Order Data Processing提出。

分层Api

lambda架构

lambda架构

特点

优点?

缺点

flink与sparkStreaming的比较

  1. mirco-batching和stream的区别.sparkStreaming实际一次处理一个微批,而flink一个处理一个event数据
  2. spark采用RDD模型,spark streaming 的DStream 实际上也就是一组组小批数据RDD的集合。flink 基本数据模型是数据流,以及事件(Event)序列
  3. spark 是批计算,将DAG划分为不同的 stage,一个完成后才可以计算下一个。flink 是标准的流执行模式,一个事件在一个节点处理完后可以直接发往下一个节点进行处理

Rest接口

Flink的优势

精确一次(exactly-once)的状态一致性保证。事件时间(event-time)和处理时间(processing-tme)语义。即使对于无序事件流,事件时间(event-time)语义仍然能提供一致且准确的结果。而处理时间(processing-time)语义可用于具有极低延迟要求的应用程序。

每秒处理数百万个事件,毫秒级延迟。 Flink应用程序可以扩展为在数千个核(cores)上运行。

连接到最常用的存储系统,如Apache Kafka,Apache Cassandra,Elasticsearch,JDBC,Kinesis和(分布式)文件系统,如HDFS和S3。

由于其高可用的设置(无单点故障),以及与Kubernetes,YARN和Apache Mesos的紧密集成,再加上从故障中快速恢复和动态扩展任务的能力,Flink能够以极少的停机时间7*24全天候运行流应用程序。

能够更新应用程序代码并将作业(jobs)迁移到不同的Flink集群,而不会丢失应用程序的状态。

详细且可自定义的系统和应用程序指标集合,以提前识别问题并对其做出反应。

最后但同样重要的是,Flink也是一个成熟的批处理器。

有状态的 Flink 程序针对本地状态访问进行了优化。任务的状态始终保留在内存中,如果状态大小超过可用内存,则会保存在能高效访问的磁盘数据结构中。任务通过访问本地(通常在内存中)状态来进行所有的计算,从而产生非常低的处理延迟。Flink 通过定期和异步地对本地状态进行持久化存储来保证故障场景下精确一次的状态一致性。

Flink的运行时架构

jobManager

Master

TaskManager

Slave

Resoucre Manger

Dispacher

Flink的wordCount

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package cn.lpc

import org.apache.flink.streaming.api.scala._
import org.apache.flink.streaming.api.windowing.time.Time

/**
 * Skeleton for a Flink Streaming Job.
 *
 * For a tutorial how to write a Flink streaming application, check the
 * tutorials and examples on the <a href="https://flink.apache.org/docs/stable/">Flink Website</a>.
 *
 * To package your application into a JAR file for execution, run
 * 'mvn clean package' on the command line.
 *
 * If you change the name of the main class (with the public static void main(String[] args))
 * method, change the respective entry in the POM.xml file (simply search for 'mainClass').
 */
case class WordCount(word:String,count:Long)

object StreamingJob {
  def main(args: Array[String]) {
    // set up the streaming execution environment
    val env = StreamExecutionEnvironment.getExecutionEnvironment
    val text: DataStream[String] = env.socketTextStream("hadoop101", 9999, '\n')
    val wordCount: DataStream[WordCount] = text.flatMap(t => t.split("\\s"))
        .map(word => WordCount(word, 1))
        .keyBy("word")
        .timeWindow(Time.seconds(5))
        .sum("count")
    wordCount.print().setParallelism(1)

    /*
     * Here, you can start creating your execution plan for Flink.
     *
     * Start with getting some data from the environment, like
     *  env.readTextFile(textPath);
     *
     * then, transform the resulting DataStream[String] using operations
     * like
     *   .filter()
     *   .flatMap()
     *   .join()
     *   .group()
     *
     * and many more.
     * Have a look at the programming guide:
     *
     * https://flink.apache.org/docs/latest/apis/streaming/index.html
     *
     */

    // execute program
    env.execute("Flink Streaming Scala API Skeleton")
  }
}
### Flink 自定义触发器(Trigger)实现 在 Apache Flink 中,`Trigger` 是用于控制何时计算窗口的结果的核心组件之一。默认情况下,Flink 提供了一些内置的 `Trigger` 实现,但如果这些无法满足需求,则可以通过扩展 `Trigger<T, W>` 类来自定义触发逻辑。 以下是通过 `StreamExecutionEnvironment` 和 `TimeWindow` 的自定义触发器示例: #### 自定义 Trigger 示例代码 ```java import org.apache.flink.api.common.eventtime.WatermarkStrategy; import org.apache.flink.api.java.tuple.Tuple2; import org.apache.flink.streaming.api.datastream.DataStream; import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment; import org.apache.flink.streaming.api.windowing.assigners.TumblingEventTimeWindows; import org.apache.flink.streaming.api.windowing.time.Time; import org.apache.flink.streaming.api.windowing.triggers.Trigger; import org.apache.flink.streaming.api.windowing.triggers.TriggerResult; import org.apache.flink.streaming.api.windowing.windows.TimeWindow; public class CustomTriggerExample { public static void main(String[] args) throws Exception { final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(); DataStream<Tuple2<String, Integer>> stream = env.fromElements( Tuple2.of("key1", 1), Tuple2.of("key1", 2), Tuple2.of("key2", 3), Tuple2.of("key2", 4)) .assignTimestampsAndWatermarks(WatermarkStrategy.<Tuple2<String, Integer>>forMonotonousTimestamps() .withTimestampAssigner((event, timestamp) -> System.currentTimeMillis())); DataStream<Integer> result = stream.keyBy(value -> value.f0) .window(TumblingEventTimeWindows.of(Time.seconds(5))) .trigger(new MyCustomTrigger<>()) // 使用自定义触发器 .sum(1); result.print(); env.execute("Custom Trigger Example"); } /** * 定义一个简单的自定义触发器。 */ public static class MyCustomTrigger<T, W extends TimeWindow> extends Trigger<T, W> { @Override public TriggerResult onElement(T element, long timestamp, W window, TriggerContext ctx) throws Exception { // 当接收到任意元素时立即触发评估 return TriggerResult.FIRE_AND_PURGE; } @Override public TriggerResult onProcessingTime(long time, W window, TriggerContext ctx) throws Exception { // 不基于处理时间触发任何操作 return TriggerResult.CONTINUE; } @Override public TriggerResult onEventTime(long time, W window, TriggerContext ctx) throws Exception { // 如果事件时间到达窗口结束时间则触发 if (time >= window.getEnd()) { return TriggerResult.FIRE; } return TriggerResult.CONTINUE; } @Override public void clear(W window, TriggerContext ctx) throws Exception { // 清理状态的操作 } } } ``` #### 关键点解析 - **自定义触发器类**:继承 `Trigger<T, W>` 并重写其核心方法来定义触发行为[^6]。 - **onElement 方法**:每当新数据进入窗口时调用此方法。在此处可以根据条件决定是否触发窗口计算并清除数据[^7]。 - **onProcessingTime/onEventTime 方法**:分别针对处理时间和事件时间设置额外的触发条件[^8]。 - **clear 方法**:清理与特定窗口关联的状态,在某些场景下可能需要显式释放资源[^9]。 以上程序展示了如何创建一个简单但功能强大的自定义触发器,并将其应用于滚动事件时间窗口中。 --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值