相信很多在用CDP7的小伙伴都遇到了Spark里面不再支持spark-sql的问题
这里给出两种解决方案:spark-submit与spark-shell
cloudera官方给的解决方案
基于这个方案,这里提供两种通用方案
test.hql
CREATE DATABASE SPARK;
CREATE TABLE SPARK.TEST(ID INT, NAME STRING);
INSERT INTO SPARK.TEST VALUES(1,'Daniel');
SELECT
*
FROM SPARK.TEST;
-
spark-submit(推荐)
编写Scala代码来解决这个问题,这里以读取HDFS上的SQL为例
package sparksql import org.apache.spark.sql.{Encoders, SparkSession} import scala.collection.JavaConversions._ /** * @Author Daniel * @Description Spark运行HDFS上的SQL **/ object RunSparkSQL { def main(args: Array[String]): Unit = { if (args == null || args.length < 1) { println( """ |parameter errors! Usage: <SQL> |SQL: a spark sql command """.stripMargin ) System.exit(-1) } val spark = SparkSession.builder() // hive的配置 .config("hive.metastore.uris", "thrift://hadoop03:9083") .appName(RunSparkSQL.getClass.getSimpleName) .enableHiveSupport() .getOrCreate() /* 以spark.read的方式去读文本文件,会将文件读成一个表 表的话,就涉及到很多列,但这里为SQL,是没有多列的, 所以以一个不存在的分割符来切割,表示这里只需要一列 !!!如果是低版本的Spark只支持一个分隔符,改为option("sep", "@") */ val df = spark.read.option("sep", "@@@").csv(args(0)) // 将df里面数据的格式强制转换为String类型,将其转成一个集合 val rowList = df.as(Encoders.STRING).collectAsList var rows = "" // 添加空格,避免SQL连在一起产生语法错误 for (row <- rowList) { rows += " " + row } // 如果有多个SQL,以分号来分割 val sqlArr = rows.split(";") // 运行每一个SQL,注意这里要导入scala.collection.JavaConversions._才能进行遍历 for (s <- sqlArr) { // 显示完整结果 spark.sql(s).show(false) } spark.stop() } }
将代码打成jar包,上传到hdfs
hdfs dfs -put test.hql /hive_data hdfs dfs -put runsparksql.jar /hive_data/jars
然后编写Shell脚本
runspark.sh
spark-submit \ --class sparksql.RunSparkSQL \ --master local[*] \ --deploy-mode client \ --total-executor-cores 2 \ --executor-cores 1 \ --executor-memory 600M \ hdfs:///hive_data/jars/runsparksql.jar \ $1
运行脚本
bash runspark.sh hdfs:///hive_data/test.hql
结果
++ || ++ ++ ++ || ++ ++ ++ || ++ ++ +---+------+ |ID |NAME | +---+------+ |1 |Daniel| +---+------+
hive里面也可以查看
-
spark-shell
编写shell脚本来解决这个问题,在spark的bin目录下新建脚本
vi $SPARK_HOME/bin/spark2-sql
spark2-sql
#!/bin/bash if [[ $1 = "-e" ]];then sql=$2 elif [[ $1 = "-f" ]];then sql=`cat $2` else echo "Usage:" echo "--------------------------------------------------------" echo "spark2-sql.sh -f [SQL filename] : execute a sql file" echo "spark2-sql.sh -e [SQL] : execute a sql" echo "--------------------------------------------------------" fi if [[ ${sql} =~ ';' ]];then i=1 while((1==1)) do splitchar=`echo $sql|cut -d ";" -f$i` if [ "$splitchar" != "" ];then ((i++)) sparksql=${sparksql}"spark.sql(\"$splitchar\").show();" else break fi done else sparksql = "spark.sql(\"$sql\").show();" fi echo $sparksql echo ${sparksql} | spark-shell
直接运行即可,-e加具体sql,-f加文件(目前只支持Local的文件)
spark2-sql -e 'select current_timestamp;' spark2-sql test.hql