大数据高级开发工程师——Flink学习笔记(1)

Flink学习笔记

Flink基础篇

Flink简介

  • 官网地址:https://flink.apache.org/
  • Apache Flink® — Stateful Computations over Data Streams
  • Apache Flink 是一个分布式大数据处理引擎,可对有界数据流无界数据流进行有状态的计算。能够部署在各种集群环境,对各种规模大小的数据进行快速计算。

在这里插入图片描述

1. 处理无界和有界数据
  • 任何类型的数据都可以形成一种事件流。信用卡交易、传感器测量、机器日志、网站或移动应用程序上的用户交互记录,所有这些数据都形成一种流。
  • 数据可以被作为无界或则有界流来处理。
- 无界流: 有定义流的开始,但没有定义流的结束。它们会无休止地产生数据。无界流的数据必须持续处理,即数据被摄取后需要立刻处理。我们不能等到所有数据都到达再处理,因为输入是无限的,在任何时候输入都不会完成。处理无界数据通常要求以特定顺序摄取事件,例如事件发生的顺序,以便能够推断结果的完整性。
- 有界流: 有定义流的开始,也有定义流的结束。有界流可以在摄取所有数据后再进行计算。有界流所有数据可以被排序,所以并不需要有序摄取。有界流处理通常被称为批处理。

在这里插入图片描述

  • Apache Flink 擅长处理无界和有界数据集:精确的时间控制和状态化使得 Flink 的运行时(runtime)能够运行任何处理无界流的应用。有界流则由一些专为固定大小数据集特殊设计的算法和数据结构进行内部处理,产生了出色的性能。
2. 部署应用到任意地方
  • Apache Flink 是一个分布式系统,它需要计算资源来执行应用程序。Flink 集成了所有常见的集群资源管理器,例如 Hadoop YARNApache MesosKubernetes,但同时也可以作为独立集群运行。
	Flink 被设计为能够很好地工作在上述每个资源管理器中,这是通过资源管理器特定(resource-manager-specific)的部署模式实现的。Flink 可以采用与当前资源管理器相适应的方式进行交互。
	部署 Flink 应用程序时,Flink 会根据应用程序配置的并行性自动标识所需的资源,并从资源管理器请求这些资源。在发生故障的情况下,Flink 通过请求新资源来替换发生故障的容器。提交或控制应用程序的所有通信都是通过 REST 调用进行的,这可以简化 Flink 与各种环境中的集成。
3. 运行任意规模的应用
  • Flink 旨在任意规模上运行有状态流式应用。因此,应用程序被并行化为可能数千个任务,这些任务分布在集群中并发执行。所以应用程序能够充分利用无尽的 CPU、内存、磁盘和网络 IO。而且 Flink 很容易维护非常大的应用程序状态。其异步和增量的检查点算法对处理延迟产生最小的影响,同时保证 exactly-once 状态的一致性。
Flink 用户报告了其生产环境中一些令人印象深刻的扩展性数字
	每天处理数万亿的事件
	可以维护几TB大小的状态
	可以部署上千个节点的集群
4. 利用内存性能
  • 有状态的 Flink 程序针对本地状态访问进行了优化。任务的状态始终保留在内存中,如果状态大小超过可用内存,则会保存在能高效访问的磁盘数据结构中。任务通过访问本地(通常在内存中)状态来进行所有的计算,从而产生非常低的处理延迟。Flink 通过定期和异步地对本地状态进行持久化存储来保证故障场景下 exactly-once 的状态一致性。
    在这里插入图片描述

Flink的特点和应用场景

1. Flink 的特点
  • 批流统一
  • 支持高吞吐、低延迟、高性能的流处理
  • 支持带有事件时间的窗口(Window)操作
  • 支持有状态计算的 Exactly-once 语义
  • 支持高度灵活的窗口(Window)操作,支持基于 time、count、session 窗口操作
  • 支持具有反压 Backpressure 功能的持续流模型
  • 支持基于轻量级分布式快照(Snapshot)实现的容错
  • 支持迭代计算
  • Flink 在 JVM 内部实现了自己的内存管理
  • 支持程序自动优化:避免特定情况下 Shuffle、排序等昂贵操作,中间结果有必要进行缓存
2. Flink 的应用场景

在实际生产的过程中,大量数据在不断地产生,例如金融交易数据、互联网订单数据、 GPS 定位数据、传感器信号、移动终端产生的数据、通信信号数据等,以及我们熟悉的网络流量监控、服务器产生的日志数据,这些数据最大的共同点就是实时从不同的数据源中产生, 然后再传输到下游的分析系统。针对这些数据类型主要包括实时智能推荐、复杂事件处理、 实时欺诈检测、实时数仓与 ETL 类型、流数据分析类型、实时报表类型等实时业务场景,而 Flink 对于这些类型的场景都有着非常好的支持。

  • 实时智能推荐:智能推荐会根据用户历史的购买行为,通过推荐算法训练模型,预测用户未来可能会购买的物品。对个人来说,推荐系统起着信息过滤的作用;对 Web/App 服务端来说,推荐系统起着满足用户个性化需求,提升用户满意度的作用。推荐系统本身也在飞速发展,除了算法,越来越完善,对时延的要求也越来越苛刻和实时化。利用 Flink 流计算帮助用户构建更加实时的智能推荐系统,对用户行为指标进行实时计算,对模型进行实时更新,对用户指标进行实时预测,并将预测的信息推送给 Wep/App 端,帮助用户获取想要的商品信息,另一方面也帮助企业提升销售额,创造更大的商业价值。
  • 复杂事件处理:对于复杂事件处理,比较常见的案例主要集中于工业领域,例如对车载传感器、机械设备等实时故障检测,这些业务类型通常数据量都非常大,且对数据处理的时效性要求非常高。通过利用 Flink 提供的 CEP(复杂事件处理)进行事件模式的抽取,同时应用 Flink 的 Sql 进行事件数据的转换,在流式系统中构建实时规则引擎,一旦事件触发报警规则,便立即将告警结果传输至下游通知系统,从而实现对设备故障快速预警监测,车辆状态监控等目的。
  • 实时欺诈检测:在金融领域的业务中,常常出现各种类型的欺诈行为,例如信用卡欺诈、信贷申请欺诈等,而如何保证用户和公司的资金安全,是来近年来许多金融公司及银行共同面对的挑战。 随着不法分子欺诈手段的不断升级,传统的反欺诈手段已经不足以解决目前所面临的问题。以往可能需要几个小时才能通过交易数据计算出用户的行为指标,然后通过规则判别出具有欺诈行为嫌疑的用户,再进行案件调查处理,在这种情况下资金可能早已被不法分子转移,从而给企业和用户造成大量的经济损失。而运用 Flink 流式计算技术能够在毫秒内就完成对欺诈判断行为指标的计算,然后实时对交易流水进行规则判断或者模型预测,这样一旦检测出交易中存在欺诈嫌疑,则直接对交易进行实时拦截,避免因为处理不及时而导致的经济损失。
  • 实时数仓与ETL:结合离线数仓,通过利用流计算诸多优势和 SQL 灵活的加工能力,对流式数据进行实时清洗、归并、结构化处理,为离线数仓进行补充和优化。另一方面结合实时数据 ETL 处理能力,利用有状态流式计算技术,可以尽可能降低企业由于在离线数据计算过程中调度逻辑的复杂度,高效快速地处理企业需要的统计结果,帮助企业更好地应用实时数据所分析出来的结果。
  • 流数据分析:实时计算各类数据指标,并利用实时结果及时调整在线系统相关策略,在各类内容投放、无线智能推送领域有大量的应用。流式计算技术将数据分析场景实时化,帮助企业做到实时化分析 Web 应用或者 App 应用的各项指标,包括 App 版本分布情况、Crash 检测和分布等,同时提供多维度用户行为分析,支持日志自主分析,助力开发者实现基于大数据技术的精细 化运营、提升产品质量和体验、增强用户黏性。
  • 实时报表分析:实时报表分析是近年来很多公司采用的报表统计方案之一,其中最主要的应用便是实时大屏展示。利用流式计算实时得出的结果直接被推送到前端应用,实时显示出重要指标的变换情况。最典型的案例便是淘宝的双十一活动,每年双十一购物节,除疯狂购物外,最引人注目的就是天猫双十一大屏不停跳跃的成交总额。在整个计算链路中包括从天猫交易下单购买到数据采集、数据计算、数据校验,最终落到双十一大屏上展现的全链路时间压缩在 5 秒以内,顶峰计算性能高达数三十万笔订单/秒,通过多条链路流计算备份确保万无一失。而在其他行业,企业也在构建自己的实时报表系统,让企业能够依托于自身的业务数据,快速提取出更多的数据价值,从而更好地服务于企业运行过程中。

