前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >大数据之Phonenix与Hbase集成

大数据之Phonenix与Hbase集成

作者头像
码客说
发布2022-12-16 15:27:27
1.4K0
发布2022-12-16 15:27:27
举报
文章被收录于专栏:码客码客

前言

Phoenix是构建在HBase上的一个SQL层,能让我们用标准的JDBC APIs而不是HBase客户端APIs来创建表,插入数据和对HBase数据进行查询。 Phoenix完全使用Java编写,作为HBase内嵌的JDBC驱动。Phoenix查询引擎会将SQL查询转换为一个或多个HBase扫描,并编排执行以生成标准的JDBC结果集。直接使用HBase API、协同处理器与自定义过滤器,对于简单查询来说,其性能量级是毫秒,对于百万级别的行数来说,其性能量级是秒。 Phoenix通过以下方式使我们可以少写代码,并且性能比我们自己写代码更好:

将SQL编译成原生的HBase scans。 确定scan关键字的最佳开始和结束让scan并行执行

本文使用 HBase2.1.10 + Phoenix5.1.2

下载与安装

http://archive.apache.org/dist/phoenix/phoenix-5.1.2/

image-20221215092930316
image-20221215092930316

解压

代码语言:javascript
复制
tar -zxvf phoenix-hbase-2.1-5.1.2-bin.tar.gz -C /data/tools/bigdata/
cd /data/tools/bigdata/phoenix-hbase-2.1-5.1.2-bin

环境变量

环境变量

代码语言:javascript
复制
cd /etc/profile.d/

创建配置文件

代码语言:javascript
复制
vi /etc/profile.d/phoenix.sh

内容设置为

代码语言:javascript
复制
# phoenix
export PHOENIX_HOME=/data/tools/bigdata/phoenix-hbase-2.1-5.1.2-bin
export PATH=$PATH:$PHOENIX_HOME/bin

配置生效

代码语言:javascript
复制
source /etc/profile

查看是否生效

代码语言:javascript
复制
cd $PHOENIX_HOME

配置

Phoenix用来连接Hbase,不用做分布式部署。

把Jar复制到Hbase里

代码语言:javascript
复制
cd $PHOENIX_HOME
cp phoenix-server-hbase-2.1-5.1.2.jar $HBASE_HOME/lib/

注意不要复制phoenix-pherf-5.1.2.jar这个Jar包,会导致重复而无法启动Hbase。

查看是否复制成功

代码语言:javascript
复制
cd $HBASE_HOME/lib/
ls | grep phoenix

Hbase配置添加

代码语言:javascript
复制
vi $HBASE_HOME/conf/hbase-site.xml

添加

代码语言:javascript
复制
<!-- Phoenix 支持HBase 命名空间映射 -->
<property>
  <name>phoenix.schema.isNamespaceMappingEnabled</name>
  <value>true</value>
</property>
<property>
  <name>phoenix.schema.mapSystemTablesToNamespace</name>
  <value>true</value>
</property>

配置文件软连接

代码语言:javascript
复制
cd $PHOENIX_HOME
ln -sf $HBASE_HOME/conf/hbase-site.xml bin/

同步分发Hbase Phoenix不用分发

代码语言:javascript
复制
distribution.sh $HBASE_HOME

运行

查看所有服务

代码语言:javascript
复制
ha-call.sh "jps"

停止Hbase

代码语言:javascript
复制
$HBASE_HOME/bin/stop-hbase.sh

如果哪个节点没有停止,我们手动停止

代码语言:javascript
复制
ssh hadoop01 "hbase-daemon.sh stop regionserver"
ssh hadoop02 "hbase-daemon.sh stop master"
ssh hadoop02 "hbase-daemon.sh stop regionserver"
ssh hadoop03 "hbase-daemon.sh stop regionserver"

清除zookeeper 信息

代码语言:javascript
复制
zkCli.sh -server hadoop01:2181 <<< "deleteall /hbase"

清除HDFS 数据

代码语言:javascript
复制
hadoop fs -rm -r /hbase

这两个地址主要参考

image-20221215103135504
image-20221215103135504

启动Hbase

代码语言:javascript
复制
$HBASE_HOME/bin/start-hbase.sh

测试

启动 Zookeeper => HDFS => Yarn => HBase

代码语言:javascript
复制
sqlline.py hadoop01,hadoop02,hadoop03:2181

第一次启动比较慢,请耐心等待。

查询

代码语言:javascript
复制
!tables
!quit

Phoenix Shell操作

Schema的操作

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

需要将如下的参数添加到Hbase中conf目录下的hbase-site.xml 和 phoenix中bin目录下的 hbase-site.xml中

代码语言:javascript
复制
<property>
  <name>phoenix.schema.isNamespaceMappingEnabled</name>
  <value>true</value>
</property>

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

代码语言:javascript
复制
stop-hbase.sh
start-hbase.sh
sqlline.py hadoop01,hadoop02,hadoop03:2181

查看所有schema

代码语言:javascript
复制
!schema

创建schema

代码语言:javascript
复制
create schema "zdb";

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

执行如下命令使用这个新建的 schema:

代码语言:javascript
复制
use "zdb";

执行如下命令则使用默认的 schema:

代码语言:javascript
复制
USE DEFAULT;

执行如下命令可以删除 zdb 这个 schema:

注意:确保该 schema 下的表都已删除,否则该 schema 会删除失败。

代码语言:javascript
复制
DROP SCHEMA "zdb";

表的操作

1)显示所有表

代码语言:javascript
复制
!table
# 或 
!tables

2)创建表 直接指定单个列作为RowKey

代码语言:javascript
复制
CREATE TABLE IF NOT EXISTS "tuser"(
  id VARCHAR primary key,
  name VARCHAR,
  addr VARCHAR
);

指定多个列的联合作为RowKey

代码语言:javascript
复制
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)
);

3)插入数据

代码语言:javascript
复制
upsert into "tuser" values('1001','zhangsan','beijing');

4)查询记录

代码语言:javascript
复制
select * from "tuser";
select * from "tuser" where id='1001';

在Hbase中查看

代码语言:javascript
复制
list
scan 'tuser', {FORMATTER => 'toString'}

5)删除记录

代码语言:javascript
复制
delete from "tuser" where id='1001';

6)删除表

代码语言:javascript
复制
drop table "tuser";

7)退出命令行

代码语言:javascript
复制
!quit

表的映射

1)表的关系 默认情况下,直接在HBase中创建的表,通过Phoenix是查看不到的。

如果要在Phoenix中操作直接在HBase中创建的表,则需要在Phoenix中进行表的映射。

映射方式有两种:

  • 视图映射
  • 表映射。

2)命令行中创建表test HBase 中test的表结构如下,两个列族info1、info2。

Rowkey

info1

info2

id

name

address

启动HBase Shell

代码语言:javascript
复制
hbase shell

创建HBase表test

代码语言:javascript
复制
create 'test','info1','info2'

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

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

代码语言:javascript
复制
create view "test"(id varchar primary key,"info1"."name" varchar, "info2"."address" varchar);

删除视图

代码语言:javascript
复制
drop view "test";

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

  1. HBase中不存在表时,可以直接使用create table指令创建需要的表,系统将会自动在Phoenix和HBase中创建同名的表,并会根据指令内的参数对表结构进行初始化。
  2. 当HBase中已经存在表时,可以以类似创建视图的方式创建关联表,只需要将create table改为create view即可。
代码语言:javascript
复制
create table "test"(id varchar primary key,"info1"."name" varchar, "info2"."address" varchar) column_encoded_bytes=0;
create view "test"(id varchar primary key,"info1"."name" varchar, "info2"."address" varchar) column_encoded_bytes=0;

4.表映射中数值类型的问题 Hbase中存储数值类型的值(如int,long等)会按照正常数字的补码进行存储. 而phoenix对数字的存储做了特殊的处理. phoenix 为了解决遇到正负数同时存在时,导致负数排到了正数的后面(负数高位为1,正数高位为0,字典序0 < 1)的问题。

phoenix在存储数字时会对高位进行转换.原来为1,转换为0, 原来为0,转换为1. 因此,如果hbase表中的数据的写是由phoenix写入的,不会出现问题,因为对数字的编解码都是phoenix来负责。

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

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

代码语言:javascript
复制
create 'person','info'
put 'person','1001', 'info:salary',Bytes.toBytes(123456)

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

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

代码语言:javascript
复制
create table "person"(id varchar primary key,"info"."salary" integer) column_encoded_bytes=0;

select * from "person"

会发现数字显示有问题

3) 解决办法: 在phoenix中创建表时使用无符号的数值类型. unsigned_long

代码语言:javascript
复制
create table "person"(id varchar primary key,"info"."salary" unsigned_long) column_encoded_bytes=0;

Phoenix JDBC操作

Thin Client

1)启动query server

代码语言:javascript
复制
queryserver.py start

2)创建项目并导入依赖

代码语言:javascript
复制
<dependencies>
  <dependency>
    <groupId>org.apache.phoenix</groupId>
    <artifactId>phoenix-queryserver-client</artifactId>
    <version>5.1.2-HBase-2.1</version>
  </dependency>
</dependencies>

3)编写代码

代码语言:javascript
复制
import java.sql.*;
import org.apache.phoenix.queryserver.client.ThinClientUtil;

public class PhoenixTest {
  public static void main(String[] args) throws SQLException {

    String connectionUrl = ThinClientUtil.getConnectionUrl("hadoop01", 8765);

    Connection connection = DriverManager.getConnection(connectionUrl);
    PreparedStatement preparedStatement = connection.prepareStatement("select * from tuser");

    ResultSet resultSet = preparedStatement.executeQuery();

    while (resultSet.next()) {
      System.out.println(resultSet.getString(1) + "\t" + resultSet.getString(2));
    }

    //关闭
    connection.close();
  }
}

Thick Client

1)在pom中加入依赖

代码语言:javascript
复制
<dependencies>
  <dependency>
    <groupId>org.apache.phoenix</groupId>
    <artifactId>phoenix-core</artifactId>
    <version>5.1.2-HBase-2.1</version>
    <exclusions>
      <exclusion>
        <groupId>org.glassfish</groupId>
        <artifactId>javax.el</artifactId>
      </exclusion>
    </exclusions>
  </dependency>
  <dependency>
    <groupId>org.glassfish</groupId>
    <artifactId>javax.el</artifactId>
    <version>3.0.1-b06</version>
  </dependency>
</dependencies>

2)编写代码

代码语言:javascript
复制
import java.sql.*;
import java.util.Properties;

public class TestThick {
  public static void main(String[] args) throws SQLException {
    String url = "jdbc:phoenix:hadoop01,hadoop02,hadoop03:2181";
    Properties props = new Properties();
    props.put("phoenix.schema.isNamespaceMappingEnabled","true");
    Connection connection = DriverManager.getConnection(url,props);
    PreparedStatement ps = connection.prepareStatement("select * from \"test\"");
    ResultSet rs = ps.executeQuery();
    while(rs.next()){
      System.out.println(rs.getString(1)+":" +rs.getString(2));
    }
  }
}

Phoenix二级索引

1. 二级索引配置文件

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

代码语言:javascript
复制
<!-- phoenix regionserver 配置参数-->
<property>
  <name>hbase.regionserver.wal.codec</name>
  <value>org.apache.hadoop.hbase.regionserver.wal.IndexedWALEditCodec</value>
</property>

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

<property>
  <name>hbase.rpc.controllerfactory.class</name>
  <value>org.apache.hadoop.hbase.ipc.controller.ServerRpcControllerFactory</value>
  <description>Factory to create the Phoenix RPC Scheduler that uses separate queues for index and metadata updates</description>
</property>

2. 全局二级索引

Global Index是默认的索引格式,创建全局索引时,会在HBase中建立一张新表。

也就是说索引数据和数据表是存放在不同的表中的,因此全局索引适用于多读少写的业务场景。 写数据的时候会消耗大量开销,因为索引表也要更新,而索引表是分布在不同的数据节点上的,跨节点的数据传输带来了较大的性能消耗。 在读数据的时候Phoenix会选择索引表来降低查询消耗的时间。

1.创建单个字段的全局索引

代码语言:javascript
复制
CREATE INDEX my_index ON my_table (my_col);

如果想查询的字段不是索引字段的话索引表不会被使用,也就是说不会带来查询速度的提升。

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

代码语言:javascript
复制
CREATE INDEX my_index ON my_table (v1) INCLUDE (v2);

3. 本地二级索引

Local Index适用于写操作频繁的场景。 索引数据和数据表的数据是存放在同一张表中(且是同一个Region),避免了在写操作的时候往不同服务器的索引表中写索引带来的额外开销。

代码语言:javascript
复制
CREATE LOCAL INDEX my_index ON my_table (my_column);

DBeaver连接

DBeaver中搜索phoenix

修改DBeaver配置

修改dbeaver.ini文件,增加如下内容

代码语言:javascript
复制
-vm
D:/Tools/Java/jdk1.8.0_102/bin

连接配置

连接属性

image-20221215135637569
image-20221215135637569

驱动属性中也添加

属性

代码语言:javascript
复制
phoenix.schema.isNamespaceMappingEnabled

代码语言:javascript
复制
true

自动下载的Jar版本较老

我们要引用对应版本的Jar

代码语言:javascript
复制
phoenix-client-hbase-2.1-5.1.2.jar

服务配置

如果报错

CATALOG is found but client does not have phoenix.schema.isNamespaceMappingEnabled enabled

查询

代码语言:javascript
复制
select * from SYSTEM."CATALOG";

查看表的 TABLE_SCHEM 发现有些表这个属性为空。 那么如果你没有指定自动映射命名空间,就会报错。

image-20221215130549298
image-20221215130549298

在 hbase 的 conf 目录下 hbase-site.xml 文件加入下面的属性:

代码语言:javascript
复制
<property>
   <name>phoenix.schema.isNamespaceMappingEnabled</name>
   <value>true</value>
</property>

然后,重启 hbase。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 下载与安装
  • 环境变量
  • 配置
  • 运行
  • 测试
  • Phoenix Shell操作
    • Schema的操作
      • 表的操作
        • 表的映射
        • Phoenix JDBC操作
          • Thin Client
            • Thick Client
            • Phoenix二级索引
              • 1. 二级索引配置文件
                • 2. 全局二级索引
                  • 3. 本地二级索引
                  • DBeaver连接
                    • 修改DBeaver配置
                      • 连接配置
                        • 服务配置
                        相关产品与服务
                        TDSQL MySQL 版
                        TDSQL MySQL 版(TDSQL for MySQL)是腾讯打造的一款分布式数据库产品,具备强一致高可用、全球部署架构、分布式水平扩展、高性能、企业级安全等特性,同时提供智能 DBA、自动化运营、监控告警等配套设施,为客户提供完整的分布式数据库解决方案。
                        领券
                        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档