二、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/bash
export PHOENIX_HOME=/opt/modules/phoenix-4.14.2-HBase-1.3
export PATH=$PATH:${PHOENIX_HOME}/bin

source /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-bin
cp 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

<dependency>
    <groupId>org.apache.phoenix</groupId>
    <artifactId>phoenix-core</artifactId>
    <version>4.14.2-HBase-1.3</version>
</dependency>

代码:

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.<init>(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.<init>(Lcom/lmax/disruptor/EventFactory;ILjava/util/concurrent/ThreadFactory;Lcom/lmax/disruptor/dsl/ProducerType;Lcom/lmax/disruptor/WaitStrategy;)V
    at org.apache.phoenix.log.QueryLoggerDisruptor.<init>(QueryLoggerDisruptor.java:72)
    at org.apache.phoenix.query.ConnectionQueryServicesImpl.<init>(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中

<dependency>
    <groupId>com.lmax</groupId>
    <artifactId>disruptor</artifactId>
    <version>3.3.7</version>
</dependency>

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

五、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类型的。

原文地址:https://blog.51cto.com/kinglab/2447715

时间: 2024-11-14 20:28:22

二、hbase--集成Phoenix实现类SQL操作hbase的相关文章

Phoenix实现用SQL查询HBase

文章来源:大牛笔记 HBase,一个NoSQL数据库,可存储大量非关系型数据. HBase,可以用HBase shell进行操作,也可以用HBase Java api进行操作.HBase虽然是一个数据库,但是它的查询语句,很不太好用.要是能像使用Mysql等关系型数据库一样用sql语句操作HBase,那就很Perfect了. 现有工具有很多Hive,Tez,Impala,Shark/Spark,Phoenix等.今天主要记录Phoenix. phoenix,由saleforce.com开源的一个

HBase集成Phoenix创建二级索引

一.Hbase集成Phoneix 1.下载 在官网http://www.apache.org/dyn/closer.lua/phoenix/中选择提供的镜像站点中下载与安装的HBase版本对应的版本.本地使用的1.2.5,故下载的apache-phoenix-4.11.0-HBase-1.2/的tar.gz包. 2.上传并解压 tar -zxvf apache-phoenix-4.13.1-HBase-1.2-bin.tar.gzmv apache-phoenix-4.13.1-HBase-1.

java vm (二) 之 虚拟机启动对类的操作

虚拟机在启动中对类的操作 虚拟机加载类(classloader克拉斯楼的),类进行处理以后是字节码,虚拟机认识就可以做下面的事情了.从硬盘到内存的过程 链接 对类进行验证,类的头部用两个字节保存了,这个信息,详情找个专业的文档链接放到这里. 为类分配内存,给对应的变量附言默认值 int 给他 个0  Integer 给他个null…… 将特殊的字符进行解析,应该是跟Spring 对 @autowrite 的解析类似,有自己的套路,(找个合适的例子放到这里) 初始化变量赋予正确的值 比热 priv

Phoenix(sql on hbase)简介

Phoenix(sql on hbase)简介 介绍: Phoenix is a SQL skin over HBase delivered as a client-embedded JDBC driver targeting low latency queries over HBase data. Phoenix takes your SQL query, compiles it into a series of HBase scans, and orchestrates the runnin

HBase 6、用Phoenix Java api操作HBase

开发环境准备:eclipse3.5.jdk1.7.window8.hadoop2.2.0.hbase0.98.0.2.phoenix4.3.0 1.从集群拷贝以下文件:core-site.xml.hbase-site.xml.hdfs-site.xml文件放到工程src下 2.把phoenix的phoenix-4.3.0-client.jar和phoenix-core-4.3.0.jar添加到工程classpath 3.配置集群中各节点的hosts文件,把客户端的hostname:IP添加进去

使用Phoenix通过sql语句更新操作hbase数据

hbase 提供很方便的shell脚本,可以对数据表进行 CURD 操作,但是毕竟是有一定的学习成本的,基本上对于开发来讲,sql 语句都是看家本领,那么,有没有一种方法可以把 sql 语句转换成 hbase的原生API呢? 这样就可以通过普通平常的 sql 来对hbase 进行数据的管理,使用成本大大降低.Apache Phoenix 组件就完成了这种需求,官方注解为 “Phoenix - we put the SQL back in NoSql”,通过官方说明,Phoenix 的性能很高,相

phoenix——提供hbase的sql操作的框架

phoenix——提供hbase的sql操作的框架 2014年01月06日 ⁄ hadoop及周边, hbase ⁄ 共 364字 ⁄ 字号 小 中 大 ⁄ 1条评论 ⁄ 阅读 1,522 views 次 是什么? hbase提供了海量数据的毫秒级查询.可见,hbase是个非常好的实时查询框架,缺点就是查询功能非常薄弱,仅限于通过行键查询.今天看到一个框架phoenix(直译做凤凰),非常美丽的框架,他提供了HBase的sql访问功能,可以使用标准的JDBC API操作去创建表.插入记录.查询数

Phoenix的安装使用与SQL查询HBase

一. Phoenix的简介 1. 什么是phoenix 现有hbase的查询工具有很多如:Hive,Tez,Impala,Shark/Spark,Phoenix等.今天主要说Phoenix.phoenix是一个在hbase上面实现的基于hadoop的OLTP技术,具有低延迟.事务性.可使用sql.提供jdbc接口的特点. 而且phoenix还提供了hbase二级索引的解决方案,丰富了hbase查询的多样性,继承了hbase海量数据快速随机查询的特点.但是在生产环境中,不可以用在OLTP中.在线事

C#的SQL操作类实例

本文实例讲述了C#的SQL操作类,分享给大家供大家参考.具体方法如下: 代码如下: using System; using System.Collections.Generic; using System.Text; using System.Data; using System.Data.SqlClient; using System.Windows.Forms; namespace yjgl { /// <summary> /// 数据访问基础类(SQL) /// </summary