Flink基本技术栈和架构

1. Flink 基本技术栈

在flink整个软件架构体系中。同样遵循着分层的架构设计理念,在降低系统耦合度的同时,也为上层用户构建 flink 应用提供了丰富且友好的接口。
在这里插入图片描述

  • API & Libraries 层:作为分布式数据处理框架,fink同时提供了支撑流计算和批计算的接口,同时在此基础之上抽象出不同的应用类型的组件库。如:基于流处理的CEP(复杂事件处理库)、SQL&Table库、FlinkML(机器学习库)、Gelly(图处理库)。有流式处理API,批处理API。流式处理的支持事件处理,表操作。批处理的,支持机器学习,图计算,也支持表操作。
  • Runtime 核心层:主要负责对上层的接口提供基础服务,也就是flink分布式计算的核心实现。flink底层的执行引擎。
  • 物理部署层:主要涉及到flink的部署模式,目前flink支持多种部署模式:本地 local、集群 standalone/yarn、云 GCE/EC2 谷歌云、亚马逊云、kubenetes 等。
2. Flink 基本架构

Flink 整个系统主要由两个组件组成,分别为 JobManager 和 TaskManager,Flink 架构也遵循 Master-Slave 架构设计原则,JobManager 为 Master 节点,TaskManager 为 Worker(Slave)节点。所有组件之间的通信都是借助于 Akka Framework,包括任务的状态以及 Checkpoint 触发等信息。

在这里插入图片描述

  • Client:客户端负责将任务提交到集群,与 JobManager 构建 Akka 连接,然后将任务提交JobManager,通过和 JobManager 之间进行交互获取任务执行状态。客户端提交任务可以采用 CLI 方式或者通过使用 Flink WebUI 提交,也可以在应用程序中指定 JobManager 的 RPC 网络端口构建 ExecutionEnvironment 提交 Flink 应用。
  • JobManager:负责整个 Flink 集群任务的调度以及资源的管理,从客户端中获取提交的应用,然后根据集群中 TaskManager 上 TaskSlot 的使用情况,为提交的应用分配相应的 TaskSlot 资源并命令 TaskManager 启动从客户端中获取的应用。
    • JobManager 相当于整个集群的 Master 节点,且整个集群有且只有一个活跃的 JobManager,负责整个集群的任务管理和资源管理。
    • JobManager 和 TaskManager 之间通过 Actor System 进行通信,获取任务执行的情况并通过 Actor System 将应用的任务执行情况发送给客户端。同时在任务执行的过程中,Flink JobManager 会触发 Checkpoint 操作,每个 TaskManager 节点收到 Checkpoint 触发指令后,完成 Checkpoint 操作,所有的 Checkpoint 协调过程都是在 Fink JobManager 中完成。
    • 当任务完成后,Flink 会将任务执行的信息反馈给客户端,并且释放掉 TaskManager 中的资源以供下一次提交任务使用。
  • TaskManager:相当于整个集群的 Slave 节点,负责具体的任务执行和对应任务在每个节点上的资源申请和管理。客户端通过将编写好的 Flink 应用编译打包,提交到 JobManager,然后 JobManager 会根据已注册在 JobManager 中 TaskManager 的资源情况,将任务分配给有资源的 TaskManager节点,然后启动并运行任务。
    • TaskManager 从 JobManager 接收需要部署的任务,然后使用 Slot 资源启动 Task,建立数据接入的网络连接,接收数据并开始数据处理。同时 TaskManager 之间的数据交互都是通过数据流的方式进行的。
    • 可以看出,Flink 的任务运行其实是采用多线程的方式,这和 MapReduce 多 JVM 进行的方式有很大的区别,Flink 能够极大提高 CPU 使用效率,在多个任务和 Task 之间通过 TaskSlot 方式共享系统资源,每个 TaskManager 中通过管理多个 TaskSlot 资源池进行对资源进行有效管理。

