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的操作类型一致的,是针对最后的数据类型进行处理存储的;
相关推荐
美林数据Tempodata5 小时前
“双新”指引,AI驱动:工业数智应用生产性实践创新
大数据·人工智能·物联网·实践中心建设·金基地建设
人间打气筒(Ada)7 小时前
Centos7 搭建hadoop2.7.2、hbase伪分布式集群
数据库·分布式·hbase
com_4sapi9 小时前
2025 权威认证头部矩阵系统全景对比发布 双榜单交叉验证
大数据·c语言·人工智能·算法·矩阵·机器人
鲸能云11 小时前
政策解读 | “十五五”能源规划下储能发展路径与鲸能云数字化解决方案
大数据·能源
五度易链-区域产业数字化管理平台11 小时前
五度易链大数据治理实战:从数据孤岛到智能决策
大数据
激动的小非11 小时前
电商数据分析报告
大数据·人工智能·数据分析
ITVV12 小时前
湖仓一体部署
大数据·数据湖·湖仓一体
2501_9335090713 小时前
无锡制造企税惠防错指南:知了问账帮守政策红利线
大数据·人工智能·微信小程序
F36_9_13 小时前
如何在沟通不畅导致误解后进行修复
大数据