HBase整合Phoenix --黑马

Phoenix

什么是Phoenix

  • Phoenix是一个基于HBase的开源SQL引擎,可以使用标准的JDBC API代替HBase客户端API来创建表,插入数据,查询你的HBase数据
  • Phoenix完全使用Java编写,作为HBase内嵌的JDBC驱动。Phoenix查询引擎会将SQL查询转换为一个或多个HBase扫描,并编排执行以生成标准的JDBC结果集。直接使用HBase API、协同处理器与自定义过滤器,对于简单查询来说,其性能量级是毫秒,对于百万级别的行数来说,其性能量级是秒
  • Phoenix性能
    • Phoenix是构建在HBase之上的SQL引擎
    • Phoenix通过以下方式实现高性能操作HBase
      • 编译你的SQL查询为原生HBase的scan语句
      • 检测scan语句最佳的开始和结束的key
      • 精心编排你的scan语句让他们并行执行
      • 推送你的WHERE子句的谓词到服务端过滤器处理
      • 执行聚合查询通过服务端钩子(称为协同处理器)
      • 实现了二级索引来提升非主键字段查询的性能
      • 统计相关数据来提高并行化水平,并帮助选择最佳优化方案
      • 跳过扫描过滤器来优化IN,LIKE,OR查询
      • 优化主键的来均匀分布写压力

官网地址:

http://phoenix.apache.org/
在这里插入图片描述

Phoenix的安装部署

1、准备工作

  • 提前安装好ZK集群、hadoop集群、Hbase集群

2、安装包
下载地址:https://mirrors.cnnic.cn/apache/phoenix/apache-phoenix-4.14.0-cdh5.14.2/bin/

资料\安装\apache-phoenix-4.14.0-HBase-1.1-bin.tar.gz

3、上传、解压

  • 将对应的安装包上传到对应的Hbase集群其中一个服务器的一个目录下,并解压
tar -xvzf apache-phoenix-4.14.0-HBase-1.1-bin.tar.gz -C ../servers/

4、拷贝Phoenix整合HBase所需JAR包

将phoenix目录下的 phoenix-4.14.0-HBase-1.1-server.jar(phoenix-4.14.0-cdh5.14.2-server.jar)、phoenix-core-4.14.0-HBase-1.1.jar(phoenix-core-4.14.0-cdh5.14.2.jar)拷贝到各个 hbase的lib目录下

scp phoenix-4.14.0-HBase-1.1-server.jar phoenix-core-4.14.0-HBase-1.1.jar node1:/export/servers/hbase-1.1.1/lib
scp phoenix-4.14.0-HBase-1.1-server.jar phoenix-core-4.14.0-HBase-1.1.jar node2:/export/servers/hbase-1.1.1/lib
scp phoenix-4.14.0-HBase-1.1-server.jar phoenix-core-4.14.0-HBase-1.1.jar node3:/export/servers/hbase-1.1.1/lib

5、在Phoenix中配置HADOOP、配置HBASE

将hbase的配置文件hbase-site.xml、 hadoop/etc/hadoop下的core-site.xml 、hdfs-site.xml放到phoenix/bin/下,替换phoenix原来的配置文件

# 进入到 hbase bin目录
cd /export/servers/apache-phoenix-4.14.0-HBase-1.1-bin/bin

# 备份原先的 hbase-site.xml文件
mv hbase-site.xml hbase-site.xml.bak

ln -s $HBASE_HOME/conf/hbase-site.xml .
ln -s $HADOOP_HOME/etc/hadoop/core-site.xml .
ln -s $HADOOP_HOME/etc/hadoop/hdfs-site.xml .

6、重启hbase集群,使Phoenix的jar包生效

7、验证是否成功

./sqlline.py node1:2181

出现如下界面说明启动成功

Setting property: [incremental, false]
Setting property: [isolation, TRANSACTION_READ_COMMITTED]
issuing: !connect jdbc:phoenix:node1:2181 none none org.apache.phoenix.jdbc.PhoenixDriver
Connecting to jdbc:phoenix:node1:2181
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/export/servers/apache-phoenix-4.14.0-HBase-1.1-bin/phoenix-4.14.0-HBase-1.1-client.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/export/servers/hadoop-2.6.0-cdh5.14.0/share/hadoop/common/lib/slf4j-log4j12-1.7.5.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
19/10/18 09:58:06 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
Connected to: Phoenix (version 4.14)
Driver: PhoenixEmbeddedDriver (version 4.14)
Autocommit status: true
Transaction isolation: TRANSACTION_READ_COMMITTED
Building list of tables and columns for tab-completion (set fastconnect to true to skip)...
133/133 (100%) Done
Done
sqlline version 1.2.0

