hbase创建表_Flink SQL实战 — HBase的结合应用

本篇是Flink SQL实战系列文章的第三篇,主要介绍Hbase和Flink SQL的结合使用。Hbase 作为Google发表Big Table论文的开源实现版本,是一种分布式列式存储的数据库,构建在HDFS之上的NoSQL数据库,非常适合大规模实时查询,因此Hbase 在实时计算领域使用非常广泛。可以实时写hbase,也可以利用buckload一把把离线Job生成HFile Load到Hbase 表中。而当下Flink SQL的火热程度不用多说,Flink SQL也为Hbase提供了connector,因此Hbase与Flink SQL的结合非常有必要实践实践。当然,本文假设用户有一定的Hbase知识基础,不会详细去介绍Hbase的架构和原理,本文着重介绍hbase和Flink 在实际场景中的结合使用。主要分为两种场景,第一种场景:HBase 作为维表与Flink Kafka table 做temporal table join的场景;第二种场景:Flink SQL做计算之后的结果写到Hbase表,供其他用户查询的场景。因此,本文介绍的内容如下所示:
  • hbase环境准备

  • 数据准备

  • Hbase作为维度表进行temporal table join的场景

  • Flink SQL做计算写Hbase的场景

  • 总结

01 Hbase 环境准备

由于没有测试的Hbase环境以及为了避免污染线上Hbase环境。因此,自己build一个 Hbase docker image(大家可以docker pull guxinglei/myhbase 拉到本地),是基于官方干净的ubuntu imgae之上安装了Hbase 2.2.0版本以及JDK1.8版本。

  • 启动容器,暴露Hbase web UI 端口以及内置zk端口,方便我们从web 页面看信息以及创建Flink Hbase table需要zk的链接信息

docker run -it --network=host -p 2181:2181 -p 60011:60011 docker.io/guxinglei/myhbase:latest bash

4fd1dd4e2f4449851571fb09945cdfb7.png

  • 进入容器,启动hbase集群,以及启动rest server,后续方便我们用REST API来读取Flink SQL写进Hbase的数据

# 启动hbase 集群bin/start-hbase.sh# 后台启动restServerbin/hbase-daemon.sh start rest -p 8000

336a76fe5d0eadd9d843325bc03db7ad.png

02 数据准备

由于hbase环境是自己临时搞的单机服务,里面没有数据,需要往里面写点数据供后续示例用。在Flink SQL实战系列第二篇中介绍了如何注册Flink Mysql table,我们可以将广告位表抽取到hbase表中,用来做维度表,进行temporal table join。因此,我们需要在Hbase中创建一张表,同时还需要创建Flink Hbase table, 这两张表通过Flink SQL 的Hbase connector关联起来。

  • 在容器中启动hbase shell,创建一张名为dim_hbase的hbase 表,建表语句如下所示:

# 在hbase shell创建 hbase表hbase(main):002:0> create 'dim_hbase','cf'Created table dim_hbaseTook 1.3120 seconds=> Hbase::Table - dim_hbase

6822e7e52452f1f9e7699ca035b5dff4.png

  • 在Flink 中创建Flink Hbase table,建表语句如下所示:

# 注册 Flink Hbase tableDROP TABLE IF EXISTS flink_rtdw.demo.hbase_dim_table;CREATE TABLE flink_rtdw.demo.hbase_dim_table (  rowkey STRING,  cf ROW < adspace_name STRING >,  PRIMARY KEY (rowkey) NOT ENFORCED) WITH (  'connector' = 'hbase-1.4',  'table-name' = 'dim_hbase',  'sink.buffer-flush.max-rows' = '1000',  'zookeeper.quorum' = 'localhost:2181');
  • Flink MySQL table 和 Flink Hbase table已经创建好了,就可以写抽取数据到Hbase的SQL job了,SQL 语句以及job状态如下所示:

