博客已转移,请借一步说话,http://www.daniubiji.cn/archives/111html
HBase,一个NoSQL数据库,可存储大量非关系型数据。java
HBase,能够用HBase shell进行操做,也能够用HBase Java api进行操做。HBase虽然是一个数据库,可是它的查询语句,很不太好用。要是能像使用Mysql等关系型数据库同样用sql语句操做HBase,那就很Perfect了。node
现有工具备不少Hive,Tez,Impala,Shark/Spark,Phoenix等。今天主要记录Phoenix。mysql
phoenix,由saleforce.com开源的一个项目,后又捐给了Apache。它至关于一个Java中间件,帮助开发者,像使用jdbc访问关系型数据库一些,访问NoSql数据库HBase。linux
phoenix,操做的表及数据,存储在hbase上。phoenix只是须要和Hbase进行表关联起来。而后再用工具进行一些读或写操做。sql
其实,能够把Phoenix只当作一种代替HBase的语法的一个工具。虽然能够用java能够用jdbc来链接phoenix,而后操做HBase,可是在生产环境中,不能够用在OLTP中。在线事务处理的环境中,须要低延迟,而Phoenix在查询HBase时,虽然作了一些优化,但延迟仍是不小。因此依然是用在OLAT中,再将结果返回存储下来。shell
Phoenix官网上,对Phoenix讲解已经很屌了。若是英语好,能够看官网,更正式一些。数据库
phoenix与HBase版本对应关系apache
Phoenix 2.x - HBase 0.94.xapi
Phoenix 3.x - HBase 0.94.x
Phoenix 4.x - HBase 0.98.1+
我目前测试使用版本概况:
Hadoop1.0.4
HBase0.94.18
因此我能够用phoenix2.x,phoenix3.x。
官网download页面有
我选用的是phoenix3.1.0版本。
tar –zxvf phoenix.tar.gz
pwd
/root/phoenix
ll phoenix
phoenix目录结构可能会有点不一样,主要是bin目录的位置,可能在hadoop1下,也可能直接在 /root/phoenix下。不要紧,都差很少。
既然用的hadoop1.x集群,那么咱们使用phoenix目录下,hadoop1目录下的内容。
①将hadoop1下,phoenix-core-3.x.jar拷贝到hadoop集群各个节点HBase的lib目录下。
②重启一下HBase
在主节点上,切换到/root/phoenix/hadoop1/bin目录下
输入 ./sqlline.py master:2181
若是出现这个画面,那就是成功了。若是不成功,多是zookeeper配置的有一些问题吧。
好吧,先退出此界面,输入!quit回车而后就能够退出了。
这个phoenix挺有意思,有一些命令须要输入叹号的!
mysql的话,能够CLI命令行的方式操做;能够经过用jdbc,在Java代码中访问;能够经过用SQLyog进行访问管理;
phoenix,怎么用呢?~能够当作是mysql。Phoenix能够在CLI下操做;能够用jdbc操做;能够用phoenix的一个客户端工具Squirrel 访问;
先说Squirrel吧,这个简单一些。
Squirrel SQL Client,是一个链接数据库的客户端工具。通常支持JDBC的数据库均可以用它来链接。(如Squirrel链接Mysql)
下载Squirrel SQL Client,解压缩就能够了。运行squirrel-sql.bat就出现了图形界面。
①在Squirrel安装目录的lib下,添加几个jar包
a,phoenix-core-xxx.jar
b,phoenix-3.0-client.jar
c,hbase-0.94.18.jar
d,hadoop1.0.4.jar
e,hadoop-common-xxx.jar
②
须要点击“Drivers”,将phoenix的驱动添加进去。
③点击左上角 蓝色的 “ + ” 加号,添加
按上面的顺序,依次填写。第一步Name:随便写个名字,标记链接;第二步Example URL:至关于mysql的jdbc链接串,这里的alias写zookeeper的主机名称,端口号,能够写,能够不写,我通常不写;第三步选择Phoenix-core的jar包;第四步就是手动输入org.apache.phoenix.jdbc.PhoenixDriver。
而后点击OK。
④配置链接
Name:为随便起的名称。
Driver:选中③中添加的phoenix驱动。
URL:写如上内容,jdbc:phoenix:node1,node2,master等这里主要是zookeeper主机名。
User Name:要链接的主机的用户名
Password:要链接的主机的密码
点击Test能够进行测试,或点OK链接。
链接完毕,启动后,就能够看到以下的效果了。这里我已经建立了几个表了,这些表都是存在于HBase上的。
1,用squirrel创建的一些链接
2,当前链接下,全部对象,包括主见系统表,普通表,视图。
3,为表,这些表都是实际存在于zookeeper所管理的HBase上的。右键此表,能够对表进行管理。
4,为视图。
5,编写sql脚本的地方,能够输入脚本执行。脚本执行方式,在5上面有一个小人,选中sql,点击小人就能够执行了。或者按ctrl + enter键,执行。
6,为选中的对象的一些基本信息,列信息,行数等。
7,为sql执行的一些状态。
下面在Squirrel中建立一个表
在Squirrel中建立表的过程主要是编写sql,进行执行。sql该怎么写,须要看phoenix驱动都支持什么效果。
这须要看phoenix的官网了。
须要注意的是phoenix是区分大小写的,本身定义的HBase中的 HTableName,ColumnFamily,以及字段Column,须要和Phoenix中保持一致。
phoenix操做hbase,咱们有两种方式,建立表,建立视图。
这两种方式,有区别。
好比,建立表的话,就能够对HBase进行插入,查询,删除操做。视图的话,通常就只能够进行查询操做
虽然看起来,表的功能,比视图更强大一些。可是就像是mysql等关系型数据库同样,删除表操做,会将表删掉。可是删除视图操做,却不会影响原始表的结构。
由于使用phoenix,建立表后,会自动和hbase创建关联映射。当你使用phoenix删除和hbase之间的关系时,就会将hbase中的表也删掉了
因此用视图,会对原始的HBase表影响小一些。
phoenix能够建立表,
若hbase中,不存在HTable:
create htablename (
pk VARCHAR primary key not null,
col1 VARCHAR null,
col2 VARCHAR null,
col3 VARCHAR null
)
create htablename2(
pk VARCHAR primary key null,
"cf"."col1" VARCHAR null,
"cf"."col2" VARCHAR null,
"cf2"."col3" VARCHAR null,
"cf2"."col4" VARCHAR null,
)
上面的SQL脚本,能够在SQuirreL中进行执行,执行过程当中,若是出现错误,会在工具的下面进行提示。若成功后,就能够在HBase中看到这个表了。
若Hbase中,已存在名为htablename3的HTable,那么SQuirrel是不会直接显示出hbase中这个已存在的表的,咱们还须要额外作一些操做。
在SQuirreL中进行执行,执行完毕后,就会将HBase的htablename3,映射到SQuirreL中。这样咱们就能够在Java api中进行操做了。不然是不能够的。
那么须要哪些具体操做呢?其实很简单,我当时没想到
就像建立表同样,使用Create table就能够了。就这样简单。
不过这个语句怎么写呢?怎样对应呢?
create htablename3(
pk VARCHAR primary key null, -------这句话直接写就能够了,这样的话,HBase中的RowKey转换成phoenix中的主键,列名就叫 pk。rowkey自动会和primary key进行对应。
"cf"."col1" VARCHAR null, -------将名为cf的columnFamily下,字段名为col1的字段,写在这里。
"cf"."col2" VARCHAR null, -------将名为cf的columnFamily下,字段名为col2的字段,写在这里。。。下面就以此类推
"cf2"."col3" VARCHAR null,
"cf2"."col4" VARCHAR null,
)
而后在SQuirreL中执行,而后就能够看到数据了。
不过此时,可能还会有问题,乱码。 在SQuirrel中,主键以及一些包含汉字的字段,都是方块等乱码了。这个怎么解决???
建立试图
CREATE VIEW "heihei"
(pk VARCHAR primary key)
default_column_family = 'FM'
建立完成后,这里的“heihei” 是HBase中table的名称。而后定义一个主键,就能够了。
建立视图
①CREATE VIEW "DAMAI" ( PK VARCHAR PRIMARY KEY) DEFAULT_COLUMN_FAMILY='FM'
这里双引号内的 “DAMAI” 和HBase中的表名是同样的,因此会自动关联。
那么,若是想针对HBase中的一个表,建多个视图呢?
②第二种视图,能够在Phoenix table的基础上建立。
CREATE VIEW my_VIEW (new_col VARCHAR,new_col2 VARCHAR) AS SELECT * FROM phoenix_Table WHERE ......
③第三种视图,是创建在视图之上,
CREATE VIEW my_VIEW_ON_VIEW AS SELECT * FROM MY_VIEW WHERE ......
因此说,在建立DAMAI视图的时候,能够将所有字段都包括进来。而后再在此视图基础上,建立其它视图。
随着数据的增加,视图中能够看到的数据的条数,也在同步增长。
使用命令查看一下视图中的数据
select * from damai 这时能够用大小写都行了。没有区分
查询结果如今,只有一列。看来是建立视图时,没有关联好其余列。不要紧,删掉,重建。
Phoenix中的语法
Phoenix中的数据类型
Phoenix中的方法
我本身使用过程当中一些简单语句,以下:
select * from shuju;
select count(1) from shuju;
select cmtid,count(1) as num from shuju group by cmtid order by num desc;
select avg(TO_NUMBER(avgt)) from shuju;
select cmtid,count(1) as num,avg(TO_NUMBER(avgt)) as avgt,avg(TO_NUMBER(loss)) as loss from shuju group by cmtid order by num desc;
select acm,dtype,cmtid,count(1) as num,avg(TO_NUMBER(avgt)) as avgt,avg(TO_NUMBER(loss)) as loss
from shuju
group by acm,dtype,cmtid
order by num desc;
select acm,dtype,porgcode,orgid,cmtid,count(1) as num,avg(TO_NUMBER(avgt)) as avgt,avg(TO_NUMBER(loss)) as loss
from shuju
group by acm,dtype,porgcode,orgid,cmtid
order by num desc;
where TO_DATE(ttime,'yyyyMMddHHmmss')=TO_DATE('20141125','yyyyMMdd')
select ttime from shuju order by ttime desc;
where TO_DATE(ttime,'yyyyMMddHHmmss')=TO_DATE('20141125','yyyyMMdd')
select TO_DATE(ttime,'yyyyMMddHHmmss') from shuju;
select TO_DATE('20141125','yyyyMMdd') from shuju;
select (TO_DATE(ttime,'yyyyMMddHHmmss')=TO_DATE('20141125','yyyyMMdd')) as aaa from shuju order by aaa asc;
用SHELL来操做phoenix,不太好用。无助的时候,你能够喊救命!So,Say Help Help Help
./sqlline.py master:2181
进入shell后,输入help
能够看到不少命令,前面都带了一个叹号。根据意思本身猜一猜功能,而后试一试效果,就能够了。不记录了。
这个过程就想是JDBC同样使用就能够了。
①先将phoenix的 core.jar包 和 phoenix的client.jar 包放到lib里。
②建立链接,过程和mysql相似
public Connection GetConnection(){
Connection cc = null;
String driver = "org.apache.phoenix.jdbc.PhoenixDriver";
//String url = "jdbc:phoenix:192.168.206.21:2181";
try {
Class.forName(driver);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
if (cc == null) {
try {
cc = DriverManager.getConnection(url);
} catch (SQLException e) {
e.printStackTrace();
}
}
return cc;
}
OK 搞定了。