Flink数据实时写入HBase

  • main

    object MyHbaseSinkTest {
    def main(args: Array[String]): Unit = {
    //环境
    val env = StreamExecutionEnvironment.getExecutionEnvironment

      /**
       * 获取基础参数
       */
      val bootstrapserversnew = Contant.BOOTSTRAP_SERVERS_NEW
      import org.apache.flink.api.scala._
    
      /**
       * 定义kafka-source得到DataStream
       */
      val topics = "vs_merging_middle_topic"
      //将kafka中数据反序列化,
      val valueDeserializer: DeserializationSchema[String] = new SimpleStringSchema()
    
      val properties = new Properties()
      properties.put("bootstrap.servers", bootstrapserversnew)
      properties.put("group.id", "flink_hbase_sink_consumer2")
      properties.put("auto.offset.reset", Contant.AUTO_OFFSET_RESET_VALUE)
    
      println(Contant.BOOTSTRAP_SERVERS_NEW)
      val kafkaSinkDStream = env.addSource(new FlinkKafkaConsumer[String](topics, valueDeserializer, properties))
    
      kafkaSinkDStream.flatMap(data => {
        val jsonData = JSON.parseObject(data)
        val table = jsonData.getString("table")
        val rowkey = jsonData.getJSONObject("data").get("id").toString
        val jsonResult = jsonData.getJSONObject("data")
        import scala.collection.JavaConversions._
        jsonResult.keySet().map(key => {
          HbaseValueBean("variable_system:" + table, rowkey, "info", key, jsonResult.get(key).toString)
        })
      })
        .addSink(MyHbaseSinkSingle)
    
      env.execute(this.getClass.getSimpleName)
    }
    

    }

  • bean

    case class HbaseValueBean(
    tableName : String ,
    rowkey : String ,
    family : String ,
    column : String ,
    value : String
    )

  • HBase-Sink

    object MyHbaseSinkSingle extends RichSinkFunction[HbaseValueBean] {
    private var putsResult: List[Put] = collection.immutable.ListPut
    private var hbaseConn: Connection = null
    private var maxSize = 100

    /**
     * 开始,打开连接
     *
     * @param parameters
     */
    override def open(parameters: Configuration): Unit = {
      hbaseConn = HBaseUtils.getHbaseConnNotPoolNew
      maxSize = parameters.getInteger("maxSize" , 100)
      //    val lastInvokeTime = System.currentTimeMillis
    }
    
    /**
     * 数据处理
     *
     * @param value
     * @param context
     */
    override def invoke(value: HbaseValueBean, context: SinkFunction.Context[_]): Unit = {
      if (value.tableName == "variable_system:risk_task") {
    
        import scala.collection.JavaConversions._
        /**
         * rowkey与put
         */
        val put = new Put(value.rowkey.getBytes())
        PutUtils.setDataString(put , value.family , value.column , value.value)
        putsResult = putsResult :+ put
        println(s"puts-size:${putsResult.size}")
    
        /**
         * 判断输出
         */
        if (putsResult.size() >= maxSize) {
          val table = hbaseConn.getTable(TableName.valueOf(value.tableName))
          table.put(putsResult)
    
          println("进行sink")
          println(s"table:${value.tableName} , 已经达到:${maxSize} , 已存储;")
          println(s"puts:${putsResult}")
    
          /**
           * 因为Java与Scala集合转换,所以这里是没有scala的清除方法的
           */
          putsResult = collection.immutable.List[Put]()
          table.close()
        }
      }
    }
    
    /**
     * 满足条件输出数据并且关闭连接
     */
    override def close(): Unit = {
      hbaseConn.close()
    }
    

    }

  • HBase-Connect

    def getHbaseConnNotPoolNew: Connection = {
    var conf: Configuration = HBaseConfiguration.create
    conf.set("hbase.zookeeper.quorum", "host:port")
    conf.set("hbase.zookeeper.property.clientPort", "port")
    conf.set("hbase.master", "16000")
    conf.set("hbase.rootdir", "dir")
    val conn = ConnectionFactory.createConnection(conf)
    conn
    }

  • HBase-Utiles

    object PutUtils {
    def setDataString(put: Put,cf:String,col:String,data:String): Unit ={
    put.addColumn(Bytes.toBytes(cf) , Bytes.toBytes(col) , Bytes.toBytes(data))
    }

    def setDataStringGetPut(put: Put,cf:String,col:String,data:String): Put ={
      put.addColumn(Bytes.toBytes(cf) , Bytes.toBytes(col) , Bytes.toBytes(if(data!= null && data != "") data else "null"))
    }
    

    }

部署

#!/bin/bash
flink run -m yarn-cluster \
-c com.xxxx.flink.MyHbaseSinkTest \
-p 8 \
/home/cdh/xxxx/2020/11/FlinkToKuduDemo/realtime_source_dw.jar

注意事项

  1. 不能够以Spark Streaming的方式来理解Fink的Source和Sink,如果使用客户端是无法针对每个分区进行连接数据处理的,使用Sink可以建立全局连接进行数据存储;
  2. 由上面,全局连接,全局数据处理导致的问题就是不能够每个分区建立线程不安全的集合进行数据存储,必须使用线程安全的集合,也就是不可变的集合进行数据处理,那么使用了Scala之间的集合转换就要注意方法的使用,很多Java结合的方法Scala是没有的,所以一般的清空操作还是使用地址替换重新复制覆盖的方式来进行
  3. addSink的之前的DataStream的数据类型一定是与自定义Sink的操作类型一致的,是针对最后的数据类型进行处理存储的;
相关推荐
B站计算机毕业设计超人3 分钟前
计算机毕业设计hadoop+spark知网文献论文推荐系统 知识图谱 知网爬虫 知网数据分析 知网大数据 知网可视化 预测系统 大数据毕业设计 机器学习
大数据·hadoop·爬虫·机器学习·spark·知识图谱·推荐算法
Yz98767 分钟前
Hadoop里面MapReduce的序列化与Java序列化比较
java·大数据·jvm·hadoop·分布式·mapreduce·big data
Fan1 小时前
Elasticsearch 下载安装及使用总结
大数据·elasticsearch·jenkins
m0_713344852 小时前
新能源汽车数据大全(产销数据\充电桩\专利等)
大数据·人工智能·新能源汽车
goTsHgo3 小时前
从底层原理上解释 ClickHouse 的索引
大数据·clickhouse
Yz98763 小时前
Hadoop-MapReduce的 原理 | 块和片 | Shuffle 过程 | Combiner
大数据·数据库·数据仓库·hadoop·mapreduce·big data
新榜有数3 小时前
品牌建设是什么?怎么做好品牌建设?
大数据·矩阵·数据分析·新媒体运营·流量运营·媒体·内容运营
好记性+烂笔头4 小时前
Flink提交任务
大数据·flink
Apache Flink4 小时前
Apache Flink 流批融合技术介绍
人工智能·flink·apache
goTsHgo4 小时前
Flink 中 Checkpoint 的底层原理和机制
大数据·flink