7、 老版本创建流处理批处理
7.1 老版本流处理
val settings = EnvironmentSettings.newInstance()
.useOldPlanner() // 使用老版本 planner
.inStreamingMode() // 流处理模式
.build()
val tableEnv = StreamTableEnvironment.create(env, settings)
7.2 老版本批处理
val batchEnv = ExecutionEnvironment.getExecutionEnvironment
val batchTableEnv = BatchTableEnvironment.create(batchEnv)
7.3 blink 版本的流处理环境
val bsSettings = EnvironmentSettings.newInstance()
.useBlinkPlanner()
.inStreamingMode().build()
val bsTableEnv = StreamTableEnvironment.create(env, bsSettings)
7.4 blink 版本的批处理环境
val bbSettings = EnvironmentSettings.newInstance()
.useBlinkPlanner()
.inBatchMode().build()
val bbTableEnv = TableEnvironment.create(bbSettings)
// 连接外部文件
bbTableEnv.connect(new FileSystem().path("file:///E:/d.txt"))
.withFormat(new Csv().fieldDelimiter(','))
.withSchema(new Schema().field("id", DataTypes.STRING()))
.createTemporaryTable("output");
// 设置 hive 方言
bbTableEnv.getConfig().setSqlDialect(SqlDialect.HIVE);
// 获取hive-site.xml目录
String hiveConfDir = Thread.currentThread().getContextClassLoader().getResource("").getPath().substring(1);
HiveCatalog hive = new HiveCatalog("hive", "warningplatform", hiveConfDir);
bbTableEnv.registerCatalog("hive", hive);
bbTableEnv.useCatalog("hive");
bbTableEnv.useDatabase("warningplatform");
bbTableEnv.executeSql("insert into test select id from default_catalog.default_database.output");
通过bbTableEnv.connect()去创建临时表的方式已经过时了,建议使用bbTableEnv.executeSql()的方式,通过DDL去创建临时表,临时表到底是属于哪一个catalog目前还不太确定,到底是什么规则目前还不清楚。 查资料得知,临时表与单个Flink会话的生命周期相关,临时表始终存储在内存中。 永久表需要一个catalog来管理表对应的元数据,比如hive metastore,该表将一直存在,直到明确删除该表为止。 因此猜测:default_catalog是存储在内存中,如果在切换成hive catalog之前创建临时表,那我们就可以使用default_catalog.default_database.tableName来获取这个临时表。 如果切换了catalog再去创建临时表,那我们就无法获取到临时表了,因为它不在default_catalog中,而且保存在内存里面,直接查询临时表会去当前的catalog里面去查找临时表,因此一定要在default_catalog 里面创建临时表。 而临时视图好像是存储在当前的catalog里面
通过bbTableEnv.createTemporaryView()创建的视图则是属于当前的database的
bbTableEnv.createTemporaryView("output",bbTableEnv.sqlQuery("select * from default_catalog.default_database.output"));
注意1.11版本的执行sql的方法发生了改变,通过执行环境的executeSql(),executeInsert()等来进行插入或者执行sql语句
public static void main(String[] args) throws Exception {
ParameterTool params = ParameterTool.fromArgs(args);
EnvironmentSettings settings = EnvironmentSettings
.newInstance()
.useBlinkPlanner() // 使用BlinkPlanner
.inBatchMode() // Batch模式,默认为StreamingMode
.build();
TableEnvironment tableEnv = TableEnvironment.create(settings);
String name = "myhive"; // Catalog名称,定义一个唯一的名称表示
String defaultDatabase = params.get("defaultDatabase"); // 默认数据库名称
String hiveConfDir = params.get("hiveConf"); // hive-site.xml路径
String version = "2.1.1"; // Hive版本号
HiveCatalog hive = new HiveCatalog(name, defaultDatabase, hiveConfDir, version);
tableEnv.registerCatalog("myhive", hive);
tableEnv.useCatalog("myhive");
TableResult result;
String SelectTables_sql ="select * from test.testdata";
result = tableEnv.executeSql(SelectTables_sql);
result.print();
}
1、进入flink的目录下执行 bin/start-cluster.sh
2、登录rest.address : rest.port查看网页是否正常运行
3、执行命令提交任务
flink/flink-1.13.1/bin/flink run -c org.example.FlinkHiveIntegration flink/job/flinkcommonjob-1.1.jar -hiveConf /etc/hive/conf.cloudera.hive/ -defaultDatabase test
Caused by: java.lang.NoClassDefFoundError: Lorg/apache/hadoop/mapred/JobConf;
解决方法:补充hadoop-mapreduce-client-core-3.0.0.jar包
需求: 将一个txt文本文件作为输入流读取数据过滤id不等于sensor_1的数据
实现思路: 首先我们先构建一个table的env环境通过connect提供的方法来读取数据然后设置表结构将数据注册为一张表就可进行我们的数据过滤了(使用sql或者流处理方式进行解析)
准备数据
sensor_1,1547718199,35.8
sensor_6,1547718201,15.4
sensor_7,1547718202,6.7
object FlinkSqlTable {
def main(args: Array[String]): Unit = {
// 构建运行流处理的运行环境
val env = StreamExecutionEnvironment.getExecutionEnvironment
// 构建table环境
val tableEnv = StreamTableEnvironment.create(env)
//通过 connect 读取数据
tableEnv.connect(new FileSystem().path("D:\\d12\\Flink\\FlinkSql\\src\\main\\resources\\sensor.txt"))
.withFormat(new Csv()) //设置类型
.withSchema(new Schema() // 给数据添加元数信息
.field("id", DataTypes.STRING())
.field("time", DataTypes.BIGINT())
.field("temperature", DataTypes.DOUBLE())
).createTemporaryTable("inputTable") // 创建一个临时表
val resTable = tableEnv.from("inputTable")
.select("*").filter('id === "sensor_1")
// 使用sql的方式查询数据
var resSql = tableEnv.sqlQuery("select * from inputTable where id='sensor_1'")
// 将数据转为流进行输出
resTable.toAppendStream[(String, Long, Double)].print("resTable")
resSql.toAppendStream[(String, Long, Double)].print("resSql")
env.execute("FlinkSqlWrodCount")
}
}
6、TableEnvironment 的作用
注册 catalog
在内部 catalog 中注册表
执行 SQL 查询
注册用户自定义函数
注册用户自定义函数
保存对 ExecutionEnvironment 或 StreamExecutionEnvironment 的引用
在创建 TableEnv 的时候,可以多传入一个 EnvironmentSettings 或者 TableConfig 参数,可以用来配置 TableEnvironment 的一些特性。