您好,登錄后才能下訂單哦!
1、簡(jiǎn)介
可以把Phoenix理解為Hbase的查詢引擎,phoenix,由saleforce.com開源的一個(gè)項(xiàng)目,后又捐給了Apache。它相當(dāng)于一個(gè)Java中間件,幫助開發(fā)者,像使用jdbc訪問(wèn)關(guān)系型數(shù)據(jù)庫(kù)一些,訪問(wèn)NoSql數(shù)據(jù)庫(kù)HBase。
phoenix,操作的表及數(shù)據(jù),存儲(chǔ)在hbase上。phoenix只是需要和Hbase進(jìn)行表關(guān)聯(lián)起來(lái)。然后再用工具進(jìn)行一些讀或?qū)懖僮鳌?/p>
其實(shí),可以把Phoenix只看成一種代替HBase的語(yǔ)法的一個(gè)工具。雖然可以用java可以用jdbc來(lái)連接phoenix,然后操作HBase,但是在生產(chǎn)環(huán)境中,不可以用在OLTP中。在線事務(wù)處理的環(huán)境中,需要低延遲,而Phoenix在查詢HBase時(shí),雖然做了一些優(yōu)化,但延遲還是不小。所以依然是用在OLAT中,再將結(jié)果返回存儲(chǔ)下來(lái)。
基礎(chǔ)環(huán)境:
hadoop
hbase
zookeeper
這個(gè)基礎(chǔ)環(huán)境就是前面hbase的部署之后的環(huán)境,請(qǐng)自行按照前面的進(jìn)行部署,這里不重復(fù)部署
下面我們通過(guò)Phoenix作為中間件,操作hbase集群數(shù)據(jù)。根據(jù)hbase的版本下載對(duì)應(yīng)版本的Phoenix,這里用的是 apache-phoenix-4.14.2-HBase-1.3-bin.tar.gz。并且是部署在bigdata121這臺(tái)主機(jī)上
解壓程序包:
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
配置環(huán)境變量:
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
復(fù)制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訪問(wèn)hbase 的一些依賴包拷貝到hbase 的lib目錄下,注意:需要復(fù)制到所有hbase節(jié)點(diǎn)上
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/
復(fù)制到另外兩臺(tái)hbase節(jié)點(diǎn)上
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/
啟動(dòng)Phoenix命令行,測(cè)試是否能連接hbase
sqlline.py zkserver地址
如:
sqlline.py bigdata121,bigdata122,bigdata123:2181
要注意的是:Phoenix其實(shí)就是一個(gè)hbase的插件庫(kù),并不是獨(dú)立的一個(gè)組件,hbase有了這個(gè)插件之后,重啟hbase,然后就可使用Phoenix來(lái)連接hbase,并操作hbase了。
展示表有哪些
!table
創(chuàng)建表
create table "student"(
id integer not null primary key,
name varchar);
表名不加引號(hào)的話,就會(huì)默認(rèn)將表名全部轉(zhuǎn)為大寫字母,加了引號(hào)就不會(huì)。后面的命令用到表名的時(shí)候情況都類似
刪除表
drop table “test”
插入數(shù)據(jù)
upsert into test values(1,'Andy');
插入value的時(shí)候,字符串不要用雙引號(hào),只能用單引號(hào),否則報(bào)錯(cuò).記住這里是upsert,不是insert,別搞錯(cuò)了
查詢數(shù)據(jù)
select * from "test"。用法基本和普通的sql的select一樣
刪除數(shù)據(jù)
delete from "test" where id=2
修改表結(jié)構(gòu)
增加字段:alter table "student" add address varchar
刪除字段:alter table "student" drop column address
創(chuàng)建映射表
hbase創(chuàng)建表
create 'fruit','info','accout'
插入數(shù)據(jù)
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創(chuàng)建映射表,注意必須是同名
create view "fruit"(
"ROW" varchar primary key,
"info"."name" varchar,
"info"."color" varchar,
"info"."price" varchar,
"account"."sells" varchar,
);
接著就可以在 Phoenix 中查看到hbase中的數(shù)據(jù)了
maven項(xiàng)目的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驅(qū)動(dòng)類
Class.forName("org.apache.phoenix.jdbc.PhoenixDriver");
//構(gòu)建連接字符串
String url = "jdbc:phoenix:bigdata121,bigdata122,bigdata123:2181";
//創(chuàng)建連接
Connection connection = DriverManager.getConnection(url);
//創(chuàng)建會(huì)話
Statement statement = connection.createStatement();
//執(zhí)行sql語(yǔ)句,注意,因?yàn)楸砻枰p引號(hào),所以記得加上 \ 用于轉(zhuǎn)義
boolean execute = statement.execute("select * from \"fruit\"");
if (execute) {
//獲取返回的執(zhí)行結(jié)果,并打印
ResultSet resultSet = statement.getResultSet();
while (resultSet.next()) {
System.out.println(resultSet.getString("name"));
}
}
statement.close();
connection.close();
}
}
用jdbc連接Phoenix,出現(xiàn)的問(wèn)題
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這個(gè)方法不存在,于是在ideal里面找了找,是有這個(gè)方法的,然后我百度了下,這個(gè)包是hbase和Phoenix依賴的一個(gè)包。既然方法是存在的,但是卻顯示不存在的報(bào)錯(cuò),按照經(jīng)驗(yàn)來(lái)說(shuō),很可能是這個(gè)依賴包的版本不對(duì),導(dǎo)致某些方法不兼容。所以我嘗試換了下比較新的disruptor這個(gè)包的版本,去maven上找了找,挑了個(gè)3.3.7的版本(默認(rèn)的是3.3.0),添加到pom.xml中
<dependency>
<groupId>com.lmax</groupId>
<artifactId>disruptor</artifactId>
<version>3.3.7</version>
</dependency>
然后重新運(yùn)行程序,奇跡出現(xiàn)了,正常運(yùn)行了。那很明顯是因?yàn)榘陌姹締?wèn)題了。
首先hbase的列簇中的字段沒(méi)有類型的概念,全都直接用二進(jìn)制的方式存儲(chǔ),且hbase本身只能解析string類型的。而我們使用Phoenix來(lái)用常規(guī)sql創(chuàng)建表時(shí),字段是有類型的。會(huì)出現(xiàn)以下情況的bug
1、hbase顯示亂碼
? 這種情況是在Phoenix創(chuàng)建表的時(shí)候,字段有非string類型,比如int,double之類的。然后當(dāng)從Phoenix使用insert之類的語(yǔ)句插入數(shù)據(jù)時(shí),然后從Phoenix使用select語(yǔ)句查看數(shù)據(jù),是正常的,沒(méi)問(wèn)題的。但是在hbase中使用scan查看表數(shù)據(jù)時(shí),會(huì)發(fā)現(xiàn),其他非string類型的字段,顯示全是亂碼。這種情況是正常的,因?yàn)榍懊嬲f(shuō)了hbase無(wú)法解析非string類型,顯示出來(lái)是直接二進(jìn)制的方式顯示。這個(gè)bug我暫時(shí)無(wú)解。
? 這種情況最好的方法就是,不從hbase查詢數(shù)據(jù),而是從Phoenix查詢數(shù)據(jù)。而且在這種情況下,在hbase中,連列簇,rowkey,column都是顯示奇奇怪怪的字符的。完全看不懂
2、Phoenix顯示不正常(不是亂碼)
? 在hbase中實(shí)現(xiàn)已存在一張表(有數(shù)據(jù)),然后在Phoenix中創(chuàng)建一張映射表。在hbase端查看數(shù)據(jù)是正常的,但是通過(guò)Phoenix查看,發(fā)現(xiàn)非string類型的顯示不正常,比如int,double之類的,變成一些非正常的數(shù)字。比如這樣:
select * from "fruit";
+-------+---------+---------+--------------+--------+
| ROW | name | color | price | sells |
+-------+---------+---------+--------------+--------+
| 1001 | apple | red | -1322241488 | null |
| 1002 | orange | orange | -1204735952 | null |
+-------+---------+---------+--------------+--------+
原因其實(shí)很簡(jiǎn)單,因?yàn)閔base本身的表并沒(méi)有存儲(chǔ)任何數(shù)據(jù)類型的信息,但是Phoenix卻強(qiáng)行強(qiáng)行解析成其他數(shù)據(jù)類型,自然不會(huì)匹配,所以顯示不正常。
price和sells明明是數(shù)字類型的,但是顯示出來(lái)的東西不正常。這種情況解決方案是:在Phoenix創(chuàng)建映射表時(shí),字段類型全部定義為 varchar 這種string類型的。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。