cindysz110 / blog

8 stars 1 forks source link

[Hadoop] 使用Spark SQL来访问Hive里面的数据 #39

Open cindygl opened 6 years ago

cindygl commented 6 years ago

1. 环境准备

2. Spark SQL使用交互式命令行来访问Hive表

2.1 使用spark-shell交互式命令行连接hive

[hadoop@hadoop000 ~]$ spark-shell --master local[2] --jars ~/software/mysql-connector-java-5.1.46/mysql-connector-java-5.1.46.jar

使用Spark SQL的API调用Hive的命令,把结果展示出来

scala> spark.sql("show tables").show(false)
scala> spark.sql("select * from hive.emp").show(false)
scala> spark.sql("select * from hive.dept").show(false)
scala> spark.sql("select a.empno,a.name,b.dname from hive.emp a join hive.dept b on a.depno = b.deptno").show(false)

对比之下,Spark SQL对hive表做join查询时执行效率比HiveQL高很多。

2.2 使用spark-sql交互式命令行来连接hive

# 这里的--jars也可以不带
[hadoop@hadoop000 ~]$ spark-sql --master local[2] --jars ~/software/mysql-connector-java-5.1.46/mysql-connector-java-5.1.46.jar --driver-class-path ~/software/mysql-connector-java-5.1.46/mysql-connector-java-5.1.46.jar

使用Spark SQL的API调用hive命令,把结果展示出来。这里的命令跟HiveQL一模一样。

spark-sql> select * from hive.emp;
spark-sql> select * from hive.dept;
spark-sql> select a.empno,a.name,b.dname from hive.emp a join hive.dept b on a.depno = b.deptno;

Spark的Web UI右上角的显示会随着连接方式的改变而改变。 image

3. Spark SQL通过JDBC/ODBC连接HiveServer2来访问Hive里面的数据

启动一个Spark ThriftServer,ThriftServer就对应Hive里面的HiveServer2。

[hadoop@hadoop000 ~]$ app/spark/sbin/start-thriftserver.sh --master local[2] --jars ~/software/mysql-connector-java-5.1.46/mysql-connector-java-5.1.46.jar

从启动日志可以看到,服务端口号为10000

18/08/31 09:05:22 INFO ThriftCLIService: Starting ThriftBinaryCLIService on port 10000 with 5...500 worker threads

启动成功之后通过Spark Web UI (http://192.168.1.8:4040/jobs)可以看到启动的状态(如果4040被占用,它会启动在4041端口)。此时我们可以通过spark beeline客户端来连接它。

beeline -u jdbc:hive2://192.168.1.8:10000 -n hadoop
select * from hive.emp;

特别注意:如果机器上面既装了spark又装了hive,要区分开启动的是spark的beeline还是hive的beeline。

除此之外,也可以通过IDEA编程,使用JDBC/ODBC来连接Spark ThriftServer。

pom.xml添加hive依赖

    <dependency>
      <groupId>org.apache.hive</groupId>
      <artifactId>hive-jdbc</artifactId>
      <version>1.1.0-cdh5.7.0</version>
    </dependency>

SparkSQLClientApp.scala

/**
  * 使用JDBC连接Spark SQL
  */

package com.data.sparksql.d1

import java.sql.DriverManager

object SparkSQLClientApp {

  def main(args: Array[String]): Unit = {

    Class.forName("org.apache.hive.jdbc.HiveDriver")

    // JDBC连接时,用户名写hadoop,密码不用写
    val conn = DriverManager.getConnection("jdbc:hive2://10.132.37.38:10000","hadoop","")
    val stmt = conn.prepareStatement("select product_id,product_name from product_info limit 3")
    val rs = stmt.executeQuery()
    while (rs.next()) {
      println("product_id:" + rs.getInt("product_id") + " product_name:" + rs.getString("product_name"))
    }
    rs.close()
    stmt.close()
    conn.close()
  }

}


思考:ThriftServer和spark-shell或者spark-sql的区别在哪? 我们的ThriftServer也是一个Application,ThriftServer启动后服务7*24小时一直运行。其他应用可以以JDBC/ODBC的方式去访问它。这样减少了服务每次启动时带来的资源消耗和时间成本。 工作中我们经常也需要把自己的application封装成一个http服务,服务启动时一次性请求资源,客户端调用服务时一个http请求就可以把结果拿回来,不用去重复申请资源(HUE,Zeeplin都是以这样的一种方式来运行的)。