8、查看当前有哪些表

  • 输入!tables 查看都有哪些表
  • 红框部分是用户建的表,其他为Phoenix系统表,系统表中维护了用户表的元数据信息
+--------------+-------------+---------------+-+-----------------+---------------+---------+
| TABLE_SCHEM  | TABLE_NAME  |  TABLE_TYPE   | | IMMUTABLE_ROWS  | SALT_BUCKETS  | MULTI_T |
+--------------+-------------+---------------+-+-----------------+---------------+---------+
| SYSTEM       | CATALOG     | SYSTEM TABLE  | | false           | null          | false   |
| SYSTEM       | FUNCTION    | SYSTEM TABLE  | | false           | null          | false   |
| SYSTEM       | LOG         | SYSTEM TABLE  | | true            | 32            | false   |
| SYSTEM       | SEQUENCE    | SYSTEM TABLE  | | false           | null          | false   |
| SYSTEM       | STATS       | SYSTEM TABLE  | | false           | null          | false   |
+--------------+-------------+---------------+-+-----------------+---------------+---------+

9、退出Phoenix,输入!quit

Phoenix入门案例

需求一:

  • 使用SQL语句在Phoenix中,创建一个用户表。该用户表有以下列
ID姓名年龄性别地址
1张三30北京西城区
2李四20上海闵行区
  • 往表中插入两条数据,查询数据,并查看HBase中的数据

需求分析:

  • 直接在 Phoenix 中,使用 create table 语法创建表结构
  • 因为数据最终都需要保存在HBase中,故创建表的时候需要指定 HBase 中的列蔟名称

参考代码:

-- 创建表
create table if not exists "user_info"(
    "id" varchar primary key,
    "cf"."name" varchar,
    "cf"."age" integer,
    "cf"."sex" varchar,
    "cf"."address" varchar
);

-- 新增数据
upsert into "user_info" values('1', '张三', 30, '男', '北京市西城区');
upsert into "user_info" values('2', '李四', 20, '女', '上海市闵行区');

需求二:

  • 修改 id为1 用户的年龄为 45
-- 修改数据
upsert into "user_info"("id", "age") values('1', 35);

需求三:

  • 删除 id为2 用户数据
-- 删除数据
delete from "user_info" where "id" = '2';

建立与HBase表映射

在HBase已经存在表,需要使用 Phoenix 建立与 HBase的映射,从而以SQL的方式,通过Phoenix 操作HBase。

案例:

1、在HBase中,建立employee的映射表—数据准备

create 'employee','company','family'

put 'employee','row1','company:name','ted'
put 'employee','row1','company:position','worker'
put 'employee','row1','family:tel','13600912345'

put 'employee','row2','company:name','michael'
put 'employee','row2','company:position','manager'
put 'employee','row2','family:tel','1894225698'

scan 'employee'

2、建立映射视图

  • 在HBase中已有表,在Phoenix中建立映射,必须要使用 create view

  • Phoenix是大小写敏感的

  • 所有命令都是大写

  • 如果表名不用双引号括起来,无论输入大写或小写,建立的表名都是大写

  • 如果要建立同时包含大写和小写的表名和字段名,用双引号把表名或者字段名括起来

在Phoenix中打开命令行

CREATE VIEW IF NOT EXISTS "employee" (
    "rowid" VARCHAR NOT NULL PRIMARY KEY, 
    "company"."name" VARCHAR,
    "company"."position" VARCHAR,
    "family"."tel" VARCHAR
);

这个语句有几个注意点

  • IF NOT EXISTS可以保证如果已经有建立过这个表,配置不会被覆盖

  • 作为rowkey的字段用 PRIMARY KEY标定

  • 列簇用 columnFamily.columnName 来表示

  • 建立好后,查询一下数据

3、 查询所有映射表数据

0: jdbc:phoenix:node01> SELECT * FROM "employee";
+-------+----------+-----------+--------------+-------+
|  no   |   name   | position  |     tel      |  age  |
+-------+----------+-----------+--------------+-------+
| row1  | ted      | worker    | 13600912345  | null  |
| row2  | michael  | manager   | 1894225698   | null  |
+-------+----------+-----------+--------------+-------+

