FlinkSQL连接Hive并动态插入进Hive数据库中

大家好,我是代码搬运工。最近在利用FlinkSQL进行开发连接Hive数据库的时候遇到了一些小问题,接下来分享给大家以免以后踩坑。

在一个项目中我主要利用FlinkSQL来连接Hive数据库并执行Insert动态插入语句来关联设备信息,话不多说我们直接开始。

maven的依赖如下

    
        org.slf4j
        slf4j-log4j12
        1.7.15
    

    


    
        org.apache.flink
        flink-table-api-java-bridge_2.12
        1.12.2

    

    
        org.apache.flink
        flink-table-api-java
        ${flink.version}

    

    
        org.apache.flink
        flink-table-common
        ${flink.version}

    

    


    
        org.apache.flink
        flink-connector-hive_2.12
        ${flink.version}
    

    
    

    
    
        org.apache.hadoop
        hadoop-common
        2.8.1
    

    
    
        javax.xml.bind
        jaxb-api
        2.2.11
    

    
        org.apache.hive
        hive-exec
        3.1.2
        
            
                log4j-api
                org.apache.logging.log4j
            
            
                log4j
                log4j
            
            
                log4j-core
                org.apache.logging.log4j
            
            
                log4j-slf4j-impl
                org.apache.logging.log4j
            
            
                slf4j-api
                org.slf4j
            
        
    

    
        org.apache.hive
        hive-serde
        ${hive.version}
        
            
                log4j-api
                org.apache.logging.log4j
            
            
                log4j-core
                org.apache.logging.log4j
            
            
                log4j-slf4j-impl
                org.apache.logging.log4j
            
            
                slf4j-api
                org.slf4j
            
        
    

    
        org.apache.hive
        hive-jdbc
        ${hive.version}
        
            
                slf4j-log4j12
                org.slf4j
            
            
                log4j-slf4j-impl
                org.apache.logging.log4j
            
            
                log4j-web
                org.apache.logging.log4j
            
            
                log4j-core
                org.apache.logging.log4j
            
            
                log4j-api
                org.apache.logging.log4j
            
            
                log4j-1.2-api
                org.apache.logging.log4j
            
            
                netty-all
                io.netty
            
            
                hive-common
                org.apache.hive
            
            
                parquet-hadoop-bundle
                org.apache.parquet
            
            
                xerces
                xercesImpl
            
            
                hbase-client
                org.apache.hbase
            
            
                curator-framework
                org.apache.curator
            
            
                zookeeper
                org.apache.zookeeper
            
            
                slf4j-api
                org.slf4j
            
            
                httpcore
                org.apache.httpcomponents
            
            
                httpclient
                org.apache.httpcomponents
            
            
                commons-cli
                commons-cli
            
            
                commons-compress
                org.apache.commons
            
            
                commons-lang
                commons-lang
            
            
                guava
                com.google.guava
            
            
                gson
                com.google.code.gson
            
            
                avro
                org.apache.avro
            
            
                hbase-common
                org.apache.hbase
            
            
                hbase-hadoop2-compat
                org.apache.hbase
            
            
                hbase-server
                org.apache.hbase
            
            
                tephra-hbase-compat-1.0
                co.cask.tephra
            
            
                hbase-hadoop-compat
                org.apache.hbase
            
            
                log4j
                log4j
            
        
    



1.首先我们先用FlinkSQL连接Hive

!注意,这里我们要使用阿里的Blanner 我在这里踩了巨坑,一定要用阿里的Blanner才可以执行动态insert

因为Flink是流式处理,

如果我们构建table的环境是流式环境的话,数据是源源不断得输入进来。如下所示

     // 构建运行流处理的运行环境
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        // 构建table环境
        StreamTableEnvironment tableEnv = StreamTableEnvironment.create(env);

这样的话我们执行动态操作的时候,例如 Insert intoXXXX Select * from XXX等语句是会报错误的,Hive Table SInk是不支持这样的。

我们查看源码可知。

