介绍
StreamX 项目的初衷是——让 Flink 开发更简单, 使用 StreamX 开发,可以极大降低学习成本和开发门槛,让开发者只用关心最核心的业务,StreamX 规范了项目的配置,鼓励函数式编程,定义了最佳的编程方式,提供了一系列开箱即用的Connectors,标准化了配置、开发、测试、部署、监控、运维的整个过程,提供 scala 和 java 两套 api,其最终目的是打造一个一站式大数据平台,流批一体,湖仓一体的解决方案。
StreamX的特色有:
- 开发脚手架;
- 多版本 Flink 支持(1.12+);
- 一系列开箱即用的 connectors;
- 支持项目编译功能(maven 编译);
- 在线参数配置;
- 支持 Application 模式或Yarn-Per-Job 模式启动;
- 快捷的日常操作(任务启动、停止、savepoint,从 savepoint 恢复);
- 支持火焰图;
- 支持 notebook(在线任务开发);
- 项目配置和依赖版本化管理;
- 支持任务备份、回滚(配置回滚);
- 在线管理依赖(maven pom)和自定义 jar;
- 自定义 udf、连接器等支持;
- Flink SQL WebIDE;
- 支持 catalog、hive;
- 任务运行失败发送告警邮件;
- 支持失败重启重试;
- 从任务开发阶段到部署管理全链路支持等
架构
其中:
- StreamX-Core的定位是一个开发时框架,关注编码开发,规范了配置文件,按照约定优于配置的方式进行开发,提供了一个开发时 RunTime Content 和一系列开箱即用的 Connector,扩展了 DataStream 相关的方法,融合了 DataStream 和 Flink sql api,简化繁琐的操作,聚焦业务本身,提高开发效率和开发体验;
- StreamXPump的定位是一个数据抽取的组件,类似于flinkx。它基于 streamx-core 中提供的各种 connector 开发,目的是打造一个方便快捷,开箱即用的大数据实时数据抽取和迁移组件,并且集成到 streamx-console 中,解决实时数据源获取问题,目前在规划中;
- StreamX-Console是一个综合实时数据平台,低代码(Low Code)平台,可以较好的管理Flink 任务,集成了项目编译、发布、参数配置、启动、savepoint,火焰图(flame graph),Flink SQL,监控等诸多功能于一体,大大简化了 Flink 任务的日常操作和维护,融合了诸多最佳实践。旧时王谢堂前燕,飞入寻常百姓家,让大公司有能力研发使用的项目,现在人人可以使用,其最终目标是打造成一个实时数仓,流批一体的一站式大数据解决方案。
部署环境介绍
基础环境如下:
软件 | 版本 | 是否必须 | 其他事项 |
---|---|---|---|
CentOS | 7.5 | 是 | StreamX不支持Windows |
Java | 1.8 | 是 | |
Maven | 3.8.5 | 否 | 需要部署应用的结点需要安装Maven |
Node.js | 是 | ||
Flink | 1.13.6 | 是 | 版本必须是1.12及以上,scala版本必须是2.11 |
Hadoop | 2.10.1 | 否 | 如果需要yarn才需要Hadoop |
MySQL | 5.7.26 | 否 | |
Python | 2.7 | 否 | 火焰图功能会用到Python和Perl |
Perl | 未安装 | 否 | 火焰图功能会用到Python和Perl |
不过Flink版本>=1.13,那么将自带火焰图,即不用额外装Python或Perl
环境准备
我主要装一下Node.js和Flink:
[root@scentos szc]# curl -fsSL https://rpm.nodesource.com/setup_16.x | sudo bash -
[root@scentos szc]# yum install -y nodejs
[root@scentos szc]# node --version
v16.14.2
[root@scentos szc]# tar -zxvf flink-1.13.6-bin-scala_2.11.tgz
[root@scentos szc]# export FLINK_HOME=/home/szc/flink-1.13.6/
对于Hadoop,安装过程参见Hadoop2.5.0在CentOS7下的安装部署,装好后,配置环境变量HADOOP_HOME跟HADOOP_CLASSPATH:
[root@scentos szc]# export PATH=$PATH:/home/szc/hadoop-2.10.1/bin/
[root@scentos szc]# export HADOOP_HOME=/home/szc/hadoop-2.10.1
[root@scentos szc]# export HADOOP_CLASSPATH=`hadoop classpath`
然后在core-site.xml中加入如下配置:
<property>
<name>dfs.client.datanode-restart.timeout</name>
<value>30</value>
</property>
安装部署StreamX
解压安装包
[root@scentos szc]# tar -zxvf streamx-console-service-1.2.2-bin.tar.gz
[root@scentos szc]# mv streamx-console-service-1.2.2 streamx-1.2.2
在MySQL中创建数据库和数据表
mysql> CREATE DATABASE `streamx` CHARACTER SET utf8 COLLATE utf8_general_ci;
Query OK, 1 row affected (0.00 sec)
mysql> use streamx;
Database changed
mysql> source C:\\Users\\songzeceng\\Desktop\\final.sql;
最后一步的final.sql来源于streamx-1.2.2/script/final.sql。
配置连接信息
[root@scentos szc]# vim streamx-1.2.2/conf/application.yml
修改内容如下:
............
# 配置默认数据源
primary: primary
datasource:
# 数据源-1,名称为 primary
primary:
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://windows:3306/streamx?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8
aop.proxy-target-class: true
............
streamx:
# HADOOP_USER_NAME
hadoop-user-name: root
# 本地的工作空间,用于存放项目源码,构建的目录等.
workspace:
local: /home/szc/streamx_workspace
remote: hdfs:///streamx # support hdfs:///streamx/ 、 /streamx 、hdfs://host:ip/streamx/
............
启动并配置
[root@scentos szc]# streamx-1.2.2/bin/startup.sh
.+.
_____/ /_________ ____ _____ ___ _ __
/ ___/ __/ ___/ _ \/ __ `/ __ `__ \| |/_/
(__ ) /_/ / / __/ /_/ / / / / / /> <
/____/\__/_/ \___/\__,_/_/ /_/ /_/_/|_|
|/
.
• WebSite: http://www.streamxhub.com
• GitHub : http://github.com/streamxhub/streamx
• Gitee : http://gitee.com/streamxhub/streamx
──────── Make stream processing easier ô~ô!
[StreamX] Using APP_BASE: /home/szc/streamx-1.2.2
[StreamX] Using APP_HOME: /home/szc/streamx-1.2.2
[StreamX] Using JRE_HOME: /home/szc/jdk1.8.0_331
[StreamX] Using APP_PID: /home/szc/streamx-1.2.2/.pid
[StreamX] Usage: properties file:application.yml
[StreamX] Using HADOOP_HOME: /home/szc/hadoop-2.10.1
[StreamX] StreamX start successful. pid: 15772
访问centosIP:10000登录web界面,初始用户名和密码分别为admin和streamx:
登录后,可以看到如下界面:
然后通过StreamX->Setting->Flink Home配置Flink Home:
填写Flink版本和解压路径即可:
提交后结果如下:
部署Flink应用
部署FlinkStream应用
首先新建Idea项目:
pom.xml文件内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.szc.example</groupId>
<artifactId>TestStreamXStream</artifactId>
<version>1.0</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<flink.version>1.13.6</flink.version>
<scala.binary.version>2.11</scala.binary.version>
<slf4j.version>1.7.30</slf4j.version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-java</artifactId>
<version>${flink.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-streaming-java_${scala.binary.version}</artifactId>
<version>${flink.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-clients_${scala.binary.version}</artifactId>
<version>${flink.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-runtime-web_${scala.binary.version}</artifactId>
<version>${flink.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-to-slf4j</artifactId>
<version>2.14.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<artifactSet>
<excludes>
<exclude>com.google.code.findbugs:jsr305</exclude>
<exclude>org.slf4j:*</exclude>
<exclude>log4j:*</exclude>
</excludes>
</artifactSet>
<filters>
<filter>
<!-- Do not copy the signatures in the META-INF
folder.
Otherwise, this might cause SecurityExceptions when
using the JAR. -->
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
<transformers combine.children="append">
<transformer
implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer">
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
示例java代码,用以统计向scentos:9999发送的字符串及出现次数,相当于WordCount:
import org.apache.flink.api.common.functions.FlatMapFunction;
import org.apache.flink.api.common.functions.MapFunction;
import org.apache.flink.api.java.functions.KeySelector;
import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.util.Collector;
public class Main {
public static void main(String[] args) throws Exception {
StreamExecutionEnvironment env =
StreamExecutionEnvironment.getExecutionEnvironment();
env.setParallelism(1);
env
.socketTextStream("scentos", 9999)
.flatMap(new FlatMapFunction<String, String>() {
@Override
public void flatMap(String line,
Collector<String> out) throws Exception {
for (String word : line.split(" ")) {
out.collect(word);
}
}
})
.map(new MapFunction<String, Tuple2<String, Long>>() {
@Override
public Tuple2<String, Long> map(String word) throws Exception {
return Tuple2.of(word, 1L);
}
})
.keyBy(new KeySelector<Tuple2<String, Long>, String>() {
@Override
public String getKey(Tuple2<String, Long> t) throws Exception {
return t.f0; // t._1
}
})
.sum(1)
.print();
env.execute();
}
}
而后将项目代码上传到github或gitee的公开仓库中:
(base) PS D:\develop\ideaWorkspace\TestStreamXStream> git init
(base) PS D:\develop\ideaWorkspace\TestStreamXStream> git remote add origin https://gitee.com/songzeceng/test-stream-x.git
(base) PS D:\develop\ideaWorkspace\TestStreamXStream> git push -u origin "master"
然后在StreamX的web界面的StreamX->Project中配置项目:
填写项目名、项目类型、版本控制工具、仓库URL和分支,点击提交即可:
完成后,点击右边的闪电图标来编译项目:
编译过程中:
第一次编译时间较久,因为要下载很多依赖。编译成功后的结果:
完成后,在StreamX->Application中添加应用:
然后按照图中所示配置项目即可:
剩下不带*的都不用填,注意此时要启动yarn,然后点击提交:
然后上线应用:
启动完成后,启动socket,监听9999端口:
[root@scentos szc]# nc -lk 9999
再在StreamX界面上点击运行应用:
不用从保存点启动:
可以从yarn平台上(8088端口)查看,发现应用确实已经在运行了:
在事先启动的nc -lk中发送数据:
[root@scentos szc]# nc -lk 9999
test
test2
test
test
再查看任务的输出,在StreamX的web界面上点击应用:
在弹出的界面里点击Task Managers,然后点击正在运行的任务:
再点击stdout即可查看输出:
部署FlinkSQL应用
还是在StreamX的web界面上,点击StreamX->Application->添加应用:
注意部署模式这里应该是Flink SQL:
然后在FlinkSQL中写入以下语句:
create table t1 (test string) with(
'connector' = 'kafka',
'topic' = 't1',
'properties.bootstrap.servers' = 'scentos:9092',
'scan.startup.mode' = 'latest-offset',
'format' = 'csv'
);
create table t2 (test string) with('connector' = 'print');
insert into t2 select * from t1;
在依赖一栏中选择Maven pom,并写入以下语句:
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-connector-kafka_2.11</artifactId>
<version>1.13.6</version>
</dependency>
点击应用:
填写应用名:
再点击提交:
在命令行中启动Kafka命令行生产者(安装过程参见CentOS7下安装使用kafka及其监控组件)进行测试:
[root@scentos szc]# kafka-console-producer.sh --broker-list scentos:9092 --topic t1
>testtt
>test2
>
>
然后跟上一小节中一样,上传、运行应用,启动成功后的状态如下:
跟5.1一样,点击应用名进入控制面板,点击Task Managers->任务的Path,ID->stdout,会发现有如下输出: