千家信息网

二、hbase--集成Phoenix实现类SQL操作hbase

发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,一、Phoenix概述1、简介可以把Phoenix理解为Hbase的查询引擎,phoenix,由saleforce.com开源的一个项目,后又捐给了Apache。它相当于一个Java中间件,帮助开发者
千家信息网最后更新 2026年11月01日二、hbase--集成Phoenix实现类SQL操作hbase

一、Phoenix概述

1、简介
可以把Phoenix理解为Hbase的查询引擎,phoenix,由saleforce.com开源的一个项目,后又捐给了Apache。它相当于一个Java中间件,帮助开发者,像使用jdbc访问关系型数据库一些,访问NoSql数据库HBase。

phoenix,操作的表及数据,存储在hbase上。phoenix只是需要和Hbase进行表关联起来。然后再用工具进行一些读或写操作。

其实,可以把Phoenix只看成一种代替HBase的语法的一个工具。虽然可以用java可以用jdbc来连接phoenix,然后操作HBase,但是在生产环境中,不可以用在OLTP中。在线事务处理的环境中,需要低延迟,而Phoenix在查询HBase时,虽然做了一些优化,但延迟还是不小。所以依然是用在OLAT中,再将结果返回存储下来。

二、部署

基础环境:
hadoop
hbase
zookeeper
这个基础环境就是前面hbase的部署之后的环境,请自行按照前面的进行部署,这里不重复部署
下面我们通过Phoenix作为中间件,操作hbase集群数据。根据hbase的版本下载对应版本的Phoenix,这里用的是 apache-phoenix-4.14.2-HBase-1.3-bin.tar.gz。并且是部署在bigdata121这台主机上
解压程序包:

tar zxf  apache-phoenix-4.14.2-HBase-1.3-bin.tar.gz -C /opt/modules/mv /opt/modules/apache-phoenix-4.14.2-HBase-1.3-bin /opt/modules/phoenix-4.14.2-HBase-1.3-bin

配置环境变量:

vim /etc/profile.d/phoenix.sh#!/bin/bashexport PHOENIX_HOME=/opt/modules/phoenix-4.14.2-HBase-1.3export PATH=$PATH:${PHOENIX_HOME}/binsource /etc/profile.d/phoenix.sh

复制hbase的 conf/hbase-site.xml 到/opt/modules/phoenix-4.14.2-HBase-1.3-bin/bin下。

cp ${HBASE_HOME}/conf/hbase-site.xml /opt/modules/phoenix-4.14.2-HBase-1.3-bin/bin

接着将Phoenix访问hbase 的一些依赖包拷贝到hbase 的lib目录下,注意:需要复制到所有hbase节点上

cd /opt/modules/phoenix-4.14.2-HBase-1.3-bincp phoenix-4.10.0-HBase-1.2-server.jar phoenix-core-4.10.0-HBase-1.2.jar ${HBASE_HOME}/lib/复制到另外两台hbase节点上scp phoenix-4.10.0-HBase-1.2-server.jar phoenix-core-4.10.0-HBase-1.2.jar bigdata122:${HBASE_HOME}/lib/scp phoenix-4.10.0-HBase-1.2-server.jar phoenix-core-4.10.0-HBase-1.2.jar bigdata122:${HBASE_HOME}/lib/

启动Phoenix命令行,测试是否能连接hbase

sqlline.py zkserver地址如:sqlline.py bigdata121,bigdata122,bigdata123:2181

要注意的是:Phoenix其实就是一个hbase的插件库,并不是独立的一个组件,hbase有了这个插件之后,重启hbase,然后就可使用Phoenix来连接hbase,并操作hbase了。

三、基本使用命令

展示表有哪些

!table

创建表

create table "student"(id integer not null primary key,name varchar);表名不加引号的话,就会默认将表名全部转为大写字母,加了引号就不会。后面的命令用到表名的时候情况都类似

删除表

drop table "test"

插入数据

upsert into test values(1,'Andy');插入value的时候,字符串不要用双引号,只能用单引号,否则报错.记住这里是upsert,不是insert,别搞错了

查询数据

select * from "test"。用法基本和普通的sql的select一样

删除数据

delete from "test" where id=2

修改表结构

增加字段:alter table "student" add address varchar删除字段:alter table "student" drop column address

创建映射表

hbase创建表create 'fruit','info','accout'插入数据put 'fruit','1001','info:name','apple'put 'fruit','1001','info:color','red'put 'fruit','1001','info:price','10'put 'fruit','1001','account:sells','20'put 'fruit','1002','info:name','orange'put 'fruit','1002','info:color','orange'put 'fruit','1002','info:price','8'put 'fruit','1002','account:sells','100'Phoenix创建映射表,注意必须是同名create view "fruit"("ROW" varchar primary key,"info"."name" varchar,"info"."color" varchar,"info"."price" varchar,"account"."sells" varchar,);接着就可以在 Phoenix 中查看到hbase中的数据了

四、使用jdbc连接Phoenix

maven项目的pom.xml

    org.apache.phoenix    phoenix-core    4.14.2-HBase-1.3

代码:

package PhoenixTest;import org.apache.phoenix.jdbc.PhoenixDriver;import java.sql.*;public class PhoenixConnTest {    public static void main(String[] args) throws ClassNotFoundException, SQLException {        //加载phoenix的jdbc驱动类        Class.forName("org.apache.phoenix.jdbc.PhoenixDriver");        //构建连接字符串        String url = "jdbc:phoenix:bigdata121,bigdata122,bigdata123:2181";        //创建连接        Connection connection = DriverManager.getConnection(url);        //创建会话        Statement statement = connection.createStatement();        //执行sql语句,注意,因为表名需要双引号,所以记得加上 \ 用于转义        boolean execute = statement.execute("select * from \"fruit\"");        if (execute) {            //获取返回的执行结果,并打印            ResultSet resultSet = statement.getResultSet();            while (resultSet.next()) {                System.out.println(resultSet.getString("name"));            }        }        statement.close();        connection.close();    }}

用jdbc连接Phoenix,出现的问题

Exception in thread "main" com.google.common.util.concurrent.ExecutionError: java.lang.NoSuchMethodError: com.lmax.disruptor.dsl.Disruptor.(Lcom/lmax/disruptor/EventFactory;ILjava/util/concurrent/ThreadFactory;Lcom/lmax/disruptor/dsl/ProducerType;Lcom/lmax/disruptor/WaitStrategy;)V    at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2254)    at com.google.common.cache.LocalCache.get(LocalCache.java:3985)    at com.google.common.cache.LocalCache$LocalManualCache.get(LocalCache.java:4788)    at org.apache.phoenix.jdbc.PhoenixDriver.getConnectionQueryServices(PhoenixDriver.java:241)    at org.apache.phoenix.jdbc.PhoenixEmbeddedDriver.createConnection(PhoenixEmbeddedDriver.java:147)    at org.apache.phoenix.jdbc.PhoenixDriver.connect(PhoenixDriver.java:221)    at java.sql.DriverManager.getConnection(DriverManager.java:664)    at java.sql.DriverManager.getConnection(DriverManager.java:270)    at PhoenixTest.PhoenixConnTest.main(PhoenixConnTest.java:11)Caused by: java.lang.NoSuchMethodError: com.lmax.disruptor.dsl.Disruptor.(Lcom/lmax/disruptor/EventFactory;ILjava/util/concurrent/ThreadFactory;Lcom/lmax/disruptor/dsl/ProducerType;Lcom/lmax/disruptor/WaitStrategy;)V    at org.apache.phoenix.log.QueryLoggerDisruptor.(QueryLoggerDisruptor.java:72)    at org.apache.phoenix.query.ConnectionQueryServicesImpl.(ConnectionQueryServicesImpl.java:414)    at org.apache.phoenix.jdbc.PhoenixDriver$3.call(PhoenixDriver.java:248)    at org.apache.phoenix.jdbc.PhoenixDriver$3.call(PhoenixDriver.java:241)    at com.google.common.cache.LocalCache$LocalManualCache$1.load(LocalCache.java:4791)    at com.google.common.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3584)    at com.google.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2372)    at com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2335)    at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2250)    ... 8 more

