1、基础信息
我们使用VMWare启动3个节点,进行测试部署Flink Standalone模式
系统版本
节点信息
IP | hostname | 配置 |
---|---|---|
192.168.48.110 | f1 | 2C2G |
192.168.48.111 | f2 | 2C2G |
192.168.48.112 | f3 | 2C2G |
hosts配置(3个节点配置相同)
基础环境包
此处需要注意“flink-1.12.0-bin-scala_2.12.tgz”文件名中的scala_2.12,代表scala 大 版本号为2.12。所以理论上2.12.x版本都可以
2、环境配置
配置基础环境
# 解压目录下的压缩包
ls | xargs -n1 | tar -zxvf
将解压之后的文件夹重命名然后移动到 /usr/local 目录下
# 配置节点之间的免密登陆,一路回车即可
ssh-keygen -t rsa
# 配置节点之间的免密登陆
ssh-copy-id -i f1
ssh-copy-id -i f2
ssh-copy-id -i f3
# 关闭防火墙。正式环境不建议执行此操作,配置防火墙规则即可,具体需要开放的端口可以参考flink配置文件中的说明
systemctl stop firewalld && systemctl disable firewalld
# 编辑当前用户的环境变量,将java和scala配置进环境变量中。需要根据实际情况替换路径
cat >> ~/.bashrc << EOF
JAVA_HOME=/usr/local/java
SCALA_HOME=/usr/local/scala
FLINK_HOME=/usr/local/flink
PATH=$PATH:$JAVA_HOME/bin:$SCALA_HOME/bin
export SCALA_HOME
export JAVA_HOME
export FLINK_HOME
export PATH
EOF
# 使环境变量生效
source ~/.bashrc
Flink配置
# 修改flink基本配置文件
vim $FLINK_HOME/conf/flink-conf.yaml
# 需要调整的配置,可将f1设置为管理节点(主节点的主机名或者IP地址),注意阅读配置文件中的注释,如对注释理解有困难可以查看下面的链接地址中的详细说明。
jobmanager.rpc.address: f1
正式环境建议开启zookeeper
# 配置maser节点信息,此处我们将f1设置为主节点,且只配置一个主节点
echo "f1:8081" > $FLINK_HOME/conf/masters
# 配置work节点
cat > $FLINK_HOME/conf/workers << EOF
f2
f3
EOF
# 将配置完成的flink传输到其他节点
scp -r /usr/local/flink f2:/usr/local
scp -r /usr/local/flink f2:/usr/local
# 启动flink,注意观察启动信息,启动完毕之后访问 $master:8081 可以看到web管理页面
cd $FLINK_HOME/bin/
./start-cluster.sh
具体flink配置文件详解,可以参考 @11宁静致远 大佬的Flink 配置文件详解一文
3、环境配置
首先我们使用python生成测试集,用来体验使用flink中的wordcount,一般centos中都有基础的python环境支持
# python2.7
import random
out = open('data.dat', 'w')
for i in range(1000000):
v1 = str(random.randint(111111, 999999))
v2 = str(random.randint(111111, 999999))
out.write(v1 + ' ' + v2)
out.write('\n')
out.flush()
最终生成了100w行的随机数,格式示例如下,每行2个数值。
接着开始使用java编写WordCount程序。我们创建一个maven项目,其中的pom.xml基础配置为
<properties>
<flink.version>1.12.0</flink.version>
<scala.binary.version>2.12</scala.binary.version>
</properties>
<dependencies>
<!-- Apache Flink 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>
<!-- These dependencies are excluded from the application JAR by default. -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.7</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<!--此处我们不需要将依赖打入到jar包中,因为flink原生框架中拥有本项目使用到的jar包。只需要指定jar包的入口类即可-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<useUniqueVersions>false</useUniqueVersions>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>cn.gcy.StreamingJob</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
接着是Java代码
import org.apache.flink.api.common.functions.FlatMapFunction;
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.util.Collector;
public class StreamingJob {
public static void main(String[] args) throws Exception {
//初始化基础配置
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
// 读取本地指定文件路径下的文件,此处建议将 data.dat文件分发到3个节点下。防止提示无法找到此文件的错误提示。
DataStream<String> text = env.readTextFile("file:///soft/data.dat");
// 在这里我们做了3个动作。1、将文本中的内容按照非常见字符进行切割,将其转换为 <word, 1> 这种的格式。接着将其根据word进行聚合分组,聚合完成后根据下标为1的位置进行求和。
DataStream<Tuple2<String, Integer>> counts = text.flatMap(new Tokenizer()).keyBy(value -> value.f0).sum(1);
//将结果写入到本地,为了方便统一查看结果,调整并行度为1
counts.writeAsText("file:///soft/result").setParallelism(1);
// 开启任务
env.execute("Java WordCount from SocketTextStream Example");
}
public static final class Tokenizer implements FlatMapFunction<String, Tuple2<String, Integer>>{
@Override
public void flatMap(String s, Collector<Tuple2<String, Integer>> collector) {
String[] tokens = s.split("\\W+");
for (String token : tokens) {
if(token.length() > 0){
collector.collect(new Tuple2<>(token, 1));
}
}
}
}
}
# 进入项目根目录,将项目打成jar包,并将jar包上传到服务器
mvn clean package
# 提交flink任务
$FLINK_HOME/bin/flink run flink_word_count.jar
执行完毕后,会在某个work节点的/soft/下生成result文件,输出信息如下示例如下,元祖前一位是字符内容,后面是其出现的次数