# 抽取Mysql数据到Hbase表中insert into  hbase_dim_tableselect  CAST (ID as VARCHAR),  ROW(name)from  mysql_dim_table;

3b9f02bebe1ad62cab480895b0022a4d.png

eb3999d403d05cc4efca897b007aee0b.png

62edd8161abe980cdb6fc525aa620f3e.png

325357a262b60bf062a375a8d5652b02.png

03 HBase 作为维表与Kafka 做temporal join的场景

在Flink SQL join中,维度表的join一定绕不开的,比如订单金额join 汇率表,点击流join广告位的明细表等等,使用场景非常广泛。那么作为分布式数据库的Hbase比MySQL作为维度表用作维度表join更有优势。在Flink SQL实战系列第二篇中,我们注册了广告的点击流,将kafka topic注册Flink Kafka Table,同时也介绍了temporal table join在Flink SQL中的使用;那么本节中将会介绍Hbase作为维度表来使用,上面小节中已经将数据抽取到Hbase中了,我们直接写temporal table join 计算逻辑即可。

  • 作为广告点击流的Flink Kafa table 与 作为广告位的Flink Hbase table通过广告位Id进行temporal table join,输出广告位Id和广告位中文名字,SQL join 逻辑如下所示: 

select adsdw_dwd_max_click_mobileapp.publisher_adspace_adspaceId as publisher_adspace_adspaceId,       hbase_dim_table.cf.adspace_name as publisher_adspace_namefrom adsdw_dwd_max_click_mobileappleft join hbase_dim_table FOR SYSTEM_TIME AS OF adsdw_dwd_max_click_mobileapp.procTimeon cast(adsdw_dwd_max_click_mobileapp.publisher_adspace_adspaceId as string) = hbase_dim_table.rowkey;
  • temporal table join job提交Flink集群上的状态以及join结果如下所示:

1cd7dd4ad443cfde5d2515d02a25a081.png

fbf6a3ba59b3b6e10cb7e341455aff3d.png

04 计算结果sink 到Hbase作为结果的场景

上面小节中,Hbase作为维度表用作temporal table join是非常常见的场景,实际上Hbase作为存储计算结果也是非常常见的场景,毕竟Hbase作为分布式数据库,底层存储是拥有多副本机制的HDFS,维护简单,扩容方便, 实时查询快,而且提供各种客户端方便下游使用存储在Hbase中的数据。那么本小节就介绍Flink SQL将计算结果写到Hbase,并且通过REST API查询计算结果的场景。

  • 进入容器中,在hbase 中新建一张hbase 表,一个column family就满足需求,建表语句如下所示:

# 注册hbase sink tablecreate 'dwa_hbase_click_report','cf'

f5719a01cb4c4122ffa8a12bc9e58137.png

  • 建立好hbase 表之后,我们需要在Flink SQL创建一张Flink Hbase table,这个时候我们需要明确cf 这个column famaly下面column字段,在Flink SQL实战第二篇中,已经注册好了作为点击流的Flink Kafka table,因此本节中,将会计算点击流的uv和点击数,因此两个column分别为uv和click_count,建表语句如下所示:

# 注册 Flink Hbase tableDROP TABLE IF EXISTS flink_rtdw.demo.dwa_hbase_click_report;CREATE TABLE flink_rtdw.demo.dwa_hbase_click_report (  rowkey STRING,  cf ROW < uv BIGINT, click_count BIGINT >,  PRIMARY KEY (rowkey) NOT ENFORCED) WITH (  'connector' = 'hbase-1.4',  'table-name' = 'dwa_hbase_click_report',  'sink.buffer-flush.max-rows' = '1000',  'zookeeper.quorum' = 'hostname:2181');

