千家信息网

hbase的sql解决方案是怎样的

发表于:2025-01-31 作者:千家信息网编辑
千家信息网最后更新 2025年01月31日,hbase的sql解决方案是怎样的,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。最近的需求是希望能用mysql、sqls
千家信息网最后更新 2025年01月31日hbase的sql解决方案是怎样的

hbase的sql解决方案是怎样的,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。

最近的需求是希望能用mysql、sqlserver这样的sql来进行hbase的数据查询,这样不但查询比起hbase自带的查询语言更符合使用习惯,也能够整合mybatis、hibernate的框架,写起来不用考虑这么多。我上网一搜:"hbase sql查询",phoenix有最多的教程贴。被这么多人使用,肯定有它的独到之处,并且劣势不会那么难以接受,那么我先用phoenix试试效果,看看感受如何。

首先phoenix的安装并不困难,简单来说下载对应hbase版本的phoenix,解压之后把对应包放入每个hbase RegionServer的lib下面,重启hbase就可以了。我的hadoop是cdh 6.3.0版本,在安装的时候没有遇到什么困难。之后进入phoenix的安装位置的bin目录,执行sqlline.py,就能在shell中进入phoenix的使用界面了。

安装成功,先试试phoenix的一些基础操作,比如!tables,create table等等。都没有问题,使用习惯也和mysql差不多。比较大的不同之处在于插入和更新都用的是upsert,这和hbase也是比较类似的。

在linux上使用也没有问题,那么接下来就是使用javaApi进行连接。连接方式也并不困难,和其它组件差不多,配置连接信息然后就能连接了。具体怎么配网上教程很多,我就不做搬运工了。随便找个链接【十二】Phoenix Java API操作 同质化内容那么多,总要说点自己的东西。值得一提的是phoenix是用jdbc连接的,配置看上去就和mysql的连接一样,显然这是十分友好的。在按照上面教程操作过后,我感觉十分欣喜,不愧是众多教程所推荐的中间件,使用起来太舒爽了(除了手动加两个phoenix的包,也不知道能不能在pom文件里面配置自动加载这样不值一提的小问题),就连我这样的小白都能轻松使用。不过教程上面的表都是直接建立在默认命名空间的,假如我想建立在指定命名空间,那应该怎么办呢?

按照之前的习惯,我直接将表名改为 命名空间.表名,但是报了错,表示没有找到namespace.table这张表。是因为我用的.出错了吗?我将.改为:,但还是报错,报错信息只是将namespace.table改为namespace:table,说明错误类型都是一样的,错误不在这里。

上网搜索"phoenix 指定命名空间",大量的帖子告诉了我一件事:phoenix想要使用命名空间映射,需要额外的配置。这里要说一下,很多教程写的不完全一样,有的多一些有的少一些,按照经验来说,多配置一些更不容易出问题。给出一个配置比较全的帖子:HBase - Phoenix的安装使用教程3(SCHEMA的启用、操作、关闭) 。在我看各种关于如何开启phoenix命名空间映射帖子的时候,有些帖子提到这个功能不但无法正常使用,反而还把原本正常的功能弄出问题了。关于如何关闭在上面这个帖子里面也有,我在使用过程中没有遇到,给大家看看以防万一。

我当时看的帖子是cdh版的,帖子现在找不到了,配置内容是在web页面完成的,配置内容更多一些,我把完成后的结果给大家看看,步骤基本都差不多,方法不同而已。

分别在客户端和服务端配置信息,并将这两个配置写入phoenix的bin目录的hbase.site.xml文件内。

之后重启hbase,在shell中进入phoenix,就能够使用create schema 来创建命名空间了。

再试试用java api来连接,先将之前下载的hbase.site.xml换成现在的,然后再次连接,报错配置信息错误,和我之前新加的phoenix配置有关。感觉像是我哪里配置没配好,找半天也找不到。本着先能用的方式在创建phoenix连接的时候手动加入配置:

Properties pros = new Properties();pros.setProperty("phoenix.schema.isNamespaceMappingEnabled", "true");pros.setProperty("phoenix.schema.mapSystemTablesToNamespace", Boolean.toString(true));

之后再创建的连接就没有问题了。能够直接查询多个命名空间下面的表,相当于跨库查询。要注意的一点是:当你使用shell进入phoenix创建命名空间下面的表时,需要先use schema,然后才能创建表。但是在你使用java api进行创建的时候就不需要这么麻烦,直接 create table schema.table即可,不需要像shell中一样那么麻烦。假如像shell中一样先use schema 再create table反而会报错。关于这一点我倒是没看到有教程提到,明明这才是比较有价值的东西。

举个栗子:

public static void selectTable() throws SQLException{            String sql = "select * from ENTERPRISE_INFORMATION.TEST_PHOENIX_API a left join ENTERPRISE_INFORMATION.TEST_PHOENIX_API2 b on a.mykey = b.mykey ";            rs = stat.executeQuery(sql);            JSONArray array = resultSetToJosnArray(rs);            System.out.println(array.toJSONString());    }        public static void testCreateTable() throws SQLException {        String sql="create table ENTERPRISE_INFORMATION.test_phoenix_api2(mykey integer not null primary key ,mycolumn varchar )";        stat.executeUpdate(sql);        conn.commit();    }     public static void upsert() throws SQLException {        String sql1="upsert into ENTERPRISE_INFORMATION.test_phoenix_api2 values(1,'test4')";        String sql2="upsert into ENTERPRISE_INFORMATION.test_phoenix_api2 values(2,'test5')";        String sql3="upsert into ENTERPRISE_INFORMATION.test_phoenix_api2 values(3,'test6')";        stat.executeUpdate(sql1);        stat.executeUpdate(sql2);        stat.executeUpdate(sql3);        conn.commit();    }     public static void delete() throws SQLException {        String sql1="delete from ENTERPRISE_INFORMATION.test_phoenix_api where mykey = 1";        stat.executeUpdate(sql1);        conn.commit();    }     public static void deleteTable() throws SQLException {            String sql = "drop table ENTERPRISE_INFORMATION.test_phoenix_api";            stat.executeUpdate(sql);            conn.commit();      

创建连接之后,执行的表名直接使用schema.table即可,不加双引号的情况下,无论大小写都会被转换成大写。在执行select的时候,要使用rs = stat.executeQuery(sql);在增删改的时候,使用stat.executeUpdate(sql)。假如在增删改的时候使用executeQuery,可能会报错。另外还要注意一点,phoenix在识别string类型数据的时候要使用单引号而不是双引号,双引号会报错无法识别,这一点无论是在shell还是java api执行的时候都是一样的,比如我上面的sql:

"upsert into ENTERPRISE_INFORMATION.test_phoenix_api2 values(1,'test4')";

test4是用单引号包起来的,这一点一定要注意。

我之前使用的是squirrel-3.7.1来进行phoenix的图形化界面操作。配置比较简单,需要把phoenix的驱动加入,之后写下phoenix的jdbc连接就可以了。使用还算,并且能够连接多种数据库。但是在我进行phoenix命名空间映射后,就无法连接上了。报错和我之前通过java api连接报错一样,缺少关于phoenix.schema的配置。这一点没法解决,我真找不到哪里的配置有问题。网上大把的教程没能解决我这个问题,最后我只有放弃squirrel,而是使用shell来操作phoenix。

以上都是小问题,还在我的接受范围之内。那么接下来就是要将phoenix和hbase已有的表进行映射。按照我对phoenix的理解,phoenix在使用上是和mysql一样的,schema映射为命名空间,table假如没有就在hbase中新建一个表并且将它们映射在一起,我操作phoenix中的表就能将修改转换成hbase的语句;假如table和hbase已有表名一样那么就新建映射,操作还是一样的。那么最好hbase中的表名本身就是大写,我就不用特地用双引号修饰表名,写起来方便很多。

事实上我的想法没有错,只要映射的表名相同,那么就能够通过phoenix来修改hbase的数据。但是当我通过phoenix修改已有数据的时候,我发现了一件奇怪的事--phoenix不能看见hbase已有数据,但是假如把phoenix表删掉的话,hbase表也会一起被删掉,这说明映射是成功的。但是为什么在phoenix中会看不到数据呢?在hbase中是能够看到的数据的,当我尝试用phoenix往映射表中加数据,再在hbase中查看数据时,发现了一件奇怪的事:

hbase创表(通过sqoop将mysql表导入hbase):

sqoop import \--connect jdbc:mysql://192.168.49.201:3306/envir \--username root \--password Hskj123456! \--table hs_apply_detailinfo_r  \--hbase-table ENVIR:HS_APPLY_DETAILINFO_R \--m 1 \--column-family 0  \--hbase-create-table \--hbase-row-key ID

phoenix创表:

CREATE TABLE envir.hs_apply_detailinfo_r (  ID varchar primary key,  APPLY_TYPE varchar ,  APPLY_ID varchar ,  MAT_CD varchar ,  MAT_NUM double ,  PRODUCE_TIME date ,  OUTDATE_TIME date,  SUP_CD varchar)

phoenix修改数据:

upsert envir.hs_apply_detailinfo_r (ID,APPLY_ID) values ('10','2');

在phoenix中查看envir.hs_apply_detailinfo_r的数据,能看到新加的数据,并且只有这一条,hbase导入的表的数据是没有的。再到hbase中scan一下,发现了表中新加了数据,而不是修改原来row为10 ,列为0:APPLY_ID的单元格,而是新加了一个单元格,列限定符为十六进制码,而不是我在phoenix中输入的APPLY_ID;并且值也不是我所输入的字符串2,而是一串十六进制码。在hue中,我也无法查看由phoenix映射的表的数据。

这个问题比较大,直接影响到我是否会继续使用phoenix,但是我又不是很明白哪里出了问题,在网上一直搜索,大概知道了问题出在phoenix在保存字符的时候处理方式和hbase是不一样的,假如phoenix表字段要映射到hbase表字段,要加上column_encoded_bytes=0;并且字段属性要修改,能用unsigned_的尽量用unsigned_。

Phoenix 映射已存在 HBase 表,查询不到数据

phoenix映射hbase中数据类型问题

所以phoenix表的创建应该改为:

CREATE TABLE envir.hs_apply_detailinfo_r(  "ID" varchar primary key,  "info"."APPLY_TYPE" VARBINARY,  "info"."APPLY_ID" VARBINARY,  "info"."MAT_CD" varchar,  "info"."MAT_NUM" UNSIGNED_DOUBLE,  "info"."PRODUCE_TIME" UNSIGNED_DATE,  "info"."OUTDATE_TIME" UNSIGNED_DATE,  "info"."SUP_CD" varchar)column_encoded_bytes=0;

我将列族改为了info,所以上面用sqoop导入的时候也应该将--column-family改为info。0是在phoenix不指定列族的时候默认列族。

修改之后,表字段映射的问题解决了,我能修改row=10,列为info:APPLY_TYPE单元格的值了。但是数值的问题依然没有解决,我在phoenix输入的值为'2',在hbase查看的结果依然是十六进制码。这个问题有点无解,太底层了,我看了phoenix官网给出的关于数据类型转换的介绍(http://phoenix.apache.org/language/datatypes.html) ,里面没有解决办法。其它网友也遇到了类似的问题,给出的解决办法是:当用hbase存储的时候,先用Bytes.toBytes()压缩成phoenix的形式,这样就能用phoenix来获得hbase所插入的数据了。

此外,phoenix存储hbase的int时会有问题,会报错字段长度不够。还是以上的hbase表和phoenix表,假如我先创建phoenix表,再通过sqoop将数据导入hbase,就会报错字段长度不够(hbase-presto-phoenix遇到的坑)。那么假如要使用phoenix,我就需要放弃很多东西,数据的导入不能用sqoop导入,而要手写map/reduce;数据的查询修改都要使用phoenix,不然无法正确识别。从mysql向HBase+Phoenix迁移数据的心得总结 中写了一些解决方案,但是我看不懂,对我来说太难了,而且太麻烦了。与其继续坚持下去,不如换个合适的中间件来满足需求。

我同事用了antdb(antdb官网),我大概看了它的使用过程,和phoenix感觉差不多,创建一个虚拟的mysql来映射hbase表,让用户可以像修改mysql一样修改hbase数据。但是不能设置主键,一些像phoenix的特性不知道有没有,并且在我使用过程中RegionServer直接被停了,不知道什么原因。感觉太不成熟,也没有什么教程贴来教教我如何用,还是当做备用方案,先去看看simplehbase如何使用吧。

看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注行业资讯频道,感谢您对的支持。

数据 问题 配置 时候 空间 教程 查询 帖子 字段 引号 是在 还是 会报 差不多 信息 内容 感觉 类型 面的 方案 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 北京做EHS软件开发 软件开发与技术专业前景如何 崇明区智能化软件开发售后保障 软件开发复试需要带作品吗 数据库的安全访问控制 罗布勒斯国服进不去服务器怎么办 泰拉瑞亚有啥服务器 本地服务器数据库无法同步电脑端 网络安全敌对情报机构 福州九九优网络技术 设备软件开发工程师有前景吗 学校网络安全与隐私保护 数据库高手是什么原因 读软件开发职高学校能学到技术吗 用友数据库表名 全军出击服务器无法连接 浪潮服务器存储技术研究中心 网络安全的措施论文 香港代理服务器ip免费最新 数据库建模定义为标识列 软件开发支援系统程序 hpc服务器管理软件 南宁饮品店扫码点餐机软件开发 加上网络安全人才培养 罗布勒斯国服进不去服务器怎么办 安全隐患排查对标数据库 数据库计算字段的百分比 软件开发好不好跑 数据库培训速成班多少钱 卫宁健康软件开发怎么样
0