4、查询职位为 ‘worker’ 的所有员工数据

select * from "employee" where "position" = 'worker'

使用Phoenix构建二级索引加快查询效率

  • HBase通过rowkey来查询,否则就必须逐行地比较每一列的值,即全表扫瞄
  • 数据量较大的表,全表扫描的性能很差
  • 如果需要从多个角度查询数据,不可能使用 rowkey 来实现查询。此时可使用secondary index(二级索引)来完成这件事
  • Phoenix提供了对HBase secondary index的支持

配置HBase支持Phoenix二级索引

1、在每一个 HRegionServce的 hbase-site.xml 加入以下属性

<property> 
  <name>hbase.regionserver.wal.codec</name> 
  <value>org.apache.hadoop.hbase.regionserver.wal.IndexedWALEditCodec</value> 
</property>

2、重启HBase集群使配置生效

使用Phoenix创建二级索引

1、创建索引

create local index "idx_tel" on "employee"("family"."tel");

2、查看执行计划,检查是否查询二级索引

explain select * from "employee" where "name" = 'ted';
explain select  * from "employee" where "tel" = '13600912345';

3、删除索引

drop index "idx_tel" on "employee";

4、查看表上的所有索引

!indexes "employee"

订单明细创建Phoenix映射表

建立映射表

实现步骤:

  • 在Phoenix中建立映射表
  • 实现各种查询

1、建表SQL语句:

create view "dwd_order_detail"(
    "rowid" varchar primary key,
    "detail"."ogId" varchar,
    "detail"."orderId" varchar,
    "detail"."goodsId" varchar,
    "detail"."goodsNum" varchar,
    "detail"."goodsPrice" varchar,
    "detail"."goodsName" varchar,
    "detail"."shopId" varchar,
    "detail"."goodsThirdCatId" varchar,
    "detail"."goodsThirdCatName" varchar,
    "detail"."goodsSecondCatId" varchar,
    "detail"."goodsSecondCatName" varchar,
    "detail"."goodsFirstCatId" varchar,
    "detail"."goodsFirstCatName" varchar,
    "detail"."areaId" varchar,
    "detail"."shopName" varchar,
    "detail"."shopCompany" varchar,
    "detail"."cityId" varchar,
    "detail"."cityName" varchar,
    "detail"."regionId" varchar,
    "detail"."regionName" varchar
);

2、在表上的以下列创建索引

列名说明
goodsThirdCatName三级分类
goodsSecondCatName二级分类
goodsFirstCatName一级分类
cityName城市名称
regionName大区名称

参考代码:

-- 创建索引
create local index "idx_dwd_order_detail" on "dwd_order_detail"("detail"."goodsThirdCatName", "detail"."goodsSecondCatName", "detail"."goodsFirstCatName", "detail"."cityName", "detail"."regionName");

explain select * from "dwd_order_detail" where "goodsThirdCatName" = '其他蔬果' and "cityName" = '景德镇市分公司';

使用编写JDBC程序查询Phoenix数据

需求:

  • 编写Java 代码查询 订单明细

1、导入依赖

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencies>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>3.8.1</version>
    </dependency>
    <dependency>
        <groupId>org.apache.phoenix</groupId>
        <artifactId>phoenix-core</artifactId>
        <version>4.14.0-HBase-1.1</version>
    </dependency>
</dependencies>

2、编写JDBC程序

URL: jdbc:phoenix:node1:2181

3、新建一个 模块,注意不要从 itcast_shop_parent 继承(否则,会依赖CDH)

参考代码:

Class.forName("org.apache.phoenix.jdbc.PhoenixDriver");

Connection connection = DriverManager.getConnection("jdbc:phoenix:node1:2181", "", "");
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery("select * from \"dwd_order_detail\" limit 10 ");