4d21a73b38e0ec260f618b328ef414ac.png

  • 前面点击流的Flink Kafka table 和存储计算结果的Hbase table 和Flink Hbase table已经准备了,我们将做一个1分钟的翻转窗口计算uv和点击数,并且将计算结果写到Hbase中。对Hbase了解的人应该知道,rowkey的设计对 hbase regoin的分布有着非常重要的影响,基于此我们的rowkey是使用Flink SQL内置的reverse函数进行广告位Id进行反转和窗口启始时间做concat,因此,SQL逻辑语句如下所示:

INSERT INTO dwa_hbase_click_reportSELECT  CONCAT(REVERSE(CAST(publisher_adspace_adspaceId AS STRING)) ,         '_',         CAST((UNIX_TIMESTAMP(DATE_FORMAT(TUMBLE_START(ets, INTERVAL '1' MINUTE),'yyyy-MM-dd HH:mm:ss')) * 1000) AS STRING)  ) as rowkey,   ROW(COUNT(DISTINCT audience_mvid) , COUNT(audience_behavior_click_creative_impressionId)) as cfFROM  adsdw_dwd_max_click_mobileappWHERE publisher_adspace_adspaceId IS NOT NULL AND audience_mvid IS NOT NULL AND audience_behavior_click_creative_impressionId IS NOT NULLGROUP BY  TUMBLE(ets, INTERVAL '1' MINUTE),  publisher_adspace_adspaceId;

ef9a514d41c6b23bbef860a6daec935a.png

  • SQL job提交之后的状态以及结果check如下所示:

0921485fbaadb555c769b27b8c9a0854.png

9013c11d4ff10e64ddc7f68d024875bb.png

上述SQL job已经成功的将结算结果写到Hbase中了。对于线上的hbase 服务来讲,很多同事不一定有hbase 客户端的权限,从而也不能通过hbase shell 读取数据;另外作为线上报表服务显然不可能通过hbase shell来通过查询数据。因此,在实时报表场景中,数据开发工程师将数据写入Hbase, 前端工程师 通过REST API来读取数据。前面我们已经启动了hbase rest server进程,我们可以通rest服务提供读取hbase里面的数据。

  • 我们先get一条刚刚写到hbase中的数据看看,如下所示:

2c6d43e41d60dab2bc8d56561e45f625.png

  • 下面我们开始通过REST API 来查询hbase 中的数据,第一步,执行如下语句拿到scannerId;首先需要将要查询的rowkey进行base64编码才能使用,后面需要将结果进行base64解码

rowkey base64编码前:0122612_1606295280000 

base64编码之后:MDEyMjYxMl8xNjA2Mjk1MjgwMDAw

curl -vi -X PUT \         -H "Accept: text/xml" \         -H "Content-Type: text/xml" \         -d '"MDEyMjYxMl8xNjA2Mjk1MjgwMDAw" endRow=         "http://hostname:8000/dwa_hbase_click_report/scanner"

c795d113362076ecad54c32b26ec25fe.png

  • 第二步,执行如下语句根据上条语句返回的scannerID查询数据,可以看到返回的结果:

curl -vi -X GET \         -H "Accept: application/json" \         "http://hostname:8000/dwa_hbase_click_report/scanner/16063768141736ac0a8b5"

4823c2ea33fa4966373166e9bdf9afe4.png

  • 第三步,查询完毕之后,执行如下语句删除该scannerId:

curl -vi -X DELETE \         -H "Accept: text/xml" \         "http://hostname:8000/dwa_hbase_click_report/scanner/16063768141736ac0a8b5"

0776ddd4f4e3f898715b098e5f2384b6.png

五. 总结

在本篇文章中,我们介绍了Hbase 和Flink SQL的结合使用比较广泛两种的场景: 作为维度表用以及存储计算结果; 同时使用REST API对hbase中的数据进行查询,对于查询用户来说,避免直接暴露hbase的zk,同时将rest server和hbase集群解耦。


作者简介

余敖,360数据开发高级工程师,目前专注于基于Flink的实时数仓建设与平台化工作。对Flink、Kafka、Hive、Spark等进行数据ETL和数仓开发有丰富的经验。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值