Flink安装

1. Standalone 模式安装
  • 集群规划
主机名JobManagerTaskManager
node01
node02
node03
  • 依赖:

    • 主机之间免密码
    • jdk1.8以上,配置JAVA_HOME
    • 安装 hadoop 集群
    • 安装 zookeeper 集群
  • 下载安装包:flink-1.13.0-bin-scala_2.11.tgz

  • 上传安装包到node01服务器,然后解压

tar -zxvf flink-1.13.0-bin-scala_2.11.tgz -C /bigdata/install/
  • 安装步骤:node01修改以下配置文件
# 1、修改配置文件conf/flink-conf.yaml,新增配置
# 使用zookeeper搭建高可用
high-availability: zookeeper
# 存储JobManager的元数据到HDFS
high-availability.storageDir: hdfs://node01:8020/flink
high-availability.zookeeper.quorum: node01:2181,node02:2181,node03:2181

# 2、修改conf/masters
# 指定集群的JobManager地址
node01:8081
node02:8081

# 3、修改conf/workers
# 指定集群的TaskManager地址
node01
node02
node03

# 4、拷贝到其他节点
scp -r /bigdata/install/flink-1.13.0 node02:/bigdata/install
scp -r /bigdata/install/flink-1.13.0 node03:/bigdata/install

# 5、配置Flink集成hadoop
# 修改每个节点的/etc/profile, 添加 HADOOP_CLASSPATH,然后每个节点执行 source /etc/profile
export HADOOP_CLASSPATH=`hadoop classpath`

# 6、node01(JobMananger)节点启动,注意:启动之前先启动hadoop和zookeeper集群
cd /kkb/install/flink-1.13.0
bin/start-cluster.sh

# 7、关闭flink集群, 在主节点上执行
cd /bigdata/install/flink-1.13.0
bin/stop-cluster.sh

在这里插入图片描述

  • 访问验证:http://node01:8081、http://node02:8081

在这里插入图片描述

  • StandAlone 模式需要考虑的参数
jobmanager.memory.process.size:  jobmanager节点可用的内存大小
taskmanager.memory.process.size: taskmanager节点可用的内存大小
taskmanager.numberOfTaskSlots:   每台taskmanager节点提供的TaskSlot总数
parallelism.default:             默认情况下任务的并行度
taskmanager.tmp.dirs:            taskmanager的临时数据存储目录
2. Flink on Yarn模式安装

Flink on Yarn 有三种模式

第一种:Session模式
  • 在Yarn中初始化一个Flink集群,开辟指定的资源,之后我们提交的Flink Job都在这个Session中,也就是说不管提交多少个job,这些job都会共用开始时在yarn中申请的资源。这个Flink集群会常驻在Yarn集群中,除非手动停止。

在这里插入图片描述

  • 优点:多个任务可以共用一套集群,方便管理监控。
  • 缺点:当某一个任务异常导致对应的 TaskManager 崩溃,运行在其上的任务都会受到影响。同一个客户端节点上启动的作业越多,客户端节点的压力过大,它需要将任务的依赖和生成的JobGraph上传到集群中,这使客户端成为大量的资源消耗者,同时JobManager的负载也就越大。
  • 适用场景:适用于量多、执行任务时间短、对资源不敏感的场景,比如作为在线(即席)查询引擎。

在这里插入图片描述

第二种:Per-Job模式
  • 在Yarn中,每次提交job都会创建一个新的Flink集群,任务之间相互独立,互不影响并且方便管理。任务执行完成之后创建的集群也会消失。
  • 该模式下,一个作业对应一个集群,作业之间相互隔离。

在这里插入图片描述

  • 优点:每个任务单独维护集群,可以做到更好的资源隔离,集群的生命周期与任务相同,单独的任务失败也不会影响其他的任务。
  • 缺点:每一次提交任务都需要开辟新的集群,任务运行在不同的集群中,监控管理不方便。同一个客户端节点启动的作业越多,客户端节点的压力过大。
  • 适用场景执行任务长、对资源敏感或者消耗资源大的任务。

