加入收藏 | 设为首页 | 会员中心 | 我要投稿 核心网 (https://www.hxwgxz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 建站 > 正文

Hive 如何快速拉取大批量数据

发布时间:2020-11-06 10:48:29 所属栏目:建站 来源:网络整理
导读:用hive来做数仓类操作,或者大数据的运算,是没有疑问的,至少在你没有更多选择之前。 当我们要hive来做类似于大批量数据的select时,也许问题就会发生了变化。 1. 通用解决方案之分页 首先,我们要基于一个事实,就是没有哪个数据库可以无限制的提供我们s
副标题[/!--empirenews.page--]

用hive来做数仓类操作,或者大数据的运算,是没有疑问的,至少在你没有更多选择之前。

当我们要hive来做类似于大批量数据的select时,也许问题就会发生了变化。

 

1. 通用解决方案之分页

首先,我们要基于一个事实,就是没有哪个数据库可以无限制的提供我们select任意数据量的数据。比如常用的 mysql, oracle, 一般你select 10w左右的数据量时已经非常厉害了。而我们的解决方法也比较简单,那就是分页获取,比如我一页取1w条,直到取完为止。同样,因为hive基于都支持sql92协议,所以你也可以同样的方案去解决大数据量的问题。

分页的解决方案会有什么问题?首先,我们要明白分页是如何完成的,首先数据库server会根据条件运算出所有或部分符合条件的数据(取决是否有额外的排序),然后再根据分页偏移信息,获取相应的数据。所以,一次次的分页,则必定涉及到一次次的数据运算。这在小数据量的情况下是可以接受的,因为计算机的高速运转能力。但是当数据量大到一定程序时,就不行了。比如我们停滞了许多年的大数据领域解决方案就是很好的证明。

本文基于hive处理数据,也就是说数据量自然也是大到了一定的级别,那么用分页也许就不好解决问题了。比如,单次地运算也许就是3-5分钟(基于分布式并行计算系统能力),当你要select 100w数据时,如果用一页1w的运算,那么就是100次来回,1次3-5分钟,100次就是5-8小时的时间,这就完全jj了。谁能等这么长时间?这样处理的最终结果就是,业务被砍掉,等着财务结账了。

所以,我们得改变点什么!

2. 使用hive-jdbc

jdbc本身不算啥,只是一个连接协议。但它的好处在于,可以维持长连接。这个连接有个好处,就是server可以随时输出数据,而client端则可以随时处理数据。这就给了我们一个机会,即比如100w的数据运算好之后,server只需源源不断的输出结果,而client端则源源不断地接收处理数据。

所以,我们解决方案是,基于hive-jdbc, 不使用分页,而全量获取数据即可。这给我们带来莫大的好处,即一次运算即可。比如1次运算3-5分钟,那么总共的运算也就是3-5分钟。

看起来不错,解决了重复运算的问题。好似万事大吉了。

具体实现就是引入几个hive-jdbc的依赖,然后提交查询,依次获取结果即可。样例如下:

 

      org.apache.hive     hive-jdbc     2.3.4   --  // 测试hive-jdbc import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement;  import java.sql.DriverManager;   public class HiveJdbcTest {     private static Connection conn = getConnnection();     private static PreparedStatement ps;     private static ResultSet rs;     // 获取所有数据     public static void getAll(String tablename) {         String sql="select * from " + tablename;         System.out.println(sql);         try {             ps = prepare(conn, sql);             rs = ps.executeQuery();             int columns = rs.getMetaData().getColumnCount();             while(rs.next()) {                 for(int i=1;i<=columns;i++) {                     System.out.print(rs.getString(i));                       System.out.print(" ");                 }                 System.out.println();             }         }          catch (SQLException e) {             e.printStackTrace();         }       }     // 测试     public static void main(String[] args) {          String tablename="t1";         HiveJdbcTest.getAll(tablename);     }       private static String driverName = "org.apache.hive.jdbc.HiveDriver";     private static String url = "jdbc:hive2://127.0.0.1:10000/";     private static Connection conn;     // 连接hive库     public static Connection getConnnection() {         try {             Class.forName(driverName);             conn = DriverManager.getConnection(url, "hive", "123");         }         catch(ClassNotFoundException e) {             e.printStackTrace();         }         catch (SQLException e) {             e.printStackTrace();         }         return conn;     }     public static PreparedStatement prepare(Connection conn, String sql) {         PreparedStatement ps = null;         try {             ps = conn.prepareStatement(sql);         }          catch (SQLException e) {             e.printStackTrace();         }         return ps;     } } 

样例代码,无需纠结。简单的jdbc操作样板。总体来说就是,不带分页的接收全量数据。

(编辑:核心网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读