Apache Phoenix 官方站点:https://phoenix.apache.org/
Phoenix支持的sql语句: https://phoenix.apache.org/language/index.html
Phoenix 支持的DataTypes:https://phoenix.apache.org/language/datatypes.html
Phoenix 支持的函数:https://phoenix.apache.org/language/functions.html
jar包下载地址: https://phoenix.apache.org/download.html
注:打开网址http://mirror.bit.edu.cn/apache/phoenix/,可以看到如下类似的页面。phoenix对hbase版本有严格的要求,因此在使用的时候要格外小心,如果公司的hbase升级后,使用phoenix编写的代码也需要更新jar,甚至修改代码(这个有点蛋疼,不知道会不会因为这一点导致其很难广泛被使用)
在Phoenix说明中,已明确指出,Phoenix对hbase版本有严格的要求,官方摘录如下
Current release 4.15.0 can run on Apache HBase 1.3, 1.4 and 1.5. CDH HBase 5.11, 5.12, 5.13 and 5.14 is supported by 4.14.0. Apache HBase 2.0 is supported by 5.0.0. Please follow the appropriate link depending on your HBase version.
目前最新的版本支持如下:
Phoenix版本 | hbase版本 |
---|---|
5.0.0-HBase-2.0 | 2.0 |
4.15.0-HBase-1.5 | 1.3/1.4/1.5 |
4.15.0-HBase-1.4 | 1.4 |
注:以上只是最新的版本,其他版本可以查看如下链接
依赖包加载不下来的问题,可添加aliyun的国内镜像,在阿里云仓库里可以找到,phoenix-core包存在jcenter里面
阿里云仓库地址:https://maven.aliyun.com/mvn/search
repositories {
maven {
url 'http://maven.aliyun.com/nexus/content/groups/public/'
}
maven {
url 'http://maven.aliyun.com/nexus/content/repositories/jcenter'
}
}
添加依赖如下:
dependencies {
compile 'org.springframework.boot:spring-boot-starter-web'
compile('org.springframework.boot:spring-boot-starter-jdbc')
compile('mysql:mysql-connector-java:6.0.6')
compile('org.mybatis.spring.boot:mybatis-spring-boot-starter:1.3.2')
compile('org.apache.hadoop:hadoop-common:2.9.2')
compile('org.apache.phoenix:phoenix-core:5.0.0-HBase-2.0')
compile group: 'dom4j', name: 'dom4j', version: '1.6.1'
compile('javax.servlet:javax.servlet-api:4.0.1')
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
}
在配置数据库连接的时候,phoenix官方文档有明确说明,没有必要设置连接池。因为其基于HBase的连接的创建成本很低,并且用过的HBase连接不能共享使用,因此用过的Connection需要关闭。
Phoenix’s Connection objects are different from most other JDBC Connections due to the underlying HBase connection. The Phoenix Connection object is designed to be a thin object that is inexpensive to create. If Phoenix Connections are reused, it is possible that the underlying HBase connection is not always left in a healthy state by the previous user. It is better to create new Phoenix Connections to ensure that you avoid any potential issues.
application.yml 配置地址如下
spring:
datasource:
url: jdbc:phoenix:127.0.0.1:2181
driver-class-name: org.apache.phoenix.jdbc.PhoenixDriver
mybatis:
mapper-locations: classpath*:/mapper/**/*.xml
configuration:
map-underscore-to-camel-case: true #开启驼峰命名
在phoenix连接服务器时,本地和服务端均需要做相关的配置。需要提前下载
服务器环境
JDK1.8
Hbase2.0.0
这里服务器已经安装好hbase-2.0.0
下载apache-phoenix-5.0.0-HBase-2.0-bin.tar.gz
下载地址:
http://archive.apache.org/dist/phoenix/apache-phoenix-5.0.0-HBase-2.0/bin/apache-phoenix-5.0.0-HBase-2.0-bin.tar.gz
将下载好的apache-phoenix-5.0.0-HBase-2.0-bin.tar.gz上传到服务器后解压
把hbase-2.0.0已经配置好的hbase-site.xml复制到apache-phoenix-5.0.0-HBase-2.0-bin/bin/hbase-site.xml
进入Phoenix 控制台:
./apache-phoenix-5.0.0-HBase-2.0-bin/bin/sqlline.py 127.0.0.1
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-86TEKFr3-1594201709798)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1584696661653.png)]
出现上图:说明已经连接成功了
1、配置hosts文件
windows打开C:\Windows\System32\drivers\etc\hosts,添加集群的hosts信息,添加集群的hosts信息
127.0.0.1 activate.navicat.com
... manager
... node1
... node2
..*. node32、下载hadoop,解压到本地,配置到环境变量即可
下载地址:http://archive.apache.org/dist/hadoop/core/hadoop-3.0.0
接着下载hadoop.dll、winutils.exe这两个文件,根据下载地址中对应的版本下载
下载地址:https://github.com/steveloughran/winutils
(1):将hadoop.dll、winutils.exe文件复制到你解压的 hadoop-2.9.0.tar 的bin目录下
(2):将hadoop.dll复制到C:\Window\System32下(这一步最重要,找了很多文章,都没说这个,然后就还是一直不成功)(3):添加环境变量HADOOP_HOME,指向hadoop目录
(4):将%HADOOP_HOME%\bin加入到path里面
(5):重启 IDE(我的没重启就出问题了)
(6). 再次运行你的程序就不会在看到这个异常。
按照如上配置,即可连接成功了.源码参照文档中的code文件夹
CREATE TABLE IF NOT EXISTS us_population ( state CHAR(2) NOT NULL, city VARCHAR NOT NULL, population BIGINT CONSTRAINT my_pk PRIMARY KEY (state, city) );
DROP TABLE us_population;
SELECT * FROM us_population WHERE state = 'NA' AND population > 10000 ORDER BY population DESC;
*****在进行查询时,支持ORDER BY、GROUP BY、LIMIT、JOIN等操作,同时Phoenix提供了一系列的函数,其中包括COUNT()、MAX()、MIN()、SUM()等,具体的函数列表可以查看:http://phoenix.apache.org/language/functions.html
*****不管条件中的列是否是联合主键中的,Phoenix一样可以支持。
DELETE FROM us_population WHERE state = 'NA';
UPSERT INTO us_population VALUES('CA','GZ',850000);
UPSERT INTO us_population(state,city) VALUES('CA','GZ');
*****如果主键的值重复,那么进行更新操作,否则插入一条新的记录(在进行更新时,没有更新的列保持原值,在进行插入时,没有插入的列为null)
*****在使用UPSERT时,主键的列不能为空(包括联合主键)
1、需要将原有 HBase 中的表做映射才能后使用 Phoenix 操作。
2、Phoenix 区分大小写,切默认情况下会将小写转成大写,所以表名、列簇、列名需要用双引号。
3、Phoenix 4.10 版本之后,在创建表映射时需要将 COLUMN_ENCODED_BYTES 置为 0。
4、删除映射表,会同时删除原有 HBase 表。所以如果只做查询炒作,建议做视图映射。
只要直接通过HBase客户端创建的表,若想用Phoenix来进行操作,那么必须要进行表的映射,因为SYSTEM.CATALOG表中并没有维护Phoenix创建表的元数据。
phoenix是支持数据类型的,hbase存储的是二进制数据。对于int,string等不同类型,二进制转换规则是不一样的,一定意义上也可以说hbase每列可以接收各类型的数据,如果要想做到各数据类型支持,首先在创建表的时候就要做到类型规范。所以在映射hbase表前,首先要确定指定表中的各列数据存储的是什么类型,这是必要的规范。
所以下面几步是必须的:
先有建表的字段规范,再有表,然后存值的时候按照数据类型来存,按照各列类型规范来进行phoenix的表的映射,取的时候就不会出现问题了。
下面从源码中扣出的bytes转换规则样例,都是二进制转换,但是类型不同,规则不同。所以呢,hbase如果存入的是string类型,phoenix却用integer接收,这个过程还会有一个二进制toObject的操作,那你将会看到一个莫名其妙的数字。
org.apache.hadoop.hbase.util.Bytes中的Bytes.toBytes(value)方法;
int类型的转换
public static byte[] toBytes(int val) {
byte [] b = new byte[4];
for(int i = 3; i > 0; i--) {
b[i] = (byte) val;
val >>>= 8;
}
b[0] = (byte) val;
return b;
}
string类型的转换
public static byte[] toBytes(String s) {
try {
return s.getBytes(UTF8_CSN);
} catch (UnsupportedEncodingException e) {
// should never happen!
throw new IllegalArgumentException("UTF8 decoding is not supported", e);
}
}
CREATE TABLE IF NOT EXISTS 表名(
列名 类型 主键,
列簇.列名,
列簇.列名
)
*****HBase中的RowKey映射Phoenix的主键,HBase中的Column映射Phoenix的列,且使用列簇名.列名进行映射。
*****相当于在SYSTEM.CATALOG表中录入相关的元数据,使Phoenix能够进行操作它。
CREATE VIEW 视图名(
列名 类型 主键,
列簇.列名,
列簇.列名
)
*****Phoenix中的视图只能进行查询,不能进行添加、更新、删除操作。
1、hbase插入的值是什么类型,读取时就应该转为什么类型。如:hbase插入是string,phoenix不能用int类型去读取。
2、对于不同的数据类型,hbase中的Bytes.to(value)方法,给入的数据类型的不同,转换规则也不同。在读取时就要用给入的数据类型去接收。
解决方案:
方案一:提前做hbase表的规范设计,某个列簇某个字段存什么数字类型的值,存值的时候严格按这个规范导入数据。然后再做phoenix表的映射建表。后期增加类型 的话可做相应扩展
方案二:数据来源复杂,hbase设计表时某列不能确定具体类型的话,就更要规范了,确保各个途径进入hbase的该列的数据类型一致,或者统一用string,然后在phoenix也用varchar接收,需要类型转换时再做转换。不统一的话就扯了。
Can not resolve node3, please check your network
java.net.UnknownHostException: node3
解决办法:windows打开C:\Windows\System32\drivers\etc\hosts,添加集群的hosts信息
127.0.0.1 activate.navicat.com
39.100.153.59 manager
39.98.144.222 node1
39.98.148.29 node2
39.101.222.209 node3
https://blog.csdn.net/fangchao2011/article/details/103477782?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task
表名区分大小写,如果小写的时候需要给字段名或表名添加双引号
插入值如果是字符串要用单引号引起来,切记不能用双引号
Error: ERROR 204 (22008): Values in UPSERT must evaluate to a constant.
表名如果要体现小写效果,必须要用双引号
存储中文用varchar
因为phoenix的char类型只支持ascii字符,不支持中文等多字节字符,如果存储中文时用varchar
Illegal data. CHAR types may only contain single byte characters (张三)
boolean类型
存储boolean值时需要用boolean类型,存储的值为TRUE/FALSE.
Error: ERROR 203 (22005): Type mismatch. BOOLEAN and TINYINT for expression: true in column 0.read
存储 1时会报如下错
Error: ERROR 203 (22005): Type mismatch. INTEGER cannot be coerced to BOOLEAN
date类型
- java phoenix插入和查询不存在时区问题
- phoenix工具插入时出现时区问题,可在sql语句中对时区进行处理
日期类型保存为UTC时间,在shell/squirrel查询的时候要用CONVERT_TZ做转换,CONVERT_TZ(col, ‘UTC’, ‘Asia/Shanghai’),但有个bug,如果col字段是timestamp的话,会报Type mismatch. expected: [DATE]。实在需要转换的话先转成Date类型:CONVERT_TZ(TO_DATE(TO_CHAR(col,‘yyyy-MM-dd HH:mm:ss’),‘yyyy-MM-dd HH:mm:ss’),‘UTC’,‘Asia/Shanghai’)
UPSERT INTO table(id, col1) SELECT id, 'val1' FROM table WHERE col2 = val2
java.util.Date cannot be cast to org.apache.phoenix.schema.types.PhoenixArray
Phoenix’s Connection objects are different from most other JDBC Connections due to the underlying HBase connection. The Phoenix Connection object is designed to be a thin object that is inexpensive to create. If Phoenix Connections are reused, it is possible that the underlying HBase connection is not always left in a healthy state by the previous user. It is better to create new Phoenix Connections to ensure that you avoid any potential issues.
4.1 使用hbase shell看不到数据?
Hbase中的数据类型都是Byte类型,显示都是二进制的形式,如果想在hbase中能看到数据,那么可以在导入数据到hbase中时设置为String类型,这样在hbase中就可以看见数据
4.2 为什么hbase可以看到数据,phoenix查到的数据是异常
由于phoenix本质上在HBase读写数据,所以HBase集群的性能影响是最大的,一般使用多节点(一般hadoop集群节点要大于等于5个)、SSD、更大的内存与缓存和对phoenix/hbase/hadoop配置参数进行调优能获得更大性能的提升。下面列举一些针对phoenix的优化措施: