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的操作类型一致的,是针对最后的数据类型进行处理存储的;
相关推荐
WLJT12312312312 分钟前
九寨:在山水间触摸生活的诗意
大数据·生活
Elastic 中国社区官方博客3 小时前
在 Elasticsearch 中使用 Mistral Chat completions 进行上下文工程
大数据·数据库·人工智能·elasticsearch·搜索引擎·ai·全文检索
橙色云-智橙协同研发4 小时前
从 CAD 图纸到 Excel 数据:橙色云智橙 PLM 打造制造企业数字化协同新模式
大数据·功能测试·云原生·cad·plm·云plm·bom提取
喝可乐的希饭a5 小时前
Elasticsearch 的 Routing 策略详解
大数据·elasticsearch·搜索引擎
TDengine (老段)6 小时前
TDengine 字符串函数 CHAR 用户手册
java·大数据·数据库·物联网·时序数据库·tdengine·涛思数据
2501_933670796 小时前
高职大数据技术专业需要的基础
大数据
Deamon Tree7 小时前
HBase 核心架构和增删改查
java·hbase
科技峰行者8 小时前
微软与OpenAI联合研发“Orion“超大规模AI模型:100万亿参数开启“科学家AI“新纪元
大数据·人工智能·microsoft
拓端研究室8 小时前
2025母婴用品双11营销解码与AI应用洞察报告|附40+份报告PDF、数据、绘图模板汇总下载
大数据·人工智能
GOATLong8 小时前
git使用
大数据·c语言·c++·git·elasticsearch