while(resultSet.next()) {
    String rowid = resultSet.getString("rowid");
    String ogId = resultSet.getString("ogId");
    String orderId = resultSet.getString("orderId");
    String goodsId = resultSet.getString("goodsId");
    String goodsNum = resultSet.getString("goodsNum");
    String goodsPrice = resultSet.getString("goodsPrice");
    String goodsName = resultSet.getString("goodsName");
    String shopId = resultSet.getString("shopId");
    String goodsThirdCatId = resultSet.getString("goodsThirdCatId");
    String goodsThirdCatName = resultSet.getString("goodsThirdCatName");
    String goodsSecondCatId = resultSet.getString("goodsSecondCatId");
    String goodsSecondCatName = resultSet.getString("goodsSecondCatName");
    String goodsFirstCatId = resultSet.getString("goodsFirstCatId");
    String goodsFirstCatName = resultSet.getString("goodsFirstCatName");
    String areaId = resultSet.getString("areaId");
    String shopName = resultSet.getString("shopName");
    String shopCompany = resultSet.getString("shopCompany");
    String cityId = resultSet.getString("cityId");
    String cityName = resultSet.getString("cityName");
    String regionId = resultSet.getString("regionId");
    String regionName = resultSet.getString("regionName");

    System.out.print(rowid);
    System.out.print(ogId);
    System.out.print(orderId);
    System.out.print(goodsId);
    System.out.print(goodsNum);
    System.out.print(goodsPrice);
    System.out.print(goodsName);
    System.out.print(shopId);
    System.out.print(goodsThirdCatId);
    System.out.print(goodsThirdCatName);
    System.out.print(goodsSecondCatId);
    System.out.print(goodsSecondCatName);
    System.out.print(goodsFirstCatId);
    System.out.print(goodsFirstCatName);
    System.out.print(areaId);
    System.out.print(shopName);
    System.out.print(shopCompany);
    System.out.print(cityId);
    System.out.print(cityName);
    System.out.print(regionId);
    System.out.print(regionName);
    System.out.println();
}

resultSet.close();
statement.close();
connection.close();
}

热门文章

暂无图片
编程学习 ·

Java输出数组的内容

Java输出数组的内容_一万个小时-CSDN博客_java打印数组内容1. 输出内容最常见的方式// List<String>类型的列表List<String> list new ArrayList<String>();list.add("First");list.add("Second");list.add("Third");list.ad…
暂无图片
编程学习 ·

母螳螂的“魅惑之术”

在它们对大蝗虫发起进攻的时候&#xff0c;我认认真真地观察了一次&#xff0c;因为它们突然像触电一样浑身痉挛起来&#xff0c;警觉地面对限前这个大家伙&#xff0c;然后放下自己优雅的身段和祈祷的双手&#xff0c;摆出了一个可怕的姿势。我被眼前的一幕吓到了&#xff0c;…
暂无图片
编程学习 ·

疯狂填词 mad_libs 第9章9.9.2

#win7 python3.7.0 import os,reos.chdir(d:\documents\program_language) file1open(.\疯狂填词_d9z9d2_r.txt) file2open(.\疯狂填词_d9z9d2_w.txt,w) words[ADJECTIVE,NOUN,VERB,NOUN] str1file1.read()#方法1 for word in words :word_replaceinput(fEnter a {word} :)str1…
暂无图片
编程学习 ·

HBASE 高可用

为了保证HBASE是高可用的,所依赖的HDFS和zookeeper也要是高可用的. 通过参数hbase.rootdir指定了连接到Hadoop的地址,mycluster表示为Hadoop的集群. HBASE本身的高可用很简单,只要在一个健康的集群其他节点通过命令 hbase-daemon.sh start master启动一个Hmaster进程,这个Hmast…
暂无图片
编程学习 ·

js事件操作语法

一、事件的绑定语法 语法形式1 事件监听 标签对象.addEventListener(click,function(){}); 语法形式2 on语法绑定 标签对象.onclick function(){} on语法是通过 等于赋值绑定的事件处理函数 , 等于赋值本质上执行的是覆盖赋值,后赋值的数据会覆盖之前存储的数据,也就是on…
暂无图片
编程学习 ·

Photoshop插件--晕影动态--选区--脚本开发--PS插件

文章目录1.插件界面2.关键代码2.1 选区2.2 动态晕影3.作者寄语PS是一款栅格图像编辑软件&#xff0c;具有许多强大的功能&#xff0c;本文演示如何通过脚本实现晕影动态和选区相关功能&#xff0c;展示从互联网收集而来的一个小插件&#xff0c;供大家学习交流&#xff0c;请勿…
暂无图片
编程学习 ·

vs LNK1104 无法打开文件“xxx.obj”

写在前面&#xff1a; 向大家推荐两本新书&#xff0c;《深度学习计算机视觉实战》和《学习OpenCV4&#xff1a;基于Python的算法实战》。 《深度学习计算机视觉实战》讲了计算机视觉理论基础&#xff0c;讲了案例项目&#xff0c;讲了模型部署&#xff0c;这些项目学会之后可以…
暂无图片
编程学习 ·

