第一关: Phoenix 安装
任务描述
本关任务:安装与配置Phoenix。
相关知识
学习完之前的内容,我们会发现HBase的基本理念和传统的关系数据库是截然不同的,HBase查询数据利用的是 scan() 和 get() 与过滤器配合进行查询,插入数据则使用 put() 方法,这和操作关系型数据库差别很大,在关系型数据库中,比如创建表使用create 语句,插入数据使用 insert 语句,这些是我们熟悉的,不过HBase本身并不支持SQL,那如果我们想要写HBase程序也像写SQL那样是不是没办法呢? 答案是有办法的。
为了使得熟悉SQL的程序员能够快速使用HBase ,使用Apache Phoenix 是比较好的办法。它提供了一组类似于SQL的语法,以及序列、索引、函数等工具,使得将SQL代码移植至HBase成为可能。
本关讨论Phoenix具体如何使用,以及HBase结合Phoenix的使用方法。
安装 Phoenix
Phoenix可以在官网下载,安装Phoenix的时候需要关注它的版本号,否则很有可能你安装的Phoenix并不适用于你的HBase,在这里我们选择的是 Phoenix5.0.0-HBase-2.0 版本,即Phoenix对应HBase2.0.0的版本。
具体安装步骤:在 /opt 目录下已经将 Phoenix 安装包下载好了。
第一步:将下载好的Phoenix安装包解压到指定目录(本关卡需要解压到 /app 下),将
phoenix-version-HBase-[version]-server.jar 、phoenix-core-[version]-HBase-[version].jar
复制到HBase lib目录;注意不要复制多了,否则可能导致HMaster或者HRegionServer进程无法启动:
cp phoenix-5.0.0-HBase-2.0-server.jar /app/hbase-2.1.1/lib/ cp phoenix-core-5.0.0-HBase-2.0.jar /app/hbase-2.1.1/lib/
第二步:如果你使用的是HBase集群,就需要用scp拷贝到各个 regionserver的HBase的lib目录下,并且重启HBase集群,当然如果使用的单机版或者伪分布式,只需要完成第一步,然后重启 HBase 就够了。
第三步:在Hbase集群每个服务器的hbase-site.xml配置文件中,加入:
hbase.regionserver.wal.codec org.apache.hadoop.hbase.regionserver.wal.IndexedWALEditCodec
这是在Phoenix中建立索引的必要条件。如果不添加此设置,Phoenix虽然可以正常使用,但是不能建立索引。
第四步: 测试
在Phoenix目录下使用命令
./bin/sqlline.py 127.0.0.1:2181 127.0.0.1:2181
是本机Zookeeper的服务器和端口号,上述命令如果执行报错可能是因为你系统中Python的版本问题,可以尝试在命令之前加上 python2 执行 sqlline.py 文件。
出现以下显示则说明连接成功。
Connected to: Phoenix (version 5.0) Driver: PhoenixEmbeddedDriver (version 5.0) Autocommit status: true Transaction isolation: TRANSACTION_READ_COMMITTED Building list of tables and columns for tab-completion (set fastconnect to true to skip)… 138/138 (100%) Done Done sqlline version 1.2.0 0: jdbc:phoenix:127.0.0.1:2181>
Phoenix 的简单操作
接下来试一试创建表添加数据:
创建表:
0: jdbc:phoenix:127.0.0.1:2181> create table test(id INTEGER PRIMARY KEY,name VARCHAR);
查看表:
(注意,Phoenix只能看到自己创建的表,不能看到HBase创建的表)
0: jdbc:phoenix:127.0.0.1:2181> !tables
±-----------±-------------±------------±--------------±---------±-----------±---------------------------±-+ | TABLE_CAT | TABLE_SCHEM | TABLE_NAME | TABLE_TYPE | REMARKS | TYPE_NAME | SELF_REFERENCING_COL_NAME | | ±-----------±-------------±------------±--------------±---------±-----------±---------------------------±-+ | | SYSTEM | CATALOG | SYSTEM TABLE | | | | | | | SYSTEM | FUNCTION | SYSTEM TABLE | | | | | | | SYSTEM | LOG | SYSTEM TABLE | | | | | | | SYSTEM | SEQUENCE | SYSTEM TABLE | | | | | | | SYSTEM | STATS | SYSTEM TABLE | | | | | | | | TEST | TABLE | | | | | ±-----------±-------------±------------±--------------±---------±-----------±---------------------------±-+
插入数据:
0: jdbc:phoenix:127.0.0.1:2181> upsert into TEST values(1,‘张三’);
查询数据:
0: jdbc:phoenix:127.0.0.1:2181> SELECT * FROM TEST;
±----±------+ | ID | NAME | ±----±------+ | 1 | 张三 | ±----±------+
1 row selected (0.055 seconds)
编程要求
请仔细阅读右侧代码,根据方法内的提示,在Begin - End区域内进行代码补充,具体任务如下:
Phoenix 的安装包已经存放在/opt 目录,需要你在 /app 目录下安装 Phoenix ;
在 Phoenix 中创建表 USER;
向USER表中添加数据;
表结构与数据如下:
结构:
字段 类型 属性
ID INTEGER 主键
NAME VARCHAR 无
AGE VARCHAR 无
数据:
ID NAME AGE 1101 zhangsan 21 1102 lisi 22 1103 wangwu 29
测试说明
补充完代码后,点击测评,平台会对你编写的代码进行测试,当你的结果与预期输出一致时,即为通过。
预期输出:
ID NAME AGE
1101 zhangsan 21 1102 lisi 22 1103 wangwu 29
————本题参考答案
cd /opt tar -zxvf apache-phoenix-5.0.0-HBase-2.0-bin.tar.gz -C /app cd /app/apache-phoenix-5.0.0-HBase-2.0-bin/ cp phoenix-5.0.0-HBase-2.0-server.jar /app/hbase-2.1.1/lib/ cp phoenix-core-5.0.0-HBase-2.0.jar /app/hbase-2.1.1/lib/ start-hbase.sh cd /app/hbase-2.1.1/conf vi hbase-site.xml <property> <name>hbase.regionserver.wal.codec</name> <value>org.apache.hadoop.hbase.regionserver.wal.IndexedWALEditCodec</value> </property> cd /app/apache-phoenix-5.0.0-HBase-2.0-bin/bin ./sqlline.py 127.0.0.1:2181 create table user(id INTEGER PRIMARY KEY,name VARCHAR,AGE VARCHAR); upsert into USER values(1101,'zhangsan','21'); upsert into USER values(1102,'lisi','22'); upsert into USER values(1103,'wangwu','29'); SELECT * FROM USER; // 查看自己的表
第2关:Phoenix 基础语法
任务描述
本关任务:使用 Phoenix 语法创建表,添加数据,创建序列。
相关知识
创建表
CREATE TABLE IF NOT EXISTS MYTABLE (ID INTEGER PRIMARY KEY, NAME VARCHAR, SEX VARCHAR);
注意:Phoenix 创建表必须指定主键,主键是后续很多操作的必要因素。
删除表
DROP TABLE TABLENAME;
添加数据
UPSERT INTO MYTABLE VALUES (1, ‘张三’, ‘男’);
修改数据
UPSERT INTO MYTABLE VALUES (1, ‘李四’, ‘FEMALE’);
第一眼,你可能会觉得我写错了,在 Phoenix 中修改和添加使用的是同样的语句,在这个例子中若主键 1 不存在,则插入数据,若主键 1 存在则表示更新数据。这也是 Phoenix 表必须设置主键的原因。
删除数据
DELETE FROM MYTABLE WHERE ID = 1;
查询数据
SELECT * FROM MYTABLE WHERE ID=1;
分页查询
SELECT * FROM MYTABLE LIMIT 10; SELECT * FROM MYTABLE LIMIT 10 OFFSET 5;
进行到这里,可以发现 Phoenix 的 SQL 语句基本和我们学习的 MySQL 或 O\fracle 很像。
创建序列
Phoenix的序列与O\fracle很像,也是先创建,然后调用 next 得到下一个值。也可以继续调用 current value 得到当前序列值,没有调用 next 时,不能使用 current value。
例如创建一个自增的序列:
CREATE SEQUENCE IF NOT EXISTS MY_SEQ START WITH 1000 – 从1000开始 INCREMENT BY 1 – 每次累加几个 MINVALUE 1000 – 最小值1000 MAXVALUE 10000000 --最大值 CYCLE CACHE 10; --设置缓存
使用序列
首先创建一张测试表:
CREATE TABLE MYTABLE(ID INTEGER PRIMARY KEY,info.name VARCHAR);
序列只能在Select或者Upsert语句中使用,例如在Upsert中使用:
CREATE TABLE MYTABLE(ID INTEGER PRIMARY KEY,info.name VARCHAR);
添加成功可以查看表中的值;
0: jdbc:phoenix:127.0.0.1:2181> SELECT * FROM MYTABLE;
±------±----------+ | ID | NAME | ±------±----------+ | 1000 | zhangsan | ±------±----------+
删除序列
DROP SEQUENCE IF EXISTS MY_SEQ;
编程要求
创建表 table_step2,表结构为;
字段 类型 属性
ID INTEGER 主键
INFO VARCHAR 无
手动添加一条数据:ID为 1 ,INFO 为 educoder;
创建序列 seq_step2,规则为:
从2000开始;
每次累加1个;
最小值2000;
最大值为100000;
设置缓存为 10。
使用创建的序列为表添加两条数据;
做完上述步骤表中数据如下:
ID INFO 1 educoder 2000 edu 2001 coder
测试说明
测试脚本会调用你的序列添加一条数据,然后查询 table_step2表。
预期输出:
±------±----------+ | ID | INFO | ±------±----------+ | 1 | educoder | | 2000 | edu | | 2001 | coder | | 2010 | test | ±------±----------+
————本题参考答案
cd /app/apache-phoenix-5.0.0-HBase-2.0-bin/bin ./sqlline.py 127.0.0.1:2181 create table table_step2(ID INTEGER PRIMARY KEY,INFO VARCHAR); create sequence if not exists seq_step2 START WITH 2000 INCREMENT BY 1 MINVALUE 2000 MAXVALUE 100000 CYCLE CACHE 10; upsert into table_step2 values(1,'educoder'); upsert into table_step2 values(next value for seq_step2,'edu'); upsert into table_step2 values(next value for seq_step2,'coder'); upsert into table_step2 values(2010,'test'); ```