DataSet 不同于Java 或 Kryo 序列化,它用的是Encoder去序列化对象。,而且它支持动态序列化,以及可以让spark依照一个格式来执行filtering sorting操作。
而且注意DataSet不支持python
创建DataSet
case class Dept(dept_id:Int,dept_name:String)
val deptRDD = sc.makeRDD(Seq(Dept(1,"sales"),Dept(2,"HR")))
val deptDS = spark.createDataset(deptRDD)
val deptDF = spark.createDataFrame(deptRDD)
deptDS.rdd ---RDD[Dept]
deptDF.rdd ---RDD[Row]
将DataFrame转为DataSet
val newDeptDS = deptDF.as[Dept]
将DataSet转为DataFrame
DS.toDF
访问元数据获取hive 和 UDF 的信息
spark.catalog.listDatabases().select("name").show() //实例
spark.catalog.listTables.show()
spark.catalog.isCached("sample_07")
spark.catalog.listFunctions().show
createTempView dropTempView
Data Source API
是sparkSQL中专门用来加载和存储数据的API
默认的数据源是parquet 通过 spark.sql.sources.default 配置
内建的数据源:text,json,ORC,parquet,JDBC,CSV
df_txt = spark.read.text("people.txt")
df_json = spark.read.json("people.json")
当然也可以用load的方式来加载数据
但是这样是错误的
df_json = spark.read.load("people.json")
因为sparksql默认读取的是parquet文件,所以如果是parquet文件,可以这样写,否则就是下面
df_json = spark.read.load("people.json",format="json")
将数据写入另一个json文件
df_json.write.json("newjson_dir")
or
df_json.write.format("json").save("newjson_dir2")
将数据写入到一个parquet文件中
df_json.write.parquet("parquet_dir")
or
df_json.write.format("parquet").save("parquet_dir2")
从一个parquet文件中读取数据,parquet是列式存储,而且是sparksql中默认的读取格式
df_parquet = spark.read.load("parquet_dir")
or
df_parquet = spark.read.parquet("parquet_dir2"
建立临时表
df_parquet.createOrReplaceTempView("parquet_table")
写成json文件
df_parquet.write.json("myjson_dir")
or
df_parquet.write.format("json").save("myjson_dir2")
数据的文件如果是存在的话,就会报错
在输出的文件已经存在的情况下,有三种模式可以采用 ignore append overwrite
df_parquet.write.mode("append").json("myjson_dir")
df_parquet.write.mode("append").format("json").save("
myjson_dir ")
df_parquet.write.mode("overwrite").save("parquet_dir")
一个dataFrame也可以写入到hive table中
df_parquet.write.saveAsTable("hive_parquet_table") //这是parquet文件格式
parquet也支持多种schema格式 例如protocolBuffer ,avro ,thrift
通过把 spark.sql.parquet.margeSchema 设置为true 或者使用mergeSchema的选项的方式
df_parquet = spark.read.option("mergeSchema","true").parquet("parquet_dir")
因为parquet是列格式存储,所以自动支持列裁剪,而且谓词下压也是默认支持的,当然是设置好的
spark.sql.parquet.filterPushdown = true
而且在parquet文件在输出时也可以通过partitionBy的方式选择输出的列
ORC格式文件
ORC Optimized Row Columnar 也是列式存储
通过读取了一个json文件后,通过输出的方式创建一个ORC文件
df_json.write.orc("myorc_dir")
df_json.write.format("orc").save("myorc_dir")
通过读取的方式创建orc文件
df_orc = spark.read.orc("myorc_dir")
or
df_orc = spark.read.load("myorc_dir",format="orc")
将一个以json格式的Dataframe放入到hive中的orc文件
df_json.write.saveAsTable("hive_orc_table","orc")
orc也支持列裁剪,谓词下推,分区裁剪
默认是关闭的
spark.conf.set("spark.sql.orc.filterPushDown","true")
spark.conf.get("spark.sql.orc.filterPushDown")
分区裁剪 partition Pruning
df_json.write.format("orc").partitionBy("age").save("partitioned_orc")
以上是常用的也是sparksql 的DataSourceAPI中内嵌的格式
有的格式是没有的,需要下载指定的package 通过 --package 命令才可以用
详细的内容看Packt.Big.Data.Analytics.with.Spark.and.Hadoop 一书
重点说下sparkSQL作为分布式的SQL解析引擎
sparkSQL有两种应用方向:
1 是用来写查询语言的库,SQL scala java等
2
作为一个分布式SQL解析引擎,通过jdbc 连接client 与 thrift server
sparkSQL的thrift server 提供了jdbc访问方式
thrift server 的jdbc类似与Hiv中的hiveServer2 ,有多会话模式
开启的命令,
./start-thriftserver.sh --master yarn --hiveconf hive.server2.thrift.bind.host=localhost --hiveconf hive.server2.thrift.port=10001
spark获得hive的支持,通过 --Phive 和 -Phive-thriftserver
在开启了thrift server后,可以用beeline来测试
bin/beeline -u "jdbc:hive2://localhost:10001/default;hive.server2.transport.mode=http;hive.server2.thrift.http.path=cliservice"
通过sparksql CLI查询hive的数据
SparkSQL CLI不能连接thrift JDBC server
而是在本地运行hive metastore service
./bin/spark-sql
Hive on Spark
当已经存在hive时,用户可以在hive上写sql,但是执行引擎由MR换成spark
hive 中打入 set hive.execution.engine=spark