Phoenix简介及操作

时间:2024-03-07 12:58:07

1.什么是Phoenix

  Phoenix是构建在HBase上的一个SQL层,能让我们用标椎的JDBC APIs而不是HBase客户端APIs来创建表,插入数据和对HBase数据进程查询;

  Phoenix完全使用java编写,作为HBase内嵌的JDBC驱动,Phoenix查询引擎会将SQL查询转换为一个或多个HBase扫描(Scan),并编排执行以生成标椎的JDBC结果集;直接使用HBase API协同处理器自定义过滤器,对于简单查询来说,其性能量级是毫秒,对于百万级的行数来说,其性能量级是秒;

2.Phoenix安装

  2.1 下载Phoenix

    http://phoenix.apache.org/download.html

    

  2.2 上传并解压文件

    

  2.3 将Phoenix安装目录下的两个jar包copy到hbase的lib目录下(三台机器都需要)

    

  2.4 将hbase-site.xml文件copy到Phoenix的bin目录下,完成覆盖   

cd /opt/module/hbase/conf
cp hbase-site.xml /opt/module/phoenix/bin/

    

    

  2.5 重启hbase服务,开启Phoenix服务

bin/sqlline.py hadoop102:2181   

3.Phoenix测试

  使用!table查看生成的元数据表:

    

  使用!help查看Phoenix的用法

  使用!exit退出Phoenix

  3.1 创建数据表并导入数据

    3.1.1 在Phoenix的bin目录下,执行该语句:

      使用Phoenix自带的sql脚本文件

./psql.py localhost:2181 ../examples/WEB_STAT.sql

      

    3.1.2 再导入指定的数据:

      -t 后携带的是表名,CSV是数据文件

./psql.py -t WEB_STAT localhost:2181 ../examples/WEB_STAT.csv

  3.2 查询数据

    3.2.1 进入Phoenix命令行,执行!table查看已经创建的表:

      

    3.2.2 检索该表记录条数:

select count(1) from web_stat;

      

    3.2.3 按照domain域名进行分组查询:

select domain,count(1) as number from web_stat group by domain order by number;

      

  3.3 插入表数据

    3.3.1 创建新的数据表 

create table us_population(state varchar(2),city varchar(15),population bigint,constraint pk primary key(state,city));

      

    3.3.2 插入/更新数据

upsert into us_population(state,city,population) values(\'NY\',\'New York\',8143197);
upsert into us_population(state,city,population) values(\'NY\',\'New York\',8143197);  
upsert into us_population(state,city,population) values(\'CA\',\'Los Angeles\',3844829); 
upsert into us_population(state,city,population) values(\'IL\',\'Chicago\',2842518);
upsert into us_population(state,city,population) values(\'TX\',\'Houston\',2016582);
upsert into us_population(state,city,population) values(\'PA\',\'Philadelphia\',1463281);  
upsert into us_population(state,city,population) values(\'AZ\',\'Phoenix\',1461575);
upsert into us_population(state,city,population) values(\'TX\',\'San Antonio\',1256509);  
upsert into us_population(state,city,population) values(\'CA\',\'San Diego\',1255540);
upsert into us_population(state,city,population) values(\'TX\',\'Dallas\',1213825);
upsert into us_population(state,city,population) values(\'CA\',\'San Jose\',912332);

      

  3.4 修改表数据

upsert into us_population(state,city,population) values(\'AZ\',\'Phoenix\',1500000);

      

  3.5 删除表数据

delete from us_population where state=\'NY\';

      

  3.6 创建带列族的数据表

    3.6.1 创建新数据表

create table us_population2("state" varchar(2),"city" varchar(15),"info"."population" bigint,constraint pk primary key("state","city"));

      

    3.6.2 新增数据

upsert into us_population2("state","city","info"."population") values(\'BY\',\'shanghai\',8143197);

      

      利用Phoenix查询hbase时,返回结果中无法区分字段的列族,当不同列族下存在相同名称的字段时,会产生异常(在hbase的不同列族中,不要出现相同的列名字段);

  3.7 Phoenix的表映射

    默认情况下,在hbase中创建的表在Phoenix中是看不到的;

    在hbase的shell命令行中新建表

create \'HBASE_PHONEIX\',\'grade\'

    插入数据

put \'HBASE_PHONEIX\',\'001\',\'grade:name\',\'BigData\'
put \'HBASE_PHONEIX\',\'001\',\'grade:classname\',\'B01\'

    如果在Phoenix中操作由hbase创建的数据表,则需要在Phoenix中进行表的映射;

    映射的方式有两种:视图映射和表映射;

    3.7.1 视图映射

      在Phoenix的4.10版本之后,推荐使用基于视图的方式映射到hbase上的数据;仅提供高速检索与查询功能;删除视图也不会影响hbase上的数据;

      删除视图上的数据会出现Error:ERROR 505 (4200):Table is read only这样的异常;

      创建视图:

create view "HBASE_PHONEIX"("row" varchar primary key,"grade"."classname" varchar,"grade"."name" varchar);  
select * from HBASE_PHONEIX;

      

    3.7.2 表映射

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

        1.当hbase中表已存在,创建用名表和结构即可;

        2.当hbase中不存在,可以直接使用create table指令创建需要的表,并且在创建指令中可以根据需要对hbase表结构进行显示的说明;

        3.Phoenix的主键名称不需要和hbase中相同,两边通过表格内置结构可以自动关联起来,因为表格自动识别主键;

        4.Phoenix中的column必须以hbase的columnFamily开头;

      在Phoenix中创建映射表:必须需要禁用表的映射规则,这样做会降低检索性能;

create table "HBASE_PHONEIX"("row" varchar primary key,"grade"."classname" varchar,"grade"."name" varchar)column_encodeed_bytes=0;  

  3.8 使用JDBC

    3.8.1 开发准备,从集群中copy以下文件:

      core-site.xml,hbase-site.xml,hdfs-site.xml文件放置在项目的resource目录下;

      

    3.8.2 导入依赖   

<dependency>
  <groupId>org.apache.phoenix</groupId>
  <artifactId>phoenix-core</artifactId>
  <version>4.14.3-HBase-1.4</version>
</dependency>

    3.8.3 打开连接

    private  static Connection conn=null;
    private static Statement statement=null;

    /*打开连接*/
    static {
        try {
            Class.forName("org.apache.phoenix.jdbc.PhoenixDriver");
            //这里配置zookeeper地址,可单个,也可多个,可以是域名或者ip
            String url="jdbc:phoenix:hadoop102:2181/hbase";
            conn= DriverManager.getConnection(url);
            statement=conn.createStatement();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    3.8.4 创建数据表

    /*创建数据表*/
    public static void testCreateTable(String tableName) throws SQLException {
        String sql="create table "+tableName+" (mykey integer not null primary key,mycolumn varchar)";
        statement.executeUpdate(sql);
        conn.commit();
        System.out.println("创建数据表成功!");
        conn.close();
        statement.close();
    }
    public static void main(String[] args) throws SQLException {
        testCreateTable("wn");    //创建数据表
    }

      

    3.8.5 单条插入数据

    /*单条插入数据*/
    public static void testUpsert() throws SQLException {
        String sql1="upsert into wn values(1,\'test1\')";
        String sql2="upsert into wn values(2,\'test2\')";
        String sql3="upsert into wn values(3,\'test3\')";
        statement.executeUpdate(sql1);
        statement.executeUpdate(sql2);
        statement.executeUpdate(sql3);
        conn.commit();
        System.out.println("数据已插入!");
        conn.close();
        statement.close();
    }
    public static void main(String[] args) throws SQLException {
        testUpsert();   //单条插入数据
    }

      

    3.8.6 删除数据

    /*删除数据*/
    public static void testDelete(String tableName) throws SQLException {
        String sql="delete from "+tableName+" where mykey=3";
        statement.executeUpdate(sql);
        conn.commit();
        System.out.println("删除数据成功!");
        conn.close();
        statement.close();
    }
    public static void main(String[] args) throws SQLException {
        testDelete("wn");   //删除数据
    }

      

    3.8.7 检索数据表中的记录

    /*检索数据表中的记录*/
    public static void testReadAll() throws SQLException {
        String sql="select * from wn";
        long time=System.currentTimeMillis();
        ResultSet rs = statement.executeQuery(sql);
        conn.commit();
        while (rs.next()){
            //获取字段值
            int mykey = rs.getInt("mykey");
            //获取字段值
            String mycolumn = rs.getString("mycolumn");
            System.out.println("mykey:"+mykey+"\t"+"mycolumn:"+mycolumn);
        }
        rs.close();
        conn.close();
        statement.close();
    }
    public static void main(String[] args) throws SQLException {
        testReadAll();  //检索数据表中记录
    }