本文介绍在计算机集群上如何启动和运行Shark。如果对Amazon EC2上运行Shark感兴趣,请点击这里查看如何使用EC2脚本快速启动预先配置好的集群。
依赖:
注意:Shark是一个即插即用的工具,所以可以在现有的Hive数据仓库之上运行,不需要您对现有的部署做出任何修改。
在集群上运行Shark需要一下几个外部组件:
Scala
如果系统里没有安装Scala 2.9.3,可以按提示下载:
$ wget http://www.scala-lang.org/downloads/distrib/files/scala-2.9.3.tgz
$ tar xvfz scala-2.9.3.tgz
Spark
采用Spark的单独部署模式运行Shark。
部署细节:|http://spark-project.org/docs/latest/spark-standalone.html).也可以查看我翻译的博文。
下载Spark:
$ wget http://spark-project.org/files/spark-0.7.2-prebuilt-hadoop1.tgz # Hadoop 1/CDH3
或者
$ wget http://spark-project.org/files/spark-0.7.2-prebuilt-cdh4.tgz # Hadoop 2/CDH4
解压缩:
$ tar xvfz spark-0.7.2-prebuilt*.tgz
编辑 spark-0.7.2/conf/slaves添加集群中Slaves的主机名称,每一行对应一个Salve。
编辑spark-0.7.2/conf/spark-env.sh设置SCALA_HOME和SPARK_WORKER_MEMORY
export SCALA_HOME=/path/to/scala-2.9.3
export SPARK_WORKER_MEMORY=16g
SPARK_WORKER_MEMORY 是Spark在每一个节点上可用内存的最大,增加这个数值可以在内存中缓存更多的数据,但是一定要记住给Slave的操作系统和其他服务预留足够的内存。
Shark
下载Shark 0.2.1发布包,里边包括 shark-0.2.1和hive-0.9.0-bin.
$ wget http://spark-project.org/download/shark-0.7.0-hadoop1-bin.tgz # Hadoop 1/CDH3
或者
$ wget http://spark-project.org/download/shark-0.7.0-hadoop2-bin.tgz # Hadoop 2/CDH4
解压缩:
$ tar xvfz shark-0.7.0-*-bin.tgz
编辑shark-0.7.0/conf/shark-env.sh设置HIVE_HOME, SCALA_HOME和MASTER环境变量(参考如下):
export HADOOP_HOME=/path/to/hadoop
export HIVE_HOME=/path/to/hive-0.9.0-bin
export MASTER=spark://<MASTER_IP>:7077
export SPARK_HOME=/path/to/spark
export SPARK_MEM=16g
source $SPARK_HOME/conf/spark-env.sh
(source命令通常用于重新执行刚修改的初始化文件,使之立即生效)
最后一行是为了避免重复设置SCALA_HOME。一定要确保SPARK_MEM的数值不能超过前面设置的SPARK_WORKER_MEMORY的数值.
如果是在现有的Hive上运行Shark,确定设置 HIVE_CONF_DIR (在shark-env.sh文件中)指向你的配置文件夹.也可以,复制 Hive XML配置文件到Shark的hive-0.9.0-bin/conf配置文件夹内,比如:
cp /etc/hive/conf/*.xml /path/to/hive-0.9.0-bin/conf/
复制 Spark和 Shark目录到所有的slaves.前提是master的用户可以实现无密码SSH登录到所有的slaves.例如:
$ while read slave_host; do
$ rsync -Pav spark-0.7.2 shark-0.7.0 $slave_host
$ done < /path/to/spark/conf/slaves
运行 Spark的集群启动脚本,启动集群:
$ cd spark-0.7.2
$ ./bin/start_all.sh
基于CDH4/Hadoop2配置Shark
The newest versions of require additional configuration options.
新版本的Hadoop需要额外的配置选项。在Hive的配置文件(hive-site.xml)中进行配置:
测试
使用如下命令,启动Shark
$ ./bin/shark-withinfo
关于Spark单独模式的更多脚本细节参考这里。
To verify that Shark is running, you can try the following example, which creates a table with sample data:
使用下面的命令,创建一个简单的表格就可以确认一下Shark是否可以运行。
CREATE TABLE src(key INT, value STRING);
LOAD DATA LOCAL INPATH '${env:HIVE_HOME}/examples/files/kv1.txt' INTO TABLE src;
SELECT COUNT(1) FROM src;
CREATE TABLE src_cached AS SELECT * FROM SRC;
SELECT COUNT(1) FROM src_cached;
更详细的学习Shark,可以查看官方网站的用户指南
Shark简介
Shark即Hive on Spark,本质上是通过Hive的HQL解析,把HQL翻译成Spark上的RDD操作,然后通过Hive的metadata获取数据库里的表信息,实际HDFS上的数据和文件,会由Shark获取并放到Spark上运算。Shark的特点就是快,完全兼容Hive,且可以在shell模式下使用rdd2sql()这样的API,把HQL得到的结果集,继续在scala环境下运算,支持自己编写简单的机器学习或简单分析处理函数,对HQL结果进一步分析计算。
Shark速度快的原因除了Spark平台提供的基于内存迭代计算外,在设计上还存在对Spark上进行了一定的改造,主要有
- partial DAG execution:对join优化,调节并行粒度,因为Spark本身的宽依赖和窄依赖会影响并行计算和速度
- 基于列的压缩和存储:把HQL表数据按列存,每列是一个array,存在JVM上,避免了JVM GC低效,而压缩和解压相关的技术是Yahoo!提供的
其他特性和设计要点请参看论文Shark: SQL and Rich Analytics at scale
总结来说,Shark是一个插件式的东西,在我现有的Spark和Hive及hadoop-client之间,在这两套都可用的情况下,Shark只要获取Hive的配置(还有metastore和exec等关键包),Spark的路径,Shark就能利用Hive和Spark,把HQL解析成RDD的转换,把数据取到Spark上运算和分析。在SQL on Hadoop这块,Shark有别于Impala,Stringer,而这些系统各有自己的设计思路,相对于对MR进行优化和改进的思路,Shark的思路更加简单明了些。
Shark部署
Shark Wiki上发布了两个主要版本,shark-0.7.0-hadoop1-bin.tgz和shark-0.7.0-hadoop2-bin.tgz。shark-0.7.0-hadoop1-bin.tgz适用于CDH3,shark-0.7.0-hadoop2-bin.tgz适用于CDH4,他们都使用hive-0.9.0进行了编译,使用的Spark是0.7.2的。相对来说,hive的版本比较老,想要支持0.11.0这样更新的版本的话需要自己重新编译Shark。在github上,现在Shark的master分支已经开始支持未发布的Spark0.8版本,编译注意的地方会在下一节讲。
Shark的部署参看https://github.com/amplab/shark/wiki/Running-Shark-on-a-Cluster和https://github.com/amplab/shark/wiki/Running-Shark-Locally。首先要选择适合自己Hadoop集群版本的shark-0.7.0-hadoopX-bin.tgz。
解压出来的hive-0.9.0配置在shark-env.sh的HIVE_HOME,同时还可以额外指定HIVE_CONF的目录,一般就指定自己已有的可以连接hadoop的hive conf目录。其余的SPARK_MEM, SPARK_HOME, SCALA_HOME就不说了。
用bin/shark-withinfo启动shark,可以看到INFO信息,shark首先启动自己的CLI,然后会启动Hive,再启动Spark,之后就可以用HQL测试Shark可用与否。
在配置好各个HOME后,如果跑在common hadoop上,当你进行select这样和HDFS数据打交道的操作时,会报如下的版本错误,
具体见Shark Group的这个帖。目前,我尝试了很多也没有找到解决办法,特别是像我用的hadoop-client还是公司自己改装过的,相对的Hive的几个主要jar包(hive-metastore-xx, hive-exec-xx)也被改动了,导致不但shark发布的包不能直接使用,连使用shark重新根据自己的hive编译一遍都编译不过。
最后再提醒几个可能发生的常见错误。
1. HIVE_HOME/lib下要有jdbc驱动包,比如mysql-driver的jar包,否则会报错。
2. HIVE_HOME/lib下的hive-metastore-xx.jar,可能太旧,不适应自己的hadoop集群,可以替换成自己的hive/lib下的metastore包,否则会报错,HQL执行不成功。替换后至少在执行use db; show tables; 这样的HQL没有问题。
3. 有一个错误是:
Shark编译
主要参考官方文档:https://github.com/amplab/shark/wiki/Building-Shark-from-Source-Code。在下载版本的时候,一定要注意下载配套的源码。我第一次编译的时候用了shark-master的源码,就编译失败了,因为它依赖Spark-0.8版本,而这版本还未发布。应该获取branch-0.7下的版本,
除了指定下SCALA_HOME和HIVE_HOME外,最好再指定下SPARK_HOME。最后sbt/sbt package,利用sbt进行打包,需要蛮长的时间。
我尝试了依赖公司的hive包编译,失败了,报了77个error,原因是Shark的源码里很多依赖于hive的接口,有些有,有些没有,所以我又尝试了依赖hive-0.9.0的包编译,成功了,没有报错。虽然我想尝试编译适合自己公司集群的shark失败了,但是我还是完成了这条路的探索。目前我如果想使用Shark的话,只能自己部一套CDH的hadoop和hive了。哎。