Spark SQL 简单使用

来源:互联网 发布:淘宝鞋店推荐 编辑:程序博客网 时间:2024/06/04 18:08

环境:scala 版本2.11.8,spark 版本2.0.1,使用 Intellij IDEA 来开发。
准备工作:

创建maven项目

可以从官网上找到我们建项目时使用的 archetype
这里写图片描述
至于具体怎么创建项目,请参考一个朋友的文章Intellij IDEA 创建 spark/scala 项目
这个是前一段时间发现的一个朋友,强烈推荐大家去转转。
好了,这样一来就默认大家创建好了项目…

1 第一个例子

1.1 创建 SparkSession

这里写图片描述
官方文档如是说。
那么我们可以按照这个例子来写。

import org.apache.spark.sql.SparkSessionval spark = SparkSession            .builder()            .appName("sql test")            .master("local")            .getOrCreate()import spark.implicits._            

1.2 创建 DataFrames

这里写图片描述

//创建dataframeval df = spark.read.json("C:\\Users\\Administrator\\Desktop\\people.json")df.show()// +----+-------+// | age|   name|// +----+-------+// |null|Michael|// |  30|   Andy|// |  19| Justin|// +----+-------+

就像官网写的那样,我们可以调用 show() 方法来打印出 df 的数据。这里我是把官网上的示例给放到了指定的目录。当然,我们也可以自己创建一个 json 文件,格式如下:

{"name":"Signal"}{"name":"May j Lee","age":20}{"name":"Jay Chou","age":36}{"name":"Jack Chen","age":60}

当然,还有一些其他操作,我就不一一敲了,官网上给出的示例非常详细。用到类似的了就去官网上查…
这里写图片描述

我们还可以使用 SQL 语句来操作:
这里写图片描述

不过在我们使用 SQL 进行操作之前,需要使用 createOrReplaceTempView() 方法,熟悉 SQL 语句人肯定都知道”视图(view)“,接下来这个就是我们要操作的对象。

df.createOrReplaceTempView("people")val sqlDF = spark.sql("select * from people")sqlDF.show()

2 第二个例子

在第一个例子中,我们是根据一个 json 文件进行了一系列的操作,接下来我们是不是可以创建一个呢?

这里我们需要使用到的对象是 DataSets

2.1 创建 DataSets

这里写图片描述

我们还是参照官网的例子来写:

def createDataSetsTest(spark:SparkSession): Unit ={  import spark.implicits._  //创建 DataSet  val caseClassDS = Seq(Person("Jack",80),Person("Rose",76)).toDS()  caseClassDS.show()  //保存  caseClassDS.write.mode(SaveMode.Overwrite).json("C:\\Users\\Administrator\\Desktop\\SIGNAL-TEMP\\person.json")  val primitiveDS = Seq(1,2,3).toDS()  val ds = primitiveDS.map(_+1).collect()  ds.foreach(println)  val path = "C:\\Users\\Administrator\\Desktop\\SIGNAL-TEMP\\person.json"  val personDS = spark.read.json(path).as[Person]  personDS.show()}

接下我们可以调用这个 createDataSets(…) 来看看到底发生了些什么事情。

object SqlJson {  case class Person(name:String,age:Long)  def main(args: Array[String]) {    val spark = SparkSession.builder().appName("spark json").master("local").getOrCreate()    import spark.implicits._    createDataFrameTest(spark)  }}  

这里写图片描述

于是就像图片上那样,我们成功保存了 json 对象,并且我们还将它输出到了控制台。

这里写图片描述

这里大家可能疑惑的就是 SavaMode 了,别担心,官网有:
这里写图片描述

说起来保存,我们还可以保存为 parquet。
这里写图片描述

...//保存df.write.mode(SaveMode.Overwrite).parquet("C:\\Users\\Administrator\\Desktop\\SIGNAL-TEMP\\sparkSql.parquet")//读取val parquetFile = spark.read.parquet("C:\\Users\\Administrator\\Desktop\\SIGNAL-TEMP\\sparkSql.parquet")parquetFile.where($"key"===1).select($"key",$"value".as("v")).collect().foreach(println)

同样的,会在我们指定的路径下新建一个文件夹:
这里写图片描述

但是对于这个文件就没有那么友好了,我们看不懂^@^

3 Spark 与 Hive

我们可以通过 Spark 在 Hive 中创建一张表,并且导入数据。
这次我们需要将代码打成 jar 包,放到集群下去运行。

package spark.connectimport org.apache.spark.sql.SparkSession/**  * Created by SIGNAL on 2016/11/28.  */object HiveTest {  val spark = SparkSession.builder().appName("Spark connect to Hive").enableHiveSupport().getOrCreate()  def main(args: Array[String]) {    import spark.implicits._    import spark.sql    val createTable = "create table if not exists spark_hive_test(col1 int,col2 string,col3 string) row format delimited fields terminated by '|'"    spark.sql(createTable)    sql("load data local inpath '/home/signal/spark_hive_test.txt' overwrite into table spark_hive_test")    val df = sql("select * from spark_hive_test")    df.show()    spark.stop()  }}

Intellij IDEA 打 jar 包比较麻烦,不如 Eclipse 来的顺溜。
Ctrl + Alt + Shift + s 之后,出现 Project Structure,然后如图,然后自己倒腾…
这里写图片描述

…于是经过一番折腾之后,我以为大家 jar 包打好了。
然后我们可以发送到Linux上,方便操作就放到 master 节点上的 /homa/signal 目录下了:
这里写图片描述

大家还记得 hive 的建表语法吧,记得我们在建表时指定的分割符是什么不?
这里写图片描述

可以看到我们指定的分割符是”|“,而且,导入到 hive 中的时候我们指定了文件名和文件的路径,也就我们当前所在的 /home/signal,接下来我们需要在 /home/siganl 目录下创建一个 spark_hive_test.txt 的文件,文件格式如下:

[root@master signal]# vi spark_hive_test.txt 4|Signal|male5|Kevin|male6|Max|female"spark_hive_test.txt" 3L, 40C written[root@master signal]# 

这一系列操作完了之后,我们就可以运行 spark-submit 了。但是,我们需要确保的是 Mysql 的服务是启动的。

[root@master signal]# service mysql status SUCCESS! MySQL running (1678)[root@master signal]# 

那么我们就”提交“吧:
这里写图片描述

[root@master signal]# spark-submit --class spark.connect.HiveTest --master[1] SparkHive.jar...+----+------+------+|col1|  col2|  col3|+----+------+------+|   4|Signal|  male||   5| Kevin|  male||   6|   Max|female|+----+------+------+16/11/28 19:46:35 INFO SparkUI: Stopped Spark web UI at http://192.168.38.129:404016/11/28 19:46:35 INFO MapOutputTrackerMasterEndpoint: MapOutputTrackerMasterEndpoint stopped!16/11/28 19:46:35 INFO MemoryStore: MemoryStore cleared16/11/28 19:46:35 INFO BlockManager: BlockManager stopped16/11/28 19:46:35 INFO BlockManagerMaster: BlockManagerMaster stopped16/11/28 19:46:35 INFO OutputCommitCoordinator$OutputCommitCoordinatorEndpoint: OutputCommitCoordinator stopped!16/11/28 19:46:35 INFO SparkContext: Successfully stopped SparkContext16/11/28 19:46:35 INFO ShutdownHookManager: Shutdown hook called16/11/28 19:46:35 INFO ShutdownHookManager: Deleting directory /tmp/spark-59c859cc-611b-4aac-adce-567eb8376ffa[root@master signal]# 

控制台是正常输出了,我们可以到 Hive 中看看是否真的创建成功了。
启动 hiveserver2,然后使用 beeline 访问:

[root@master bin]# hiveserver2 & > /dev/null 2>&1 [1] 7712[root@master bin]# beeline -u jdbc:hive2://master:10000 -n root...Connected to: Apache Hive (version 2.1.0)Driver: Hive JDBC (version 2.1.0)16/11/28 19:56:12 [main]: WARN jdbc.HiveConnection: Request to set autoCommit to false; Hive does not support autoCommit=false.Transaction isolation: TRANSACTION_REPEATABLE_READBeeline version 2.1.0 by Apache Hive0: jdbc:hive2://master:10000>

这里写图片描述

我们可以看到,在 default 下是有 spark_hive_test 这张表的。

0: jdbc:hive2://master:10000> use default;OKNo rows affected (0.243 seconds)0: jdbc:hive2://master:10000> select * from spark_hive_test;OK+-----------------------+-----------------------+-----------------------+--+| spark_hive_test.col1  | spark_hive_test.col2  | spark_hive_test.col3  |+-----------------------+-----------------------+-----------------------+--+| 4                     | Signal                | male                  || 5                     | Kevin                 | male                  || 6                     | Max                   | female                |+-----------------------+-----------------------+-----------------------+--+3 rows selected (2.319 seconds)0: jdbc:hive2://master:10000> 

真的就像我们在控制台里看到的那样,我们的hive中有了那张表,并且数据也加载进去了。

4 Spark 与 HBase

package spark.connectimport org.apache.hadoop.hbase.HBaseConfigurationimport org.apache.hadoop.hbase.client.Resultimport org.apache.hadoop.hbase.io.ImmutableBytesWritableimport org.apache.hadoop.hbase.mapreduce.TableInputFormatimport org.apache.hadoop.hbase.util.Bytesimport org.apache.spark.{SparkConf, SparkContext}/**  * Created by SIGNAL on 2016/11/28.  */object HBaseTest {  val conf = new SparkConf().setAppName("Spark connect to HBase").setMaster("local")  val sc = new SparkContext(conf)  def main(args: Array[String]) {    val hconf = HBaseConfiguration.create()    hconf.set(TableInputFormat.INPUT_TABLE,"student")    val hbaseRDD = sc.newAPIHadoopRDD(hconf,classOf[TableInputFormat]      ,classOf[ImmutableBytesWritable]      ,classOf[Result])    val rowRDD = hbaseRDD.map(x =>(Bytes.toString(x._1.get()), Bytes.toString(x._2.getValue("i".getBytes,"name".getBytes()))))    println(hbaseRDD.count())    rowRDD.foreach(println _)    sc.stop()  }}

这个就没什么好说的了,跟我们使用 java 访问 HBase 差不太多,只不过我们这次使用的是 scala 。
确保我们的 hbase 启动,我们就可以在 Intellij IDEA 中运行了。
这里写图片描述

然后运行,我们会在控制台上看到 student 表中 i 列族下的 name 一列的数据了:
这里写图片描述

当然,我们有好多种运行方式,可以放到集群中去运行,还可以在 yarn 下运行。大家可以参照官网上 spark-submit 来操作,就不一一演示了。

5 Spark 与 Mysql

package spark.connectimport java.sql.{Connection, DriverManager}import java.util.Propertiesimport org.apache.spark.rdd.JdbcRDDimport org.apache.spark.sql.SparkSessionimport org.apache.spark.{SparkConf, SparkContext}/**  * Created by SIGNAL on 2016/11/28.  */object MysqlTest {  val conf = new SparkConf().setAppName("Spark connect to Mysql").setMaster("local")  val sc = new SparkContext(conf)  def createConnection(): Connection ={    Class.forName("com.mysql.jdbc.Driver").newInstance()//    DriverManager.getConnection("jdbc:mysql://localhost:3306/test?user=root&password=signal")    DriverManager.getConnection("jdbc:mysql://localhost:3306/test","root","signal")  }  def formMysql(): Unit ={    val spark = SparkSession.builder.appName("spark connect to mysql").master("local").getOrCreate()    import spark.implicits._    val fromrd = spark.read.jdbc("jdbc:mysql://localhost:3306/gov?user=root&password=signal","app_user",new Properties())    fromrd.show()  }  def main(args: Array[String]): Unit = {    val mysqlData = new JdbcRDD(sc,createConnection,"select * from tb_user where user_id >= ? and user_id <= ? ",0,1000,3,r=>r)    mysqlData.map(r => (r.getLong("user_id"),r.getInt("age"),r.getString("user_name") )).foreach(println _)  }}

这个跟 HBase 一样,都是比较简单的操作,但是我只是从数据库中读取数据,往数据库中写数据都差不多,看看 API 很快就会上手,也就不写了。

这么一来,Spark SQL 也就介绍的差不多了,大家还有看不懂的就去看官方文档吧,多看看,对着敲几遍代码,去 API 里看看方法。

0 0