首先我们看到这一行:

java.lang.NoSuchMethodError: com.lmax.disruptor.dsl.Disruptor

显示的是com.lmax.disruptor.dsl.Disruptor这个方法不存在,于是在ideal里面找了找,是有这个方法的,然后我百度了下,这个包是hbase和Phoenix依赖的一个包。既然方法是存在的,但是却显示不存在的报错,按照经验来说,很可能是这个依赖包的版本不对,导致某些方法不兼容。所以我尝试换了下比较新的disruptor这个包的版本,去maven上找了找,挑了个3.3.7的版本(默认的是3.3.0),添加到pom.xml中

    com.lmax    disruptor    3.3.7

然后重新运行程序,奇迹出现了,正常运行了。那很明显是因为包的版本问题了。

五、Phoenix与hbase结合使用时的bug

首先hbase的列簇中的字段没有类型的概念,全都直接用二进制的方式存储,且hbase本身只能解析string类型的。而我们使用Phoenix来用常规sql创建表时,字段是有类型的。会出现以下情况的bug
1、hbase显示乱码
​ 这种情况是在Phoenix创建表的时候,字段有非string类型,比如int,double之类的。然后当从Phoenix使用insert之类的语句插入数据时,然后从Phoenix使用select语句查看数据,是正常的,没问题的。但是在hbase中使用scan查看表数据时,会发现,其他非string类型的字段,显示全是乱码。这种情况是正常的,因为前面说了hbase无法解析非string类型,显示出来是直接二进制的方式显示。这个bug我暂时无解。
​ 这种情况最好的方法就是,不从hbase查询数据,而是从Phoenix查询数据。而且在这种情况下,在hbase中,连列簇,rowkey,column都是显示奇奇怪怪的字符的。完全看不懂

2、Phoenix显示不正常(不是乱码)
​ 在hbase中实现已存在一张表(有数据),然后在Phoenix中创建一张映射表。在hbase端查看数据是正常的,但是通过Phoenix查看,发现非string类型的显示不正常,比如int,double之类的,变成一些非正常的数字。比如这样:

select * from "fruit";+-------+---------+---------+--------------+--------+|  ROW  |  name   |  color  |    price     | sells  |+-------+---------+---------+--------------+--------+| 1001  | apple   | red     | -1322241488  | null   || 1002  | orange  | orange  | -1204735952  | null   |+-------+---------+---------+--------------+--------+

原因其实很简单,因为hbase本身的表并没有存储任何数据类型的信息,但是Phoenix却强行强行解析成其他数据类型,自然不会匹配,所以显示不正常。

price和sells明明是数字类型的,但是显示出来的东西不正常。这种情况解决方案是:在Phoenix创建映射表时,字段类型全部定义为 varchar 这种string类型的。

数据 类型 字段 情况 版本 环境 引号 方法 查询 是在 存储 乱码 命令 字符 就是 时候 语句 问题 中间件 二进制 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 重生之互联网科技帝国 互联网科技行业发展 圆梦互联网科技 科技互联网公司装修 广州宏创互联网科技 甘肃拓世互联网科技有限公司 西藏七维空间互联网科技有限公司 南山科技园互联网公司有哪些 华夏恒生互联网科技013171 特约风豹互联网科技为什么扣费 为客找房互联网科技公司怎么样 小米互联网科技园入驻 四川互联网展示科技馆设计 互联网科技年终奖 2021世界互联网领先科技成果发布 互联网科技包装股 容联科技互联网电商 长沙渺峰互联网科技有限公司 互联网科技博主张洲 高科技和互联网的现代国家 互联网佳科技有限公司 互联网与未来科技 火传媒上海互联网科技 中国互联网金融科技基金 全球顶尖互联网科技公司 湖南一路畅行互联网科技 梅州GM互联网络科技有限公司 湖北辰鑫科技互联网 互联网科技收购价值 米泉互联网科技专业怎么样
0