在这里插入图片描述

第三种:Application模式

无论是 Session 还是 Per Job 模式,程序代码都是在客户端编译完成。这里的客户端就是我们执行 flink run 启动的程序(其实是Cli Frontend)。假如现在需要做一个平台给多个用户提交任务,或者任务的量级很大,那么客户端的压力会非常大。因为编译生成 StreamGraphJobGraph 需要消耗大量的CPU,下载依赖的Jar包资源、上传 JobGraph 也需要大量的网络带宽,客户端很容易成为瓶颈。此时就考虑可不可以把编译图的工作放在集群中完成?

  • 为了解决这个问题,社区在传统部署模式的基础上实现了Application模式。
  • Application 的设计跟 per job 非常像,只不过客户端不再编译图,而是直接把执行的 Jar 和参数信息发送到 yarn 的 AppMaster,在该进程中,同时完成JM 的启动、编译图(用户main方法执行)、任务执行等过程。

在这里插入图片描述

  • 优点:在 Application 模式中,为每个应用创建一个集群,main方法会运行在集群中,避免客户端过大的压力。 解决了 Session 和 Per Job 模式在客户端编译代码生成 JobGraph 的压力,这些工作交给集群中的 JobManager 去完成。
  • 适用场景多用户大批量任务提交,任务提交平台化,每个任务的计算资源互相隔离
3. 不同模式的任务提交
第一种:Session模式

【yarn-session.sh(开辟资源) + flink run(提交任务)】

# 1. 在 flink 目录启动 yarn-session
bin/yarn-session.sh -n 2 -tm 1024 -s 1 -d
# -n: 指定申请多少个容器
# -s: 指定每个容器启动多少个slot
# -tm: 指定每个 TaskManager 申请多少内存
# -d: 以后台进程方式运行

# 2. 使用 flink 脚本提交任务
bin/flink run examples/batch/WordCount.jar -input hdfs://node01:8020/words.txt -output hdfs://node01:8020/output/result.txt
# 如果启动了很多的yarn-session, 在提交任务的时候可以通过参数 -yid 指定作业提交到哪一个yarn-session中运行
# 例如:
bin/flink run -yid application_1647823591557_0001 examples/batch/WordCount.jar -input hdfs://node01:8020/words.txt -output hdfs://node01:8020/output/result1.txt

# 3. 停止任务
yarn application -kill application_1647823591557_0001	
  • 资源申请:

在这里插入图片描述

在这里插入图片描述

  • 提交任务执行

在这里插入图片描述

在这里插入图片描述

  • 查看执行结果输出:

在这里插入图片描述

  • yarn-session.sh 脚本参数说明
【必选】  
	-n,--container <arg>   				# 分配多少个 yarn 容器 (=taskmanager的数量)  
【可选】
	-D <arg>                        	# 动态属性  
   	-d,--detached                   	# 独立运行  
   	-jm,--jobManagerMemory <arg>    	# JobManager 的内存 [in MB]  
   	-nm,--name                     		# 在 YARN 上为一个自定义的应用设置一个名字  
   	-q,--query                      	# 显示 yarn 中可用的资源 (内存, cpu核数)  
   	-qu,--queue <arg>               	# 指定 YARN 队列.  
   	-s,--slots <arg>                	# 每个 TaskManager 使用的 slots 数量  
   	-tm,--taskManagerMemory <arg>   	# 每个 TaskManager 的内存 [in MB]  
   	-z,--zookeeperNamespace <arg>   	# 针对 HA 模式在 zookeeper 上创建 NameSpace 
   	-id,--applicationId <yarnAppId> 	# YARN 集群上的任务 id,附着到一个后台运行的 yarn session 中
第二种:Per-Job模式

【flink run -t yarn-per-job(开辟资源+提交任务)】

# 启动集群,执行任务
bin/flink run -t yarn-per-job -yjm 1024 -ytm 1024 examples/batch/WordCount.jar -input hdfs://node01:8020/words.txt -output hdfs://node01:8020/output/result2.txt

