Spark进阶(六)

2 篇文章 0 订阅

SparkSQL 运行架构 && hive 的安装实践
这里写图片描述

TreeNode 体系

Logical Plans 、Expressions 、Physical Operators 都可以使用Tree 表示
– TreeNode 具备一些scala collection 的操作能力和树遍历能力,树的修改是以替换已有节点的方式进行的。
– TreeNode ,内部带一个children: Seq[BaseType] 表示孩子节点,具备foreach 、map 、collect 等针对节点操作的方法,以及transformDown 、transformUp 这样的遍历树上节点,对匹配节点实施变化的方法。
– 三种trait
● UnaryNode 一元节点,即只有一个孩子节
点。Linit 、Filter
● BinaryNode 二元节点,即有左右孩子的二叉节点。Jion 、Union
● LeafNode 叶子节点,没有孩子节点的节点。SetCommand

SqlParser

Sql 解析成Unresolved 逻辑计划(包含UnresolvedRelation 、 UnresolvedFunction 、UnresolvedAttribute )
● 对于命令,会生成一个叶子节点;
● 对于SQL 语句,由lexical 的Scanner来扫描输入,分词,校验,如果符合语法就生成LogicalPlan 语法树,不符合则会提示解析失败。

Analyzer

  • 流程是实例化一个SimpleAnalyzer ,定义一些Batch ,然后遍历这些Batch 在RuleExecutor 的环境下,执行Batch 里面的Rules ,每个Rule 会对Unresolved Logical Plan 进行Resolve ,有些可能不能一次解析出,需要多次迭代,直到达到max 迭代次数或者达到fix point 。
  • 比较常用的Rules 有ResolveReferences 、ResolveRelations 、StarExpansion 、GlobalAggregates 、typeCoercionRules 和liminateAnalysisOperators 。
  • ResolveRelations 、ResolveFunctions 等调用了catalog 这个对象。Catalog 对象里面维护了一个tableName,Logical Plan 的HashMap 结果。通过这个Catalog 目录来寻找当前表的结构,从而从中解析出这个表的字段。

Optimizer

  • 将Analyzed Logical Plan 经过对Logical Plan 和Expression 进行Rule 的应用transfrom ,从而达到树的节点进行合并和优化。
  • 其中主要的优化的策略总结起来是合并、列裁剪、过滤器下推几大类。对Logical Plan transfrom 的是先序遍历(pre-order) ,而对Expression transfrom的时候是后序遍历(post-order)
val query = sql("select * from (select * from temp_shengli limit 100)a limit 10 ")val query = sql("select 1+2+3+4 from temp_shengli")

整体运行过程

这里写图片描述
这里写图片描述

使用时直接调用。。。
RDD操作

package week4

import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.sql.SQLContext

case class Person(name: String, age: Int)

object SQLOnSpark {
  def main(args: Array[String]) {
    val conf = new SparkConf().setAppName("SQLOnSpark")
    val sc = new SparkContext(conf)

    val sqlContext = new SQLContext(sc)
    import sqlContext._

    val people: RDD[Person] = sc.textFile("hdfs://hadoop1:8000/dataguru/week4/people.txt")
      .map(_.split(",")).map(p => Person(p(0), p(1).trim.toInt))
    people.registerAsTable("people")

    val teenagers = sqlContext.sql("SELECT name FROM people WHERE age >= 10 and age <= 19")
    teenagers.map(t => "Name: " + t(0)).collect().foreach(println)

    sc.stop()
  }
}

这里写图片描述
运行结果:Name:Justin

package week4

import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.sql.hive.LocalHiveContext

object HiveOnSpark {
  case class Record(key: Int, value: String)

  def main(args: Array[String]) {
    val sparkConf = new SparkConf().setAppName("HiveFromSpark")
    val sc = new SparkContext(sparkConf)

    val hiveContext = new LocalHiveContext(sc)
    import hiveContext._

    hql("use saledata")
    hql("select c.theyear,count(distinct a.ordernumber),sum(b.amount) from tblStock a join tblStockDetail b on a.ordernumber=b.ordernumber join tbldate c on a.dateid=c.dateid group by c.theyear order by c.theyear")
      .collect().foreach(println)

    sc.stop()
  }
}
package week4

import java.sql.{Connection, DriverManager, ResultSet}