工业元宇宙的定义与实施路线图

工业元宇宙的定义与实施路线图 李正海 1 工业元宇宙 给大家做一个关于工业元宇宙的定义。对于工业&#xff0c;从设计的角度来讲&#xff0c;现在的设计人员已经做到了普遍的三维设计&#xff0c;但是进入元宇宙时代&#xff0c;就不仅仅只是三维设计了&#xff0c;我们的目…
暂无图片
编程学习 ·

【leectode 2022.1.15】完成一半题目

有 N 位扣友参加了微软与力扣举办了「以扣会友」线下活动。主办方提供了 2*N 道题目&#xff0c;整型数组 questions 中每个数字对应了每道题目所涉及的知识点类型。 若每位扣友选择不同的一题&#xff0c;请返回被选的 N 道题目至少包含多少种知识点类型。 示例 1&#xff1a…
暂无图片
编程学习 ·

js 面试题总结

一、js原型与原型链 1. prototype 每个函数都有一个prototype属性&#xff0c;被称为显示原型 2._ _proto_ _ 每个实例对象都会有_ _proto_ _属性,其被称为隐式原型 每一个实例对象的隐式原型_ _proto_ _属性指向自身构造函数的显式原型prototype 3. constructor 每个prot…
暂无图片
编程学习 ·

java练习代码

打印自定义行数的空心菱形练习代码如下 import java.util.Scanner; public class daYinLengXing{public static void main(String[] args) {System.out.println("请输入行数");Scanner myScanner new Scanner(System.in);int g myScanner.nextInt();int num g%2;//…
暂无图片
编程学习 ·

RocketMQ-什么是死信队列?怎么解决

目录 什么是死信队列 死信队列的特征 死信消息的处理 什么是死信队列 当一条消息初次消费失败&#xff0c;消息队列会自动进行消费重试&#xff1b;达到最大重试次数后&#xff0c;若消费依然失败&#xff0c;则表明消费者在正常情况下无法正确地消费该消息&#xff0c;此时…
暂无图片
编程学习 ·

项目 cg day04

第4章 lua、Canal实现广告缓存 学习目标 Lua介绍 Lua语法 输出、变量定义、数据类型、流程控制(if..)、循环操作、函数、表(数组)、模块OpenResty介绍(理解配置) 封装了Nginx&#xff0c;并且提供了Lua扩展&#xff0c;大大提升了Nginx对并发处理的能&#xff0c;10K-1000K Lu…
暂无图片
编程学习 ·

输出三角形

#include <stdio.h> int main() { int i,j; for(i0;i<5;i) { for(j0;j<i;j) { printf("*"); } printf("\n"); } }
暂无图片
编程学习 ·

stm32的BOOTLOADER学习1

序言 最近计划学习stm32的BOOTLOADER学习,把学习过程记录下来 因为现在网上STM32C8T6还是比较贵的,根据我的需求flash空间小一些也可以,所以我决定使用stm32c6t6.这个芯片的空间是32kb的。 #熟悉芯片内部的空间地址 1、flash ROM&#xff1a; 大小32KB&#xff0c;范围&#xf…
暂无图片
编程学习 ·

通过awk和shell来限制IP多次访问之学不会你打死我

学不会你打死我 今天我们用shell脚本&#xff0c;awk工具来分析日志来判断是否存在扫描器来进行破解网站密码——限制访问次数过多的IP地址&#xff0c;通过Iptables来进行限制。代码在末尾 首先我们要先查看日志的格式&#xff0c;分析出我们需要筛选的内容&#xff0c;日志…
暂无图片
编程学习 ·

Python - 如何像程序员一样思考

在为计算机编写程序之前&#xff0c;您必须学会如何像程序员一样思考。学习像程序员一样思考对任何学生都很有价值。以下步骤可帮助任何人学习编码并了解计算机科学的价值——即使他们不打算成为计算机科学家。 顾名思义&#xff0c;Python经常被想要学习编程的人用作第一语言…
暂无图片
编程学习 ·

蓝桥杯python-数字三角形

问题描述 虽然我前后用了三种做法&#xff0c;但是我发现只有“优化思路_1”可以通过蓝桥杯官网中的测评&#xff0c;但是如果用c/c的话&#xff0c;每个都通得过&#xff0c;足以可见python的效率之低&#xff08;但耐不住人家好用啊&#xff08;哭笑&#xff09;&#xff09…