# 注意:client端必须要设置 YARN_CONF_DIR 或者 HADOOP_CONF_DIR 或者 HADOOP_HOME 环境变量,通过这个环境变量来读取 YARN 和 HDFS 的配置信息,否则启动会失败。
  • flink run 脚本参数说明
run [OPTIONS] <jar-file> <arguments>  
 "run" 操作参数:  
-c,--class <classname>  		# 如果没有在jar包中指定入口类,则需要在这里通过这个参数指定  
-m,--jobmanager <host:port>  	# 指定需要连接的jobmanager(主节点)地址,使用这个参数可以指定一个不同于配置文件中的jobmanager  
-p,--parallelism <parallelism>  # 指定程序的并行度。可以覆盖配置文件中的默认值。
-t,--target <arg>   			# 用来指定部署目标

# 补充【任务提交到standalone集群中运行】需要指定连接 host 和 port 的 jobmanager
bin/flink run -m node01:6123 examples/batch/WordCount.jar -input hdfs://hostname:port/hello.txt -output hdfs://hostname:port/result1
第三种:Application模式

【flink run-application -t yarn-application】

# 启动集群,执行任务
bin/flink run-application -t yarn-application -Djobmanager.memory.process.size=1024m \
-Dtaskmanager.memory.process.size=1024m \
-Dtaskmanager.numberOfTaskSlots=1 \
examples/batch/WordCount.jar \
-input hdfs://node01:8020/words.txt \
-output hdfs://node01:8020/output2

# -t: 用来指定部署目标,目前支持 YARN(yarn-application)和K8S(kubernetes-application)。
# -D: 用来指定与作业相关的各项参数,具体可参见官方文档。

那么如何解决传输依赖项造成的带宽占用问题呢?Flink作业必须的依赖是发行包 flink-dist.jar,还有扩展库(位于== F L I N K H O M E / l i b ) = = 和 插 件 库 ( 位 于 = = FLINK_HOME/lib)==和插件库(位于== FLINKHOME/lib====FLINK_HOME/plugin==)?

  • 我们将它们预先上传到像 HDFS 这样的共享存储,再通过 yarn.provided.lib.dirs 参数指定存储的路径即可。
-Dyarn.provided.lib.dirs="hdfs://myhdfs/flink-common-deps/lib;hdfs://myhdfs/flink-common-deps/plugins"
  • 这样所有作业就不必各自上传依赖,可以直接从 HDFS 拉取,并且 YARN NodeManager 也会缓存这些依赖,进一步加快作业的提交过程。同理,包含 Flink 作业的用户 JAR 包也可以上传到 HDFS,并指定远程路径进行提交。
4. Flink on Yarn 执行流程

在这里插入图片描述

Flink on Yarn 部署很简单,就是只要部署好 hadoop 集群即可,我们只需要部署一个 Flink 客户端,然后从 flink 客户端提交 Flink 任务即可。类似于 spark on yarn 模式。

  • STEP1
    • 启动新的 Flink Yarn 会话时,客户端首先检查所请求的资源(用于启动ApplicationMaster的内存和vcores)是否可用。然后它将包含Flink 程序和配置文件的jar包上传到HDFS。
  • STEP2
    • 客户端请求一个Yarn 的容器(container)用来启动ApplicationMaster。
  • STEP3
    • 分配一个ApplicationMaster容器(container),并启动ApplicationMaster。由于客户端将配置文件和jar文件注册为容器的资源,因此NodeManager将负责准备容器(例如下载文件)。
    • 完成后将启动ApplicationMaster(AM), 该JobManager和AM在同一容器中运行,一旦成功启动,AM就知道JobManager的地址。
    • 然后会为TaskManagers生成一个新的Flink配置文件(以便它们可以连接到JobManager),该文件会被上传到HDFS。此外,AM容器还提供Flink的Web界面。YARN代码分配的所有端口都是临时端口。这允许用户并行执行多个Flink YARN会话。
  • STEP4
    • AM 开始为 Flink 的 TaskManagers 分配容器,将从 HDFS 下载 jar 文件和修改后的配置。完成这些步骤后,可以接受jobs。

Flink入门

1. 实时需求案例
  • 需求:通过flink流处理程序,接受socket数据,实现单词计数。
  • 创建一个 Maven 工程,并添加依赖:
