常用提交方式分为local,standalone,yarn三种。
YARN_CONF_DIR
、HADOOP_CONF_DIR
、HADOOP_CONF_PATH
中的一个,才能读取YARN和HDFS的配置信息(会按三者从左到右的顺序读取,只要发现一个就开始读取。如果没有正确设置,会尝试使用HADOOP_HOME/etc/hadoop
),否则提交任务会失败。local即本地模式,可以不依赖hadoop,可以不搭建flink集群。一般在开发时调试时使用。
就是直接运行项目中的代码的方式,例如直接在idea中运行。创建ExecutionEnvironment的方式如下:
// getExecutionEnvironment()方法可以根据flink运用程序如何提交判断出是那种模式提交
//ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
ExecutionEnvironment env = ExecutionEnvironment.createLocalEnvironment();
这种方式可以将本地代码提交给远端flink集群运行,需要指定集群的master地址。在flink集群的web ui会存在Running Job/Compaleted Jobs的记录。
public class TestLocal {
public static void main(String[] args) throws Exception {
ExecutionEnvironment env = ExecutionEnvironment.createRemoteEnvironment("remote_ip", 8090, "D:\\code\\flink-local.jar");
System.out.println(env.getParallelism());
env.readTextFile("hdfs://remote_ip:9000/tmp/test.txt")
.print();
}
}
例如有如下项目代码:
public class TestLocal {
public static void main(String[] args) throws Exception {
ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
env.readTextFile("hdfs://remote_ip:9000/tmp/test.txt")
.print();
}
}
将项目打成jar包,在本机上使用flink run 指定集群的模式提交(这个机器可以不是flink集群的节点,但需要在local机器上有flink提交命令,)。如:
./flink run -m remote_ip:8090 -p 1 -c com.test.TestLocal /home/hdp/flink-local.jar
# -m flink 集群地址
# -p 配置job的并行度
# -c Job执行的main class
也会在flink web ui界面显示结果。
上面讲了flink在local机器上进行提交,需要指定flink的master信息。
standalone模式提交也是类似,不过可以不用指定master节点,还有个区别就是,提交是在flink集群的机器节点上。
两个提交命令示例:
# 前台提交
./flink run -p 1 -c com.test.TestLocal /home/hdp/flink-local.jar
# 通过-d后台提交
./flink run -p 1 -c com.test.TestLocal -d /home/hdp/flink-local.jar
yarn模式必须确保本机配置了HADOOP_HOME
环境变量,flink会尝试通过HADOOP_HOME/etc/hadoop
目录下的配置文件连接yarn。
flink on yarn 有两种提交方式:
两者区别
一种是yarn-session,就是把首先启动一个yarn-session当成了一个flink容器,官方说法是flink服务,然后我们提交到yarn上面的全部flink任务全部都是提交到这个服务,也就是容器里面进行运行的。flink任务之间也是独立的,但是都存在于flink服务即容器里面,yarn上只能监测到一个flink服务即容器,无法监测到flink单个任务,需要进入flink服务即容器内部,才可以看到。
另一种是yarn-cluster,就是每个把flink任务当成了一个application,就是一个job,在yarn上可以管理,flink任务之间互相是独立的。
这种模式下会启动yarn session,并且会启动Flink的两个必要服务:JobManager和TaskManagers,然后你可以向集群提交作业。同一个Session中可以提交多个Flink作业。需要注意的是,这种模式下Hadoop的版本至少是2.2,而且必须安装了HDFS(因为启动YARN session的时候会向HDFS上提交相关的jar文件和配置文件)。
yarn-session模式提交任务的步骤:
1.启动yarn-session,我们可以通过./bin/yarn-session.sh脚本启动,参数如下:
Usage:
Required
-n,--container <arg> Number of YARN container to allocate (=Number of Task Managers)
Optional
-D <property=value> use value for given property
-d,--detached If present, runs the job in detached mode
-h,--help Help for the Yarn session CLI.
-id,--applicationId <arg> Attach to running YARN session
-j,--jar <arg> Path to Flink jar file
-jm,--jobManagerMemory <arg> Memory for JobManager Container with optional unit (default: MB)
-m,--jobmanager <arg> Address of the JobManager (master) to which to connect. Use this flag to connect to a different JobManager than the one specified in the configuration.
-n,--container <arg> Number of YARN container to allocate (=Number of Task Managers)
-nl,--nodeLabel <arg> Specify YARN node label for the YARN application
-nm,--name <arg> Set a custom name for the application on YARN
-q,--query Display available YARN resources (memory, cores)
-qu,--queue <arg> Specify YARN queue.
-s,--slots <arg> Number of slots per TaskManager
-sae,--shutdownOnAttachedExit If the job is submitted in attached mode, perform a best-effort cluster shutdown when the CLI is terminated abruptly, e.g., in response to a user interrupt, such
as typing Ctrl + C.
-st,--streaming Start Flink in streaming mode
-t,--ship <arg> Ship files in the specified directory (t for transfer)
-tm,--taskManagerMemory <arg> Memory per TaskManager Container with optional unit (default: MB)
-yd,--yarndetached If present, runs the job in detached mode (deprecated; use non-YARN specific option instead)
-z,--zookeeperNamespace <arg> Namespace to create the Zookeeper sub-paths for high availability mode
例如:
# 方式一:启动一个新的flink集群
./bin/yarn-session.sh -n 4 -tm 8192 -s 8
# 方式二:附着到一个已存在的flink yarn session
附着到一个已存在的flink yarn session
方式一启动了4个TaskManager,每个TaskManager内存为8G且占用了8个核(是每个TaskManager,默认是1个核)。在启动YARN session的时候会加载conf/flink-config.yaml配置文件,我们可以根据自己的需求去修改里面的相关参数。启动后可以在flink web ui查看运行情况。
2.启动了yarn session之后,就可以通过flink run
命令提交作业了
例如:
./bin/flink run ./examples/batch/WordCount.jar --input hdfs:///user/zhang/LICENSE
# --input是程序的入参,不是flink内部参数
上面的YARN session是在Hadoop YARN环境下启动一个Flink cluster集群,里面的资源是可以共享给其他的Flink作业。我们还可以在YARN上启动一个Flink作业。这里我们还是使用./bin/flink,但是不需要事先启动YARN session:
./bin/flink run -m yarn-cluster -yn 2 ./examples/batch/WordCount.jar \
--input hdfs:///user/zhang/LICENSE \
--output hdfs:///user/zhang/result.txt
上面的命令同样会启动一个类似于YARN session启动的页面。其中的-yn是指TaskManager的个数,必须指定。
flink run [option]
-c,--class <classname> : 需要指定的main方法的类
-C,--classpath <url> : 向每个用户代码添加url,他是通过UrlClassLoader加载。url需要指定文件的schema如(file://)
-d,--detached : 在后台运行
-p,--parallelism <parallelism> : job需要指定env的并行度,这个一般都需要设置。
-q,--sysoutLogging : 禁止logging输出作为标准输出。
-s,--fromSavepoint <savepointPath> : 基于savepoint保存下来的路径,进行恢复。
-sae,--shutdownOnAttachedExit : 如果是前台的方式提交,当客户端中断,集群执行的job任务也会shutdown。
提交项目时如何指定外部依赖jar包呢?
通过-C命令添加外部jar包的路径,但是有两点需要注意:
a、需要指定文件路径的协议:例如本地文件用file://,多个jar包用*表示,这里不支持hdfs://
b、指定的路径要flink的所有节点都能访问
例如我在做flink与kafka和hbase整合测试时,需要依赖kafka和hbase的jar包,我的做法是,将依赖的jar包传到每个flink节点的flink_home/lib目录下,然后编写如下的启动脚本:
-m,--jobmanager : yarn-cluster集群
-yd,--yarndetached : 后台
-yjm,--yarnjobManager : jobmanager的内存
-ytm,--yarntaskManager : taskmanager的内存
-yn,--yarncontainer : TaskManager的个数
-yid,--yarnapplicationId : job依附的applicationId
-ynm,--yarnname : application的名称
-ys,--yarnslots : 分配的slots个数
flink run -m yarn-cluster -yd -yjm 1024m -ytm 1024m -ynm <name> -ys 1 <jar> <arguments>
flink list:列出flink的job列表。
flink list -r/--runing :列出正在运行的job
flink list -s/--scheduled :列出已调度完成的job
flink cancel [options] <job_id> : 取消正在运行的job id
flink cancel -s/--withSavepoint <path> <job_id> : 取消正在运行的job,并保存到相应的保存点
flink stop [options] <job_id>
flink stop <job_id>:停止对应的job
flink modify <job_id> [options]
flink modify <job_id> -p/--parallelism p : 修改job的并行度
flink savepoint [options] <job_id> <target directory>
eg:
# 触发保存点
flink savepoint <job_id> <hdfs://xxxx/xx/x> : 将flink的快照保存到hdfs目录
# 使用yarn触发保存点
flink savepoint <job_id> <target_directory> -yid <application_id>
# 使用savepoint取消作业
flink cancel -s <tar_directory> <job_id>
# 从保存点恢复
flink run -s <target_directoey> [:runArgs]
# 如果复原的程序,对逻辑做了修改,比如删除了算子可以指定allowNonRestoredState参数复原。
flink run -s <target_directory> -n/--allowNonRestoredState [:runArgs]
几个角色的作用:
task与slot
task是最基本的调度单位,由一个线程执行,里面包含一个或多个operator。多个operators就成为operation chain,需要上下游并发度一致,且传递模式(之前的Data exchange strategies)是forward。
slot是TM的资源子集,类似于spark的executor-core。如果一个TaskManager有三个slot,那么它会将其管理的内存分为三份(cpu是共享的)。slot的数量表示任务理论上最大的并行度,任务实际的并行度由参数parallelism决定。结合下面Task Execution的图,一个slot并不代表一个线程,它里面并不一定只放一个task。多个task在一个slot就涉及slot sharing group。
session模式的作业提交流程
-m master_ip:port
,yarn-cluster模式指定master:-m yarn-cluster
问题描述:搭建好一个全新flink集群后,在没有运行过flink on yarn之前,直接采用standalone模式运行项目能够成功。命令如下:
./bin/flink run ./examples/streaming/SocketWindowWordCount.jar --hostname hadoop04 --port 9090
但是在运行过一次yarn-session过后,再次用standalone模式以同样的命令运行项目,就会报错:
我们知道standalone模式不需要启动yarn,也不会去连接yarn,那么日志显示:发现了yarn的配置文件,flink尝试去连接yarn。由于yarn并没有启动,所以一直在重试。出于好奇,我启动了yarn,再次提交项目,又报了以下错误:
日志显示无法找到application:ApplicationNotFoundException: Application with id 'application_1580903213963_0001' doesn't exist in RM
,这里怎么会有application id呢?百思不得其解。根据日志我输出了/tmp/.yarn-properties-hdp
文件的内容:
发现日志中打印的application id与文件中记录的id相同。我猜测是由于运行过一次yarn-session过后,会在本地留下一个yarn的配置文件/tmp/.yarn-properties-hdp
,再次以standalone模式提交任务时,flink发现了这个配置文件,便会尝试去连接yarn。
那么如果将这个文件删除,是否就可以再以standalone模式提交任务了呢?
将这个文件删除,关闭yarn,再次以同样的命令提交任务,果然成功了!!!