设为首页 加入收藏

TOP

spark on hive原理与环境搭建   spark研习第三季
2019-04-15 00:57:18 】 浏览:49
Tags:spark hive 原理 环境 搭建   研习 第三
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/refuil/article/details/52327632

SparkSQL前身是Shark,Shark强烈依赖于Hive。Spark原来没有做SQL多维度数据查询工具,后来开发了Shark,Shark依赖于Hive的解释引擎,部分在Spark中运行,还有一部分在Hadoop中运行。所以讲SparkSQL必须讲Hive。

一、spark on hive原理与搭建

1. hive的本质

1)Hive是分布式数据仓库,同时又是查询引擎,所以SparkSQL取代的只是Hives的查询引擎,在企业实际生产环境下,Hive+SparkSQL是目前最为经典的数据分析组合。

2)Hive本身就是一个简单单机版本的软件,主要负责:

A) 把HQL翻译成Mapper(s)-Reducer-Mapper(s)的代码,并且可能产生很多MapReduce的JOB。
B)把生成的MapReduce代码及相关资源打包成jar并发布到Hadoop集群中运行(这一切都是自动的)

3)Hive本身的架构如下所示:
hive架构

可以通过CLI(命令终端)、JDBC/ODBC、Web GUI访问Hive。
JavaEE或.net程序可以通过Hive处理,再把处理的结果展示给用户。
也可以直接通过Web页面操作Hive。
※ Hive本身只是一个单机版本的的软件,怎么访问HDFS的呢?
=> 在Hive用Table的方式插入数据、检索数据等,这就需要知道数据放在HDFS的什么地方以及什么地方属于什么数据,Metastore就是保存这些元数据信息的。Hive通过访问元数据信息再去访问HDFS上的数据。

可以看出HDFS不是一个真实的文件系统,是虚拟的,是逻辑上的,HDFS只是一套软件而已,它是管理不同机器上的数据的,所以需要NameNode去管理元数据。DataNode去管理数据。
Hive通过Metastore和NameNode打交道。

2. Hive安装和配置实战

Spark1.6.1中SparkSQL可以指定具体的Hive的版本。
1) 从apache官网下载hive-1.2.1,并解压到/home/richard目录。
http://mirrors.cnnic.cn/apache/hive/hive-1.2.1/
2) 配置.bashrc,追加以下内容,或者/etc/profile:

  1. export HIVE_HOME=/home/richard/hive-1.2.1
  2. export HIVE_CONF_DIR=/$HIVE_HOME/conf
  3. export PATH=$PATH:$HIVE_HOME/bin

3)进入/home/richard/hive-1.2.1/conf目录,生成hive-env.sh:

  1. cp hive-default.xml.template hive-site.xml

配置:

  1. export HADOOP_HOME=/opt/hadoop-2.6.0
  2. export HIVE_HOME=/opt/hive-1.2.1/
  3. export HIVE_CONF_DIR=/opt/hive-1.2.1/conf

Hive默认情况下放元数据的数据库是Derby,遗憾的是Derby是单用户,所以在生产环境下一般会采用支持多用户的数据库来进行MetaStore,且进行Master-Slaves主从读写分离和备份(一般Master节点负责写数据,Slaves节点负责读数据)。最常用的是MySQL。

cp hive-env.sh.template hive-env.sh
再生成hive-site.xml,并配置如下:

  1. <configuration>
  2. <!-- WARNING!!! This file is auto generated for documentation purposes ONLY! -->
  3. <!-- WARNING!!! Any changes you make to this file will be ignored by Hive. -->
  4. <!-- WARNING!!! You must make your changes in hive-site.xml instead. -->
  5. <!-- Hive Execution Parameters -->
  6. <property>
  7. <name>javax.jdo.option.ConnectionURL</name>
  8. <value>jdbc:mysql://master:3306/hivecreateDatabaseIfNotExist=true</value>
  9. <description>JDBC connect string for a JDBC metastore</description>
  10. </property>
  11. <property>
  12. <name>javax.jdo.option.ConnectionDriverName</name>
  13. <value>com.mysql.jdbc.Driver</value>
  14. <description>Driver class name for a JDBC metastore</description>
  15. </property>
  16. <property>
  17. <name>javax.jdo.option.ConnectionUserName</name>
  18. <value>root</value>
  19. <description>username to use against metastore database</description>
  20. </property>
  21. <property>
  22. <name>javax.jdo.option.ConnectionPassword</name>
  23. <value>778899..</value>
  24. <description>password to use against metastore database</description>
  25. </property>
  26. <property>
  27. <name>hive.metastore.warehouse.dir</name>
  28. <value>/user/hive/warehouse</value>
  29. <description>location of default database for the warehouse</description>
  30. </property>
  31. </configuration>

Hive中的DataBase和表其实就是HDFS上的目录和简单的文本文件。简单的文本文件中有几列数据,每列数据的类型无法直接从文本文件中得知。但当数据放入Hive中,Hive就把元数据放入Mysql中了,这样就可以基于数据的表进行查询了。

4) MYSQL的安装和配置
root用户下执行yum -y install mysql-server即可自动安装
执行rpm -qa mysql-server可以查看是否安装成功及安装的mysql版本。
参考redhat4.4.7如何安装mysql(非yum 安装)
http://blog.csdn.net/choice_jj/article/details/8827649
http://jingyan.baidu.com/article/1974b289acebd0f4b0f77469.html
设置密码问题:
http://blog.csdn.net/rogerzhanglijie/article/details/9182125

hive打开错误参考:

  1. 主要是按照《DT-大数据 hive1.2.1mysql作为元数据库搭建》文档

http://www.aboutyun.com/thread-11131-1-1.html

另外还需要下载驱动包(mysql-connector-java-5.1.35.tar.gz)将.jar文件放到这个目录下:

  1. cd /usr/local/hive/apache-hive-1.2.1/lib/

启动hive报错

  1. Logging initialized using configuration in jar:file:/opt/hive-1.2.1/lib/hive-common-1.2.1.jar!/hive-log4j.properties
  2. Exception in thread "main" java.lang.RuntimeException: java.lang.RuntimeException: Unable to instantiate org.apache.hadoop.hive.ql.metadata.SessionHiveMetaStoreClient
  3. Caused by: java.lang.RuntimeException: Unable to instantiate org.apache.hadoop.hive.ql.metadata.SessionHiveMetaStoreClient
  4. Caused by: java.lang.reflect.InvocationTargetException
  5. Caused by: javax.jdo.JDOFatalDataStoreException: Unable to open a test connection to the given database. JDBC url = jdbc:mysql://master:3306/hivecreateDatabaseIfNotExist=true, username = hive. Terminating connection pool (set lazyInit to true if you expect to start your database after
  6. ...
  1. root@master:/opt# netstat -tnlp | grep 3306
  2. tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN 5090/mysqld
  3. //mysql的监听IP应该是0.0.0.0
  4. //在vi /etc/mysql/my.cnf 中修改
  5. killall mysqld 后守护进程还会启动mysql,等于重启

另外报错:

  1. SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
  2. SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory]
  3. [ERROR] Terminal initialization failed; falling back to unsupported

原因是hadoop目录下存在老版本jline:
/hadoop-2.5.2/share/hadoop/yarn/lib:
-rw-r--r-- 1 root root 87325 Mar 10 18:10 jline-0.9.94.jar

解决方法是:

  1. hive下的新版本jlineJAR包拷贝到hadoop下:
  2. cp /hive/apache-hive-1.1.0-bin/lib/jline-2.12.jar ./

5) Hive的表有两种基本类型:一种是内部表(这种表数据属于Hive本身,即如果原来的数据在HDFS的其他地方,此时数据会通过HDFS移动到Hive所在目录,如果删除Hive中的该表的话数据和元数据均会被删除),一种是外部表(这种表数据不属于Hive数据仓库,元数据中会表达具体数据在哪里,使用时和内部表的使用一样,只是如果通过Hive去删除的话,删除的只是元数据,并没有删除数据本身)

6)Hive扩展(Hive的数据存储-转载)

Hive是基于Hadoop分布式文件系统的,它的数据存储在Hadoop分布式文件系统中。Hive本身是没有专门的数据存储格式,也没有为数据建立索引,只需要在创建表的时候告诉Hive数据中的列分隔符和行分隔符,Hive就可以解析数据。所以往Hive表里面导入数据只是简单的将数据移动到表所在的目录中(如果数据是在HDFS上;但如果数据是在本地文件系统中,那么是将数据复制到表所在的目录中)。

Hive中主要包含以下几种数据模型:Table(表),External Table(外部表),Partition(分区),Bucket(桶)(本博客会专门写几篇博文来介绍分区和桶)。

1、表:Hive中的表和关系型数据库中的表在概念上很类似,每个表在HDFS中都有相应的目录用来存储表的数据,这个目录可以通过${HIVE_HOME}/conf/hive-site.xml配置文件中的 hive.metastore.warehouse.dir属性来配置,这个属性默认的值是/user/hive/warehouse(这个目录在 HDFS上),我们可以根据实际的情况来修改这个配置。如果我有一个表wyp,那么在HDFS中会创建/user/hive/warehouse/wyp 目录(这里假定hive.metastore.warehouse.dir配置为/user/hive/warehouse);wyp表所有的数据都存放在这个目录中。这个例外是外部表。

2、外部表:外部表指向已经在HDFS中存在的数据,可以创建Partition。它和内部表在元数据的组织上是相同的,而实际数据的存储则有较大的差异。内部表的创建过程和数据加载过程这两个过程可以分别独立完成,也可以在同一个语句中完成,在加载数据的过程中,实际数据会被移动到数据仓库目录中;之后对数据对访问将会直接在数据仓库目录中完成。删除表时,表中的数据和元数据将会被同时删除。而外部表只有一个过程,加载数据和创建表同时完成(CREATE EXTERNAL TABLE ……LOCATION),实际数据是存储在LOCATION后面指定的 HDFS 路径中,并不会移动到数据仓库目录中。当删除一个External Table时,仅删除该链接。

