达梦 hive spark hbase phoenix相互关联查询 您所在的位置:网站首页 phoenix关联查询效率高低 达梦 hive spark hbase phoenix相互关联查询

达梦 hive spark hbase phoenix相互关联查询

2024-07-11 21:22| 来源: 网络整理| 查看: 265

目的

对达梦的数据通过hive/spark进行分析计算,将结果存入hbase。

实际情况

有两种方式可供选择:1)利用spark与dm的jdbc链接直接读取dm中的数据进行计算,但是spark与hbase无法建立映射所以数据不能直接写入hbase中;2)hive可以与hbase建立映射但是无法与达梦建立连接烦死了

Solution

1.通过spark与dm的jdbc连接,先把数据导入hdfs。 两种:一种是全表导,一种是通过sql语句选择部分导入

CREATE table tmp_spark_table USING org.apache.spark.sql.jdbc OPTIONS ( url 'jdbc:dm://192.x.xx.xxx:5236/DB', driver 'dm.jdbc.driver.DmDriver', dbtable 'DB.dm_table', user 'user', password 'password', fetchsize 500000 ); CREATE table tmp_spark_table USING org.apache.spark.sql.jdbc OPTIONS ( url 'jdbc:dm://192.x.xx.xxx:5236/DB', driver 'dm.jdbc.driver.DmDriver', query "select * from DB.dm_table where create_time like '2021-10-01%'", user 'user', password 'password', fetchsize 500000 );

但现在导进来的表并没有列的概念,所有列都被揉成了一个列:col 可以通过show create table语句查看:

> show create table tmp_spark_table; ======================================================= CREATE TABLE `tmp_spark_table`( `col` array COMMENT 'from deserializer') ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe'

2.所以必须要在spark中建立一张新的表,对数据进行“分列”。如果有分区的需求,要在建表的时候就指定分区,这样数据才能在添加的时候找到指定的分区里。

不需要分区 CREATE TABLE real_spark_table AS SELECT * FROM tmp_spark_table; 分区 CREATE TABLE real_spark_table partitioned by (date_partition) AS SELECT *, date_format(create_time,'y-MM-dd') as date_partition FROM tmp_spark_table;

如果不需要设置为ORC格式,那就别加STORED AS ORC,这样默认为TextFile格式,从hive是可以查看到数据的。

如果要存为ORC格式,需要设置 (from连接) set spark.sql.hive.convertMetastoreOrc=true set spark.sql.orc.impl=native (我没有测试过,但我认为我没成功的原因应该是在这里)

CREATE TABLE real_spark_table STORED AS ORC AS SELECT * FROM tmp_spark_table;

如果设置成了orc,但是没有像上面修改配置的话那么会出现:从spark里能查到数据,但是hive里都为NULL的情况。

到这里,我们的数据准备工作就已经结束了。

3.接下来是建立从hive到hbase的映射。 建立映射的顺序为,先在hbase里建结果表,再到hive里建结果表,但是在hive建表时要指定STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'且关联在hbase中的那张表(表名必须相同),这样当我们在hive中执行insert语句的时候,hbase中对应的映射表也会自动添加数据。

hbase: create 'real_result_table','cf' hive: create external table real_result_table( id string, insert_time string, result decimal(16,4) ) STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler' WITH SERDEPROPERTIES ("hbase.columns.mapping" = ":key, cf:insert_time, cf:result") TBLPROPERTIES("hbase.table.name" = "real_result_table");

ok这样我们无论在hive中添加什么数据,hbase中的表也会立刻查到。 需要注意的是,此时这张表的数据存在hbase中而不是hive中。可以通过两种方式验证:1)直接打开hdfs,一直找到hive和hbase两张表的路径,会发现hive下是空的,而hbase里才有数据文件。2)向hive中insert一条数据,会看到日志里最后数据落盘是落在了hbase的路径下

4.然后我们又想从phoenix去查询hbase中的结果烦不烦 在phoenix里输入!tables 会显示已有的所有表,但是去执行查询语句,会发现什么都查不到。而hbase中的数据是一直在插入更新的,所以我们要在phoenix中建立一个hbase的视图(同名),这样就可以查询了。

create view "real_result_table"( "ROW" VARCHAR PRIMARY KEY, "cf"."insert_time" VARCHAR, "cf"."result" DECIMAL(16,4) );

5.再回头捋一下顺序: 【准备原始数据表】:通过spark迁移进hdfs, 【准备要写入的结果表】:先在hbase建表,再去hive建表,tablename相同。必须先去hbase建表,不然hive不知道去关联hbase中的哪张表 【分析】:正常执行hive/spark的udf,insert into结果表 【查询】:在hbase可以直接查询,但是要从phoenix查必须要建立关于hbase这张表的视图,通过视图去查询。

最后还有一点:虽然通过phoenix也可以在hbase建表,但是我们不能这么做。如果在phoenix按照正常create table语句建立了real_result_table,有三个字段:id,insert_time和result,再去hbase查看发现他还会多一列value=x,而多的这一列会导致hive的分析结果没办法插入结果表中。

6.然后我手闲的在hive里手动插入了一条数据,发现phoenix可以正常查询出来,满心欢喜的准备再把这条数据delete掉,可是这个时候报错: FAILED: SemanticException [Error 10297]: Attempt to do update or delete on table DB.real_result_table that does not use an AcidOutputFormat or is not bucketed 意思是说,这张hive结果表不是AcidOutputFormat或没有分桶,意思只有AcidOutputFormat或者分桶的表才能delete/update。 俺查了查,link说,AcidOutputFormat是给ORC用的,so u know what to do.

但我又心生一计,这数据不是存在hbase里的吗,我去hbase删除,果然直接删掉了。手动狗头。

deleteall "real_result_table","test_id"

hbase删除数据指路



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有