<properties>
    <flink.version>1.13.0</flink.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.apache.flink</groupId>
        <artifactId>flink-clients_2.11</artifactId>
        <version>${flink.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.flink</groupId>
        <artifactId>flink-streaming-java_2.12</artifactId>
        <version>${flink.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.flink</groupId>
        <artifactId>flink-streaming-scala_2.11</artifactId>
        <version>${flink.version}</version>
    </dependency>
</dependencies>
  • 使用 scala 语言开发:
import org.apache.flink.streaming.api.scala.{DataStream, StreamExecutionEnvironment}
//导入隐式转换的包
import org.apache.flink.api.scala._

object WordCountStreamScala {
  def main(args: Array[String]): Unit = {
    // 1. 构建流处理环境
    val env = StreamExecutionEnvironment.getExecutionEnvironment

    // 2. 从socket获取数据
    val sourceStream: DataStream[String] = env.socketTextStream("node01", 9999)

    // 3. 对数据进行处理
    val result: DataStream[(String, Int)] = sourceStream
                .flatMap(x => x.split(" "))  // 按照空格切分
                .map(x => (x, 1))                   // 每个单词计为1
                .keyBy(x => x._1)                   // 按照单词进行分组
                .sum(1)                    // 按照下标为1累加相同单词出现的次数

    // 4. 打印输出, sink
    result.print()

    // 5. 开启任务
    env.execute("WordCountStreamScala")
  }
}
  • 本地启动程序,并在 node01 节点上使用命令 nc -lk 9999 发送 socket 数据,并查看控制台输出结果

在这里插入图片描述

  • 将代码打成 jar 包,提交到 yarn 中运行:
flink run -t yarn-per-job -yjm 1024 -ytm 1024 -c com.yw.flink.example.WordCountStreamScala flink-demo-1.0.jar

在这里插入图片描述

  • 查看 TaskManager 的输出的日志结果

在这里插入图片描述

  • 使用 java 语言开发
public class WordCountStreamJava {
    public static void main(String[] args) throws Exception {
        // 1. 构建流处理环境
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

        // 2. 从socket获取数据
        DataStreamSource<String> streamSource = env.socketTextStream("node01", 9999);

        // 3. 对数据进行处理
        DataStream<Tuple2<String, Integer>> resultStream = streamSource
                .flatMap((FlatMapFunction<String, Tuple2<String, Integer>>) (line, collector) -> {
                    String[] words = line.split(" ");
                    Arrays.stream(words).filter(Objects::nonNull)
                            .forEach(word -> collector.collect(new Tuple2<>(word, 1)));
                }).returns(Types.TUPLE(Types.STRING, Types.INT))
                .keyBy((KeySelector<Tuple2<String, Integer>, String>) tuple2 -> tuple2.f0)
                .sum(1);
        // 4. 打印输出, sink
        resultStream.print();

        // 5. 开启任务
        env.execute("WordCountStreamJava");
    }
}
  • 测试:

在这里插入图片描述

2. 离线需求案例
  • 需求:对文件进行单词计数,统计文件当中每个单词出现的次数。
import org.apache.flink.api.scala.{DataSet, ExecutionEnvironment}
import org.apache.flink.api.scala._

/**
  * scala开发flink的批处理程序
  */
object WordCountBatchScala {
  def main(args: Array[String]): Unit = {
    // 1. 构建Flink的批处理环境
    val env = ExecutionEnvironment.getExecutionEnvironment

    // 2. 读取数据文件
    val fileDataSet: DataSet[String] = env.readTextFile("words.txt")

    // 3. 对数据进行处理
    val resultDataSet: DataSet[(String, Int)] = fileDataSet
            .flatMap(x => x.split(" "))
            .map(x => (x, 1))
            .groupBy(0)
            .sum(1)

    // 4. 打印结果
    resultDataSet.print()

    // 5. 保存结果到文件
    resultDataSet.writeAsText("output")
    env.execute("FlinkFileCount")
  }
}
  • github 代码地址:https://github.com/shouwangyw/bigdata/tree/master/flink-demo
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

讲文明的喜羊羊拒绝pua

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值