Hive Table的INSERT只支持带有"+I"的数据,不允许带有-U和+U就是会改变的数据。

那怎么解决呢,不可能我想写个动态sql都不行吧,晕。。。。。

还好国内阿里进行了FlinkSQL优化,解决方法是利用阿里的BlinkPlanner来构建表环境,阿里已经内部帮你优化好了。

 //使用阿里的Planner
        EnvironmentSettings settings = 	       EnvironmentSettings.newInstance().useBlinkPlanner().inBatchMode().build();
        // 构建table环境
        TableEnvironment tableEnv = TableEnvironment.create(settings);
        //TODO 设置env的checkpoint等其他信息
        //设置方言 不同数据库的语句有差别
        tableEnv.getConfig().setSqlDialect(SqlDialect.HIVE);

2.HiveCatalog连接Hive

构建好表环境后我们直接利用HiveCatalog来连接Hive数据库(里面我只是举例子,公司里一般写在常量里,直接调用就行,在公司这样写代码不被骂死我都服你)

 //构造hive catalog 直接调用hiveconstans就可以
// Catalog名称,定义一个唯一的名称表示
         String NAME="myhive";
// 默认Hive数据库名称
   String DEFAULTDATABASE="lwtest";
//hive-site.xml路径  运行Flink的Linux目录下
   String HIVECONFDIRPATH="/etc/hive/conf";
 //hive版本
    String VERSION="3.1.2";

    HiveCatalog myHive=new HiveCatalog(NAME, DEFAULTDATABASE,HIVECONFDIRPATH, VERSION);
//注册指定名字的catalog
        tableEnv.registerCatalog("myhive",myHive);
        //使用上面注册的catalog
        tableEnv.useCatalog("myhive");

3.编写sql

然后我们就可以写自己的sql代码啦

		 //执行逻辑
       Table tableResult = tableEnv.sqlQuery(sql);
		//获取的结果直接打印
        tableResult1.execute().print();
          //获取结果的迭代器,可以循环迭代器获取结果
       CloseableIterator<Row> rows = tableResult.execute().collect();

   
        //利用executeSql执行插入更新代码
       //例如insert into table xxxx select * from xxxx; 
        TableResult tableResult1 = tableEnv.executeSql(sql);

调用executeSql不需要调用execute,如果里面有datastream api就需要execute

完整代码如下

        //使用阿里的Planner
        EnvironmentSettings settings = EnvironmentSettings.newInstance().useBlinkPlanner().inBatchMode().build();
        // 构建table环境
        TableEnvironment tableEnv = TableEnvironment.create(settings);
        //TODO 设置env的checkpoint等其他信息
        //设置方言 不同数据库的语句有差别
        tableEnv.getConfig().setSqlDialect(SqlDialect.HIVE);

 //构造hive catalog 直接调用hiveconstans就可以
// Catalog名称,定义一个唯一的名称表示
         String NAME="myhive";
// 默认Hive数据库名称
   String DEFAULTDATABASE="lwtest";
//hive-site.xml路径  运行Flink的Linux目录下
   String HIVECONFDIRPATH="/etc/hive/conf";
 //hive版本
    String VERSION="3.1.2";

    HiveCatalog myHive=new HiveCatalog(NAME, DEFAULTDATABASE,HIVECONFDIRPATH, VERSION);

//注册指定名字的catalog
        tableEnv.registerCatalog("myhive",myHive);
        //使用上面注册的catalog
        tableEnv.useCatalog("myhive");

        // 执行逻辑
		String sql="select * from xxxx";
        Table tableResult1 = tableEnv.sqlQuery(sql);
        tableResult1.execute().print();
        //获取结果的迭代器,可以循环迭代器获取结果
       CloseableIterator<Row> rows = tableResult1.execute().collect();


        //执行executeSql 插入或更新数据库
		String executeSql="insert into table xxxx select * from xxxx";
        TableResult tableResult6 = tableEnv.executeSql(executeSql);

你可能感兴趣的:(hive,数据库,flink,sql)