object MySQL_test {
  def main(args: Array[String]) {

    Class.forName("com.mysql.jdbc.Driver")
    val conn = DriverManager.getConnection("jdbc:mysql://hadoop3:3306/test", "hadoop", "hadoop")
    try {

      val statement = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY,ResultSet.CONCUR_UPDATABLE )
      val prep=conn.prepareStatement("insert into saledata (theyear,qty,amount) values (\"2003\",2,3)")
      prep.executeUpdate()
      val rs = statement.executeQuery("select theyear,qty,amount from saledata")
      while (rs.next) {
        val theyear = rs.getString("theyear")
        val qty = rs.getString("qty")
        println("theyear = %s, qtyname = %s".format(theyear, qty))
      }
    } catch {
      case e: Exception => e.printStackTrace
    }
    conn.close
  }
}

netstat -nlt 查看TCP端口
总规划:
远程模式搭建hive系统, 也就是采用Mysql作为元数据存储的数据库,并且把mysql安装在hadoop3上面,并且在slave2上面启动metastore service,然后在slave1或者物理机的客户端hadoop上安装hive客户端,然后启动hive来访问slave2的metastore service以访问实际存储在hadoop上的文件。

hive前提,hadoop+yarn启动。

salve上 mysql安装完后,执行如下操作

登录
[root@hadoop9 hadoop]# mysql -uroot -p 
//这个不需要
mysql> grant all on *.* to mysql@'%' identified by 'mysql' with grant option; 
创建用户名:hadoop,密码:hadoop
mysql> create user 'hadoop' identified by 'hadoop'; 

mysql> grant all on *.* to hadoop@'%' with grant option; 

mysql> quit;
//先退出后,以hadoop的用户名登录,再退出
[root@hadoop9 hadoop]# mysql -u hadoop -p 
mysql> create database hive; 
mysql> quit;

show databases;
use hive;
show tables;
exit;
ls -lsa

hive的安装:
同样模式,解压后+ 修改配置文件:
hive-site.xml hive-env.sh(需要在conf文件拷贝一份出来)
hive-env.sh:HADOOP_HOME

hive-site.xml :
修改为Jdbc的支持和mysql的驱动程序,以及连接的用户名和密码

<property> 
  <name>javax.jdo.option.ConnectionURL</name> 
  <value>jdbc:mysql://slave2:3306/hive?=createDatabaseIfNotExist=true</value> 
  <description>JDBC connect string for a JDBC metastore</description> 
</property> 
<property> 
  <name>javax.jdo.option.ConnectionDriverName</name> 
  <value>com.mysql.jdbc.Driver</value> 
  <description>Driver class name for a JDBC metastore</description> 
</property> 
<property> 
  <name>javax.jdo.option.ConnectionUserName</name> 
  <value>hadoop</value> 
  <description>username to use against metastore database</description> 
</property> 
<property> 
  <name>javax.jdo.option.ConnectionPassword</name> 
  <value>hadoop</value> 
  <description>password to use against metastore database</description> 
</property>

hive.metastore.warehouse.dir
hive的数据是loading,装载的目录,可选择性修改

别忘了拷贝驱动程序到hive/lib目录下

bin/hive 启动hive
show databases;

create tables aaa(aa string.bb int)
这时在缺省目录下 得到/user/hive/warehouse/aaa

show tables;

再打开一个slave2的端口,查看mysql的情况,可以看到现在有了表结构

select * from TBLS
看到有一个表名,即元数据已经放在aaa表里面了。

使用scp命令将slave2拷贝到slave1里。
注意意义,scp -r hive/ hadoop@slave1:…/
这时还无法在slave1中启动,因为还没有配置metasore的配置。
客户端忘记配置Urls,所以客户端slave1直接连接到mysql,而不是连接metasore中

修改slave1中的hive-site.xml:

<property>
  <name>hive.metastore.uris</name>
  <value>thrift://slave2:9083</value>
  <description>Thrift uri for the remote metastore. Used by metastore client to connect to remote metastore.</description>
</property>

作为一个前台服务来启动:

1.先启动slave2的metastore service
hive –service –help查看启动的服务
hive –service metastore(作为一个前台服务来启动的)
2.客户端就可以这样访问元数据,然后对存储在hadoop上的数据进行操作。
在slave1中启动hive,查看表;
3.退出:netstat -nlt 查看端口9083

作为一个后台服务来启动:
1.启动

nohup bin/hive --service metastore > metastore.log 2>&1 &

2.后台退出
.jobs(hive目录下)
kill %num(这里num由启动的【】中num决定)
3.slave1同样可以连接看到slave2中的表

(补充讲解):
metasotre
启动 start-dfs.sh start-yarn.sh

单用户使用hive
bin/hive

多用户使用hive
slave2 : bin/hive –service metastore
slave1 : bin/hive

再增加一个用户
在master(victory)中:使用scp命令将slave2拷贝到slave1里。注意意义,scp -r hive/ hadoop@slave1:…/
master(victory) : bin/hive

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值