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的操作类型一致的,是针对最后的数据类型进行处理存储的;
相关推荐
Dreams°1232 小时前
大数据 ETL + Flume 数据清洗 — 详细教程及实例(附常见问题及解决方案)
大数据·单元测试·可用性测试
静听山水2 小时前
Flink处理无界数据流
flink
sf_www2 小时前
Flink on YARN是如何确定TaskManager个数的
大数据·flink
静听山水2 小时前
Flink API 的层次结构
flink
武子康3 小时前
大数据-213 数据挖掘 机器学习理论 - KMeans Python 实现 距离计算函数 质心函数 聚类函数
大数据·人工智能·python·机器学习·数据挖掘·scikit-learn·kmeans
武子康3 小时前
大数据-214 数据挖掘 机器学习理论 - KMeans Python 实现 算法验证 sklearn n_clusters labels
大数据·人工智能·python·深度学习·算法·机器学习·数据挖掘
Aloudata4 小时前
NoETL自动化指标平台为数据分析提质增效,驱动业务决策
大数据·数据分析·指标平台·指标体系
2401_883041088 小时前
新锐品牌电商代运营公司都有哪些?
大数据·人工智能
青云交8 小时前
大数据新视界 -- 大数据大厂之 Impala 性能优化:融合机器学习的未来之路(上 (2-1))(11/30)
大数据·计算资源·应用案例·数据交互·impala 性能优化·机器学习融合·行业拓展
Json_1817901448011 小时前
An In-depth Look into the 1688 Product Details Data API Interface
大数据·json