3、分区:在Hive中,表的每一个分区对应表下的相应目录,所有分区的数据都是存储在对应的目录中。比如wyp 表有dt和city两个分区,则对应dt=20131218,city=BJ对应表的目录为/user/hive/warehouse /dt=20131218/city=BJ,所有属于这个分区的数据都存放在这个目录中。

4、桶:对指定的列计算其hash,根据hash值切分数据,目的是为了并行,每一个桶对应一个文件(注意和分区的区别)。比如将wyp表id列分散至16个桶中,首先对id列的值计算hash,对应hash值为0和16的数据存储的HDFS目录为:/user /hive/warehouse/wyp/part-00000;而hash值为2的数据存储的HDFS 目录为:/user/hive/warehouse/wyp/part-00002。如果想应用很多的Map任务这样是不错的选择。
Hive数据抽象结构图

3. 使用Hive分析搜索数据

参考:
http://lqding.blog.51cto.com/9123978/1751030

启动HDFS/Yarn。注意如果要使用Hive进行查询就需要启动Yarn。
启动Hive。
通过show databases;可以查看数据库。默认database只有default。
选取搜狗实验的三个数据源:http://download.labs.sogou.com/dl/q.html

  1. hadoop dfs -mkdir /library/sogou
  2. hadoop dfs -put ./SogouQ1.txt /library/sogou
  3. hadoop dfs -put ./SogouQ2.txt /library/sogou
  4. hadoop dfs -put ./SogouQ3.txt /library/sogou
  1. create table SogouQ3(ID STRING, WEBSESSION STRING, WORD STRING, S_SEQ INT, C_SEQ INT, WEBSITE STRING) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' LINES TERMINATED BY '\n'; //建表
  2. LOAD DATA INPATH '/library/sogou/SogouQ3.txt' OVERWRITE INTO TABLE SogouQ3; //加载数据

查询搜索排名第一,点击排名为第一的结果:
select count(*) from sogouq1 where S_SEQ=1 and C_SEQ=1;

搜索日志中,关注排名前五的内容,并且给出分别为多少次:
select WORD, count(WORD) as COUNTWord from SogouQ1 group by WORD order by COUNTWord desc limit 5

查询例子mysql

mysql -u root -p

  1. creeate database hive;
  2. use hive;
  3. create table person(name String,age int);
  4. insert into person values(‘richard’,’34’);
  5. select * from person;即可查询。

到此不需要启动spark,只需要启动HDFS。

4. Spark SQL on Hive配置及实战

1)spark on hive 配置

  1. 切换到spar的conf目录下使用vi hive-site.xml创建hive-site.xml.并填写如下内容
  1. <configuration>
  2. <property>
  3. <name>hive.metastore.uris</name>
  4. <value>thrift://master:9083</value>
  5. <description>thrift URI for the remote metastore.Used by metastore client to connect to remote metastore. </description>
  6. </property>
  7. </configuration>

因为用sparksql操作hive实际上是把hive 当做数据仓库。数据仓库肯定有元数据和数据本身。要访问真正的数据就要访问他的元数据。所以只需要配置hive.metastore.uris即可。(不需在每台机器上配置)

2)启动集群

  1. 启动dfs 服务start-dfs.sh
  2. 启动hive 数据仓库服务 hive --service metastore >metastore.log 2>& 1&
  3. 启动spark服务start-all.sh
  4. 启动sparkshell ./spark-shell –master spark://master:7077

3)案例实战

  1. Spark on hive 实战在spark-shell 模式下
  1. val hiveContext= new org.apache.spark.sql.hive.HiveContext(sc)
  2. hiveContext.sql("use hive") //使用hive 数据库
  3. hiveContext.sql("show tables").collect.foreach(println) // 查询数据库中的表
  4. hiveContext.sql("select count(*) from sogouq1").collect.foreach(println)//(注意此时使用的是spark的引擎)
  5. hiveContext.sql(“select count(*) from sogouq2 where website like '%baidu%'”).collect.foreach(println)
  6. hiveContext.sql(“select count(*) from sogouq2 where s_seq=1 and c_seq=1 and website like '%baidu%'”).collect.foreach(println)
  1. 不基于hive 的实战代码,在spark-shell 模式下
  1. scala> sqlContext
  2. res8: org.apache.spark.sql.SQLContext = org.apache.spark.sql.hive.HiveContext@35920655(可以创建很多hiveContexthivecongtext连接的是数据仓库,程序本身(spark中的job),job在程序中并行运行,如果都hive的数据,如果用句柄,对句柄的占用比较麻烦,所有用多个实例。从查询的角度来说,有多个实例也很正常)
  3. val df =sqlcontext.read.json(“library/examples/src/main/resources/people.json”) //读取json 数据
  4. df.show()
  5. df.printSchema
  6. df.select(“name”).show()
  7. df.select(df(“name”),df(“age”)+1).show()
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Sqoop   ------- 将mysql的.. 下一篇MetaException(message:Hive Sche..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目