Phoenix 之旅

Phoenix 之旅,第1张

Phoenix 之旅

Phoenix 之旅

整合Phoenix

Phoenix简介Phoenix 快速入门

Phoenix部署Phoenix Shell *** 作Phoenix JDBC *** 作 Phoenix二级索引

二级索引配置文件全局二级索引本地二级索引 与 Hive 的集成

Hbase 与 Hive 的对比

HiveHbase Hbase与Hive集成使用

案例一案例二

整合Phoenix Phoenix简介

官网地址 : http://phoenix.apache.org/

Phoenix 是 Hbase 的开源SQL皮肤。可以使用标准 JDBC API 代替 Hbase 客户端 API 来创建表,插入数据和查询 Hbase 数据

特点 :

容易集成:如Spark,Hive,Pig,Flume 和 Map Reduce *** 作简单:DML 命令以及通过 DDL 命令创建和 *** 作表和版本化增量更改支持 Hbase 二级索引创建

Phoenix 架构 :

Phoenix 快速入门 Phoenix部署

上传并解压 tar 包

tar -zxvf phoenix-5.0.0-Hbase-2.0-bin.tar.gz -C /opt/module/

改名

mv apache-phoenix-5.0.0-Hbase-2.0-bin phoenix-5.0.0-Hbase-2.0

复制 server 包并拷贝到各个节点的 hbase/lib

cp /opt/module/phoenix-5.0.0-Hbase-2.0/phoenix-5.0.0-Hbase-2.0-server.jar /opt/module/hbase-2.0.5/lib/

xsync phoenix-5.0.0-Hbase-2.0-server.jar

配置环境变量

vim /etc/profile.d/my_env.sh
#phoenix
export PHOENIX_HOME=/opt/module/phoenix-5.0.0-Hbase-2.0
export PHOENIX_CLASSPATH=$PHOENIX_HOME
export PATH=$PATH:$PHOENIX_HOME/bin

source /etc/profile

重启Hbase

stop-hbase.sh
start-hbase.sh

连接 Phoenix

sqlline.py cpucode101,cpucode102,cpucode103:2181

Phoenix Shell *** 作

schema的 *** 作

默认情况下,在 phoenix 中不能直接创建 schema

在 Hbase 中 conf 目录下的 hbase-site.xml 和 phoenix 中 bin 目录下的 hbase-site.xml 中

   
        phoenix.schema.isNamespaceMappingEnabled
        true
    

xsync hbase-site.xml

重新启动 Hbase 和连接 phoenix 客户端

stop-hbase.sh
start-hbase.sh

sqlline.py cpucode101,cpucode102,cpucode103:2181

创建 schema

create schema bigdata;

create schema if not exists "mytest1";

删除 schema

drop schema if exists "mytest1";

在phoenix中,schema名,表名,字段名等会自动转换为大写,若要小写,使用双引号,如 “student”

表的 *** 作

显示所有表

!table
!tables

创建表

直接指定单个列作为 RowKey

CREATE TABLE IF NOT EXISTS student(
id VARCHAR primary key,
name VARCHAR,
addr VARCHAR
);

插入数据

upsert into student values('1001', 'cpuCode', 'changsha');

upsert into student (id, name, addr) values('1002','haha','wuhu');

查询记录

select * from student;

select * from student where id = '1001';

删除记录

delete from student where id = '1001';

删除表

drop table student;

指定多个列的联合作为 RowKey

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)
);

插入数据

upsert into us_population values('NY','New York',155252);
upsert into us_population values('CA','Los Angeles',3844829);

退出命令行

!quit

表的映射

表的关系

默认情况下,直接在 Hbase 中创建的表,通过 Phoenix 是查看不到的。如果要在 Phoenix 中 *** 作直接在 Hbase 中创建的表,则需要在 Phoenix 中进行表的映射

映射方式有两种 :

视图映射表映射

命令行中创建表 test

Hbase 中 test 的表结构如下,两个列族 info1、info2

Rowkeyinfo1info2idnameaddress

启动 Hbase Shell

hbase shell

创建 Hbase 表 test3

create 'test3', 'info1', 'info2'
put 'test3', '1001', 'info1:name', 'zhangsan'
put 'test3', '1001', 'info2:address', 'beijing'

视图映射

Phoenix 创建的视图是只读的,所以只能用来做查询,无法通过视图对源数据进行修改等 *** 作

在 phoenix 中创建关联 test 表的视图

create view "test3" (
id varchar primary key,
"info1"."name" varchar, 
"info2"."address" varchar
);

查询视图

select * from "test3" ; 

select id, "name", "address" from "test3";

upsert into "test3" values('1002', 'lisi', 'shanghai');

删除视图

drop view "test3";

表映射

使用 Apache Phoenix 创建对 Hbase 的表映射,有两种方法:

Hbase中不存在表时,可以直接使用 create table 指令创建需要的表,系统将会自动在 Phoenix 和 Hbase 中创建person_infomation 的表,并会根据指令内的参数对表结构进行初始化

当Hbase中已经存在表时,可以以类似创建视图的方式创建关联表,只需要将 create view 改为 create table

create table "test3"(
id varchar primary key,
"info1"."name" varchar,
"info2"."address" varchar
) COLUMN_ENCODED_BYTES = NONE;
select id, "name", "address" from "test3";

drop table "test3";

表映射中数值类型的问题

Hbase 中存储数值类型的值 (如 int , long 等) 会按照正常数字的补码进行存储. 而 phoenix 对数字的存储做了特殊的处理

phoenix 为了解决遇到正负数同时存在时,导致负数排到了正数的后面(负数高位为 1,正数高位为 0 ,字典序 0 < 1)的问题

phoenix 在存储数字时会对高位进行转换. 原来为 1, 转换为 0,原来为 0,转换为 1

如 hbase 表中的数据的写是由 phoenix 写入的 , 不会出现问题,因为对数字的编解码都是 phoenix 来负责

如 hbase 表中的数据不是由 phoenix 写入的,数字的编码由 hbase 负责. 而 phoenix 读数据时要对数字进行解码。 因为编解码方式不一致。导致数字出错

phoenix 存, phoenix 查. 没有问题
phoenix 存, hbase 查. 有问题
hbase 存, hbase 查, 没有问题
hbase 存, phoenix 查, 有问题

在 hbase 中创建表,并插入数值类型的数据

create 'person', 'info'

put 'person', '1001', 'info:salary', Bytes.toBytes(123456)

如果要插入数字类型,需要通过 Bytes.toBytes(123456) 来实现

在 phoenix 中创建映射表并查询数据

create table "person"(
id varchar primary key,
"info"."salary" integer 
) column_encoded_bytes = 0;
select * from "person";

解决办法:

在 phoenix 中创建表时使用无符号的数值类型. unsigned_long

create table "person1"(
id varchar primary key,
"info"."salary" unsigned_long
) column_encoded_bytes = 0;

upsert into "person1" values('10001', 1111);

put 'person1', '1002', 'info:salary', Bytes.toBytes(2222)

select * from "person1";

Phoenix JDBC *** 作

Thin Client

启动 query server

queryserver.py start

创建项目并导入依赖

    
        
            org.apache.phoenix
            phoenix-queryserver-client
            5.0.0-Hbase-2.0
        
    
package com.cpucode.phoenix.thin.client;

import java.sql.*;
import org.apache.phoenix.queryserver.client.ThinClientUtil;


public class ThinClientTest {
    public static void main(String[] args) throws SQLException {
        //1. 获取连接
        String connectionUrl = ThinClientUtil.getConnectionUrl("cpucode101", 8765);

        Connection connection = DriverManager.getConnection(connectionUrl);

        //2. 编写SQL
        String sql = "select * from "person1"";

        //3. 预编译
        PreparedStatement preparedStatement = connection.prepareStatement(sql);

        //4. 执行sql
        ResultSet resultSet = preparedStatement.executeQuery();

        //5. 封装结果
        while (resultSet.next()) {
            System.out.println(resultSet.getString(1) + "t" +
                    resultSet.getString(2));
        }

        //6. 关闭连接
        resultSet.close();
        preparedStatement.close();
        connection.close();
    }
}

Thick Client

在pom中加入依赖

    
        
            org.apache.phoenix
            phoenix-core
            5.0.0-Hbase-2.0
            
                
                    org.glassfish
                    javax.el
                
            
        

        
            org.glassfish
            javax.el
            3.0.1-b06
        
    
package com.cpucode.phoenix.thick.client;

import java.sql.*;
import java.util.Properties;


public class ThickClientTest {
    public static void main(String[] args) throws SQLException {
        //1. 获取连接
        String url = "jdbc:phoenix:cpucode101,cpucode102,cpucode103:2181";
        Properties properties = new Properties();
        properties.put("phoenix.schema.isNamespaceMappingEnabled", "true");

        Connection connection = DriverManager.getConnection(url, properties);

        //2. 编写SQL
        String sql = "select * from "person1"";

        //3. 预编译
        PreparedStatement preparedStatement = connection.prepareStatement(sql);

        //4. 执行sql
        ResultSet resultSet = preparedStatement.executeQuery();

        //5. 封装结果
        while(resultSet.next()){
            String line = resultSet.getString("id") + " : " +
                    resultSet.getString("salary") ;

            System.out.println(line);
        }

        //6. 关闭连接
        resultSet.close();
        preparedStatement.close();
        connection.close();
    }
}

Phoenix二级索引 二级索引配置文件

添加如下配置到 Hbase 的 HRegionserver 节点的 hbase-site.xml

    
    
        hbase.regionserver.wal.codec
        org.apache.hadoop.hbase.regionserver.wal.IndexedWALEditCodec
    

    
        hbase.region.server.rpc.scheduler.factory.class
        org.apache.hadoop.hbase.ipc.PhoenixRpcSchedulerFactory
        Factory to create the Phoenix RPC Scheduler that uses separate queues for index and metadata updates
    

    
        hbase.rpc.controllerfactory.class
        org.apache.hadoop.hbase.ipc.controller.ServerRpcControllerFactory
        Factory to create the Phoenix RPC Scheduler that uses separate queues for index and metadata updates
    

xsync hbase-site.xml

stop-hbase.sh
start-hbase.sh

全局二级索引

Global Index 是默认的索引格式,创建全局索引时,会在 Hbase 中建立一张新表。也就是说索引数据和数据表是存放在不同的表中的,全局索引适用于多读少写的业务场景

写数据的时候会消耗大量开销,因为索引表也要更新,而索引表是分布在不同的数据节点上的,跨节点的数据传输带来了较大的性能消耗

在读数据的时候 Phoenix 会选择索引表来降低查询消耗的时间

创建表

CREATE TABLE IF NOT EXISTS student(
id VARCHAR primary key,
name VARCHAR,
addr VARCHAR);

FULL SCAN :

explain select id from student;

POINT LOOKUP :

explain select id from student where id = '1002';

FULL SCAN :

explain select id from student where name = 'cpuCode';

给 name 字段建索引

create index idx_student_name on student(name);

RANGE SCAN

explain select id from student where name = 'cpu';

POINT LOOKUP :

explain select id, name from student where id = '1001';

RANGE SCAN :

explain select id, name from student where name  = 'code';

FULL SCAN :

explain select id, name, addr from student where name  = 'code';

给 name addr 建复合索引

drop index idx_student_name on student; 
create index idx_student_name on student(name, addr);

RANGE SCAN :

explain select id, name, addr  from student where name  ='cpu';

RANGE SCAN :

explain select id, name, addr from student where name = 'code' and addr = 'beijing';

FULL SCAN :

explain select id, name, addr from student where addr = 'beijing';

RANGE SCAN :

explain select id, name, addr from student where addr = 'beijing' and name = 'cpu';

给 name 列建索引包含 addr 列

drop index idx_student_name on student; 
create index idx_student_name on student(name) include(addr);

RANGE SCAN :

explain select id, name, addr from student where name  = 'cpu';

创建单个字段的全局索引

想查询的字段不是索引字段的话索引表不会被使用,不会带来查询速度的提升

创建携带其他字段的全局索引

本地二级索引

Local Index 适用于写 *** 作频繁的场景

索引数据和数据表的数据是存放在同一张表中(且是同一个Region,避免了在写 *** 作的时候往不同服务器的索引表中写索引带来的额外开销

drop index idx_student_name on student;
create local index idx_student_name on student(name);

RANGE SCAN :

explain select id, name, addr from student where name  = 'cpu';

与 Hive 的集成 Hbase 与 Hive 的对比 Hive

数据分析工具 : Hive 的本质其实就相当于将 HDFS 中已经存储的文件在 Mysql 中做了一个双射关系,以方便使用 HQL 去管理查询用于数据分析、清洗 : Hive 适用于离线的数据分析和清洗,延迟较高基于HDFS、MapReduce : Hive 存储的数据依旧在 DataNode 上,HQL语句将会转换为 MapReduce 代码执行 Hbase

数据库 : 是一种面向列族存储的非关系型数据库用于存储结构化和非结构化的数据 : 适用于单表非关系型数据的存储,不适合做关联查询,类似 JOIN 等 *** 作基于HDFS : 数据持久化存储的体现形式是 HFile,存放于 DataNode 中,被 ResionServer 以region 的形式进行管理延迟较低,接入在线业务使用 : 面对大量的企业数据,Hbase可以直线单表大量数据的存储,同时提供了高效的数据访问速度 Hbase与Hive集成使用

在 hive-site.xml 中添加 zookeeper 的属性

    
        hive.zookeeper.quorum
        cpucode101,cpucode102,cpucode103
    

    
        hive.zookeeper.client.port
        2181
    
案例一

目标:建立Hive表,关联Hbase表,插入数据到Hive表的同时能够影响Hbase表

分步实现:

在Hive中创建表同时关联Hbase

create table hive_hbase_emp_table(
	empno int,
	ename string,
	job string,
	mgr int,
	hiredate string,
	sal double,
	comn double,
	deptno int
)
STORED BY 'org.apache.hadoop.hive.hbase.HbaseStorageHandler'
WITH SERDEPROPERTIES ("hbase.columns.mapping" = ":key,info:ename,info:job,info:mgr,info:hiredate,info:sal,info:comm,info:deptno")
TBLPROPERTIES ("hbase.table.name" = "hbase_emp_table");

完成之后,可以分别进入Hive和Hbase查看,都生成了对应的表

在Hive中创建临时中间表,用于load文件中的数据

不能将数据直接load进Hive所关联Hbase的那张表中

CREATE TABLE emp(
	empno int,
	ename string,
	job string,
	mgr int,
	hiredate string,
	sal double,
	comm double,
	deptno int
) row format delimited fields terminated by 't';

向 Hive 中间表中 load 数据

load data local inpath '/home/admin/softwares/data/emp.txt' into table emp;

通过 insert 命令将中间表中的数据导入到 Hive 关联 Hbase 的那张表中

insert into table hive_hbase_emp_table select * from emp;

查看 Hive 以及关联的 Hbase 表中是否已经成功的同步插入了数据

Hive:

select * from hive_hbase_emp_table;

Hbase:

scan 'hbase_emp_table'
案例二

目标:在 Hbase 中已经存储了某一张表 hbase_emp_table ,然后在 Hive 中创建一个外部表来关联 Hbase 中的 hbase_emp_table 这张表,使之可以借助 Hive 来分析 Hbase 这张表中的数据

分步实现:

在Hive中创建外部表

create EXTERNAL table relevance_hbase_emp(
	empno int,
	ename string,
	job string,
	mgr int,
	hiredate string,
	sal double,
	comn double,
	deptno int
)
STORED BY 'org.apache.hadoop.hive.hbase.HbaseStorageHandler'
WITH SERDEPROPERTIES ("hbase.columns.mapping" = ":key,info:ename,info:job,info:mgr,info:hiredate,info:sal,info:comm,info:deptno") 
TBLPROPERTIES ("hbase.table.name" = "hbase_emp_table");

关联后就可以使用 Hive 函数进行一些分析 *** 作

select * from relevance_hbase_emp;

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5717905.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存