• hbase查询基于标准sql规范中间件Phoenix


      

       Phoenix是个很好的hbase 查询工具,在hbase中安装也很简单,可以按照 http://www.cnblogs.com/laov/p/4137136.html 这个连接中进行配置客户端和服务端的Phoenix。

    PhoenixSQL有如下类:

    • 增删数据:ExecutableAddColumnStatement、ExecutableDropColumnStatement
    • 创建/删除表格:ExecutableCreateTableStatement、ExecutableDropTableStatement
    • Select操作:ExecutableSelectStatement
    • 导入数据:ExecutableUpsertStatement
    • 解释执行:ExecutableExplainStatement

          Phoenix架构和特点:

       Phoenix中SQL Query Plan的执行,基本上是通过构建一系列的Hbase scan来完成。为了尽可能减少数据传输,在Region Server使用Coprocessor来尽可能的执行Aggregate相关工作,基本思想是使用RegionObserver在PostScannerOpen hook中将RegionScanner替换成支持Aggregation工作的定制化的Scanner,具体的Aggregate操作通过custom的scan属性传递给RegionScanner。与基于MapReduce的框架执行Plan的思想比较,基本上就是通过Coprocessor,使用RegionServer自身来在各个节点上执行Aggregation。此外,通过各种定制的Filter在Hbase的RegionScanner scan过程中,尽早的将不相关的数据过滤掉。采用JDBC接口和应用程序交互。

           目前支持简单的表的创建,修改,数据删减,过滤,检索等SQL语法,从语法上看,不支持多表操作,本质上应该是由于不支持多表联合类的操作如各种Join等,所以在Where部分也就不能做多表的比较。由于Coprocessor 和 Filter自身能力的限制,如果完全不依赖Map Reduce框架,只通过HbaseClient API想要实现复杂的Query操作如多表联合操作,相对比较困难,或者大量工作需要在客户端代码中实现,性能上可能无法满足需求。

      执行查询时,在数据访问与运行时执行之间加上SQL这样一层抽象可以进行大量优化。比如说,对于GROUP BY查询来说,我们可以利用HBase中协同处理器这样的特性。借助于该特性,我们可以在HBase服务器上执行Phoenix代码。因此,聚合可以在服务端执行,而不必在客户端,这么做会极大减少客户端与服务端之间传输的数据量。此外,Phoenix还会在客户端并行执行GROUP BY,这是根据行键的范围来截断扫描而实现的。通过并行执行,结果会更快地返回。所有这些优化都无需用户参与,用户只需发出查询即可。

    优点:

    1:命令行和java客户端使用都很简单。尤其是java客户端直接面向JDBC接口编程,封装且优化了Hbase很多细节。 
    2:在单表操作上性能比Hive Handler好很多(但是handler也有可能会升级加入斜处理器相关聚合等特性) 
    3:支持多列的二级索引,列数不限。其中可变索引时列数越多写入速度越慢,不可变索引不影响写入速度(参考:  https://github.com/forcedotcom/phoenix/wiki/Secondary-Indexing#mutable-indexing)。 
    4:对Top-N查询速度远超Hive(参考:  https://github.com/forcedotcom/phoenix/wiki/Performance#top-n) 
    5:提供对rowkey分桶的特性,可以实现数据在各个region的均匀分布(参考:  https://github.com/forcedotcom/phoenix/wiki/Performance#salting) 
    6:低侵入性,基本对原Hbase的使用没什么影响 
    7:提供的函数基本都能cover住绝大多数需求了 
    8:与Hive不同的是,Phoenix的sql语句更接近标准sql规范。

      Phoenix的基本查询语法:

    select * from shuju;
    
    select count(1) from shuju;
    
    select cmtid,count(1) as num from shuju group by cmtid order by num desc;
    
    select avg(TO_NUMBER(avgt)) from shuju;
    
    select cmtid,count(1) as num,avg(TO_NUMBER(avgt)) as avgt,avg(TO_NUMBER(loss)) as loss from shuju group by cmtid order by num desc;
    
    select acm,dtype,cmtid,count(1) as num,avg(TO_NUMBER(avgt)) as avgt,avg(TO_NUMBER(loss)) as loss
    
    from shuju
    
    group by acm,dtype,cmtid
    
    order by num desc;
    
    select acm,dtype,porgcode,orgid,cmtid,count(1) as num,avg(TO_NUMBER(avgt)) as avgt,avg(TO_NUMBER(loss)) as loss
    
    from shuju
    
    group by acm,dtype,porgcode,orgid,cmtid
    
    order by num desc;
    
    where TO_DATE(ttime,'yyyyMMddHHmmss')=TO_DATE('20141125','yyyyMMdd')
    
    select ttime from shuju order by ttime desc;
    
     
    
    where TO_DATE(ttime,'yyyyMMddHHmmss')=TO_DATE('20141125','yyyyMMdd')
    
     
    
    select TO_DATE(ttime,'yyyyMMddHHmmss') from shuju;
    
    select TO_DATE('20141125','yyyyMMdd') from shuju;
    
    select (TO_DATE(ttime,'yyyyMMddHHmmss')=TO_DATE('20141125','yyyyMMdd')) as aaa from shuju order by aaa asc;

       java调用Phoenix的驱动例子:(Phoenix基本几乎标准sql规范)

      

    import java.sql.*;
    
    public class PhoenixJDBC {
    
     public static void main(String args[]) {
    
     try {
         //Register JDBC Driver
         Class.forName("org.apache.phoenix.jdbc.PhoenixDriver").newInstance();
    
         Connection conn = DriverManager.getConnection("jdbc:phoenix:54.152.31.122","","");
    
         //Create a Statement class to execute the SQL statement
         Statement stmt = conn.createStatement();
    
         //Execute the SQL statement and get the results in a Resultset
         ResultSet rs = stmt.executeQuery("select * from US_POPULATION");
    
         // Iterate through the ResultSet, displaying two values
         // for each row using the getString method
    
         while (rs.next())
             System.out.println("Name= " + rs.getString("host"));
     }
     catch (SQLException e) {
         e.printStackTrace();
     }
     catch (Exception e) {
         e.printStackTrace();
     }
     }
     }

     


      

  • 相关阅读:
    PRelu和一些激活函数
    一个编程入门参考网站
    GPT/Bert/Attention等一些总结
    [Go] struct
    [Typescript Challenges] 15. Medium Get return type of function
    [GO] Pass by reference
    [Go] Error
    [Go] Defer, panic, recover
    [Go] Method
    [Go] Pointer
  • 原文地址:https://www.cnblogs.com/rxingyue/p/5026743.html
Copyright © 2020-2023  润新知