安装单机的spark,之前那个太复杂了
https://blog.youkuaiyun.com/zhaohaibo_/article/details/84260310
SprakSession
Spark有三大引擎,Spark core,SparkSQL,SparkStreaming
Spark core的关键抽象是SparkContext,RDD;
Spark SQL的关键抽象是SparkSession,DataFrame;
SparkStreaming的关键抽象是StreamingContext,DStream
SparkSession 是 spark2.0 引入的概念,主要用在 sparkSQL 中,当然也可以用在其他场合,他可以代替 SparkContext;
SparkSession 其实是封装了 SQLContext 和 HiveContext
SQLContext
它是SparkSQL的入口点,sparkSQL的应用必须创建一个SQLContex或者HiveContext的类实例
from pyspark import SparkContext, SparkConf
from pyspark.sql import SparkSession, SQLContext, HiveContext
conf = SparkConf().setAppName('test').setMaster('yarn')
sc = SparkContext(conf=conf)
sqlc = SQLContext(sc)
print(dir(sqlc))
# 'cacheTable', 'clearCache', 'createDataFrame', 'createExternalTable', 'dropTempTable', 'getConf', 'getOrCreate', 'newSession', 'range', 'read', 'readStream',
# 'registerDataFrameAsTable', 'registerFunction', 'registerJavaFunction', 'setConf', 'sparkSession', 'sql', 'streams', 'table', 'tableNames', 'tables', 'udf', 'uncacheTable'
### sqlcontext 读取数据也自动生成 df
data = sqlc.read.text('/usr/yanshw/test.txt')
print(type(data))
HiveContext
它是SparkSQL的另一个入口点,它继承自SQLContext,用于处理hive中的数据
HiveContext对SQLContext进行了扩展,功能要更加强大
- 它可以执行HiveSQL和SQL查询
- 它可以操作hive数据,并且可以访问HiveUDF
- 它不一定需要hive,在没有hive环境时也可以使用HiveContext
如果要处理hive数据,需要把hive的hive-site.xml文件放到spark/conf下,HiveContext将从hive-site.xml中获取hive配置信息,如果HiveContext没有找到hive-site.xml,他会在当前目录下创建spark-warehouse和metastore_db两个个文件
from pyspark import SparkContext, SparkConf
from pyspark.sql import SparkSession, SQLContext, HiveContext
conf = SparkConf().setAppName('test').setMaster('yarn')
sc = SparkContext(conf=conf)
## 需要把 hive/conf/hive-site.xml 复制到 spark/conf 下
hivec = HiveContext(sc)
print(dir(hivec))
# 'cacheTable', 'clearCache', 'createDataFrame', 'createExternalTable', 'dropTempTable', 'getConf', 'getOrCreate', 'newSession', 'range', 'read', 'readStream','refreshTable',
# 'registerDataFrameAsTable', 'registerFunction', 'registerJavaFunction', 'setConf', 'sparkSession', 'sql', 'streams', 'table', 'tableNames', 'tables', 'udf', 'uncacheTable'
data = hivec.sql('''select * from hive1101.person limit 2''')
print(type(data))
SparkSession
实现了对二者的封装
SparkSession的创建
class SparkSession(__builtin__.object):
def __init__(self, sparkContext, jsparkSession=None):
''' Creates a new SparkSession.
|
| >>> from datetime import datetime
| >>> spark = SparkSession(sc)
| >>> allTypes = sc.parallelize([Row(i=1, s="string", d=1.0, l=1,
| ... b=True, list=[1, 2, 3], dict={"s": 0}, row=Row(a=1),
| ... time=datetime(2014, 8, 1, 14, 1, 5))])
| >>> df = allTypes.toDF()
| >>> df.createOrReplaceTempView("allTypes")
| >>> spark.sql('select i+1, d+1, not b, list[1], dict["s"], time, row.a '
| ... 'from allTypes where b and i > 0').collect()
| [Row((i + CAST(1 AS BIGINT))=2, (d + CAST(1 AS DOUBLE))=2.0, (NOT b)=False, list[1]=2, dict[s]=0, time=datetime.datetime(2014, 8, 1, 14, 1, 5), a=1)]
| >>> df.rdd.map(lambda x: (x.i, x.s, x.d, x.l, x.b, x.time, x.row.a, x.list)).collect()
| [(1, u'string', 1.0, 1, True, datetime.datetime(2014, 8, 1, 14, 1, 5), 1, [1, 2, 3])]'''
示例代码
from pyspark.sql import SparkSession
### method 1
sess = SparkSession.builder \
.appName("aaa") \
.config("spark.driver.extraClassPath", sparkClassPath) \
.master("local") \
.enableHiveSupport() \ # sparkSQL 连接 hive 时需要这句
.getOrCreate() # builder 方式必须有这句
### method 2
conf = SparkConf().setAppName('myapp1').setMaster('local[4]') # 设定 appname 和 master
sess = SparkSession.builder.config(conf=conf).getOrCreate() # builder 方式必须有这句
### method 3
from pyspark import SparkContext, SparkConf
conf = SparkConf().setAppName('myapp1').setMaster('local[4]') # 设定 appname 和 master
sc = SparkContext(conf=conf)
sess = SparkSession(sc)
文件数据源
from pyspark import SparkContext, SparkConf
from pyspark.sql import SparkSession, SQLContext, HiveContext
conf = SparkConf().setAppName('test').setMaster('yarn')
sc = SparkContext(conf=conf)
#### 替代了 SQLContext 和 HiveContext,其实只是简单的封装,提供了统一的接口
spark = SparkSession(sc)
print(dir(spark))
# 很多属性,我把私有属性删了
# 'Builder','builder', 'catalog', 'conf', 'createDataFrame', 'newSession', 'range', 'read', 'readStream','sparkContext', 'sql', 'stop', 'streams', 'table', 'udf', 'version'
### sess 读取数据自动生成 df
data = spark.read.text('/usr/yanshw/test.txt') #read 可读类型 [ 'csv', 'format', 'jdbc', 'json', 'load', 'option', 'options', 'orc', 'parquet', 'schema', 'table', 'text']
print(type(data)) # <class 'pyspark.sql.dataframe.DataFrame'>
Hive数据源
## 也需要把 hive/conf/hive-site.xml 复制到 spark/conf 下
spark = SparkSession.builder.appName('test').master('yarn').enableHiveSupport().getOrCreate()
hive_data = spark.sql('select * from hive1101.person limit 2')
print(hive_data) # DataFrame[name: string, idcard: string]
SparkSQL直接连接到hive
def main(args: Array[String]): Unit = {
val Array(inpath, dt, hour) = args
val conf = new SparkConf().setAppName(this.getClass.getSimpleName)
//.setMaster("local[*]")
.setMaster("spark://192.168.40.52:7077")
val session = SparkSession.builder()
.config(conf)
// 指定hive的metastore的端口 默认为9083 在hive-site.xml中查看
.config("hive.metastore.uris", "thrift://192.168.40.51:9083")
//指定hive的warehouse目录
.config("spark.sql.warehouse.dir", "hdfs://192.168.40.51:9000/user/hive/warehouse")
//直接连接hive
.enableHiveSupport()
.getOrCreate()
import session.implicits._
val df1 = session.read.parquet(inpath)
//df1.write.saveAsTable(s"tmp.tmp_app_log_1")
df1.createOrReplaceTempView("tmp_app_log_test")
//sql的代码省略
val sql1 =
s"""
|select *
|from tmp_app_log_test
""".stripMargin
val hive_table = "dwb2.fact_mbk_offline_log_mbk_app_action_event_v2_i_h"
val sql2 = s"alter table $hive_table add if not exists partition ( dt='$dt',hour='$hour')"
session.sql(sql2)
val tmp_table =s"""tmp.app_log_${dt}_${hour}"""
val sql3 = s"""drop table IF EXISTS $tmp_table""".stripMargin
session.sql(sql3)
val df2 = session.sql(sql1)
//结果先写入临时表
df2.write.saveAsTable(tmp_table)
//结果从临时表写入分区表
val sql4 =
s"""INSERT OVERWRITE TABLE $hive_table
|PARTITION( dt='$dt',hour='$hour')
| select * from $tmp_table """.stripMargin
session.sql(sql4)
val sql5 = s"""drop table IF EXISTS $tmp_table""".stripMargin
session.sql(sql5)
}
SparkSQL之DataFrame操作大全
Spark SQL中的DataFrame类似于一张关系型数据表,在关系型数据库中对单表或进行的查询操作,在DataFrame中都可以通过调用其API接口来实现
DataFrame对象的生成
Spark-SQL可以以其他RDD对象、parquet文件、json文件、hive表,以及通过JDBC连接到其他关系型数据库作为数据源来生成DataFrame对象。本文将以MySQL数据库为数据源,生成DataFrame对象后进行相关的DataFame之上的操作。
源码
object DataFrameOperations {
def main (args: Array[String ]) {
val sparkConf = new SparkConf().setAppName( "Spark SQL DataFrame Operations").setMaster( "local[2]" )
val sparkContext = new SparkContext(sparkConf)
val sqlContext = new SQLContext(sparkContext)
val url = "jdbc:mysql://m000:3306/test"
val jdbcDF = sqlContext.read.format( "jdbc" ).options(
Map( "url" -> url,
"user" -> "root",
"password" -> "root",
"dbtable" -> "spark_sql_test" )).load()
val joinDF1 = sqlContext.read.format( "jdbc" ).options(
Map("url" -> url ,
"user" -> "root",
"password" -> "root",
"dbtable" -> "spark_sql_join1" )).load()
val joinDF2 = sqlContext.read.format( "jdbc" ).options(
Map ( "url" -> url ,
"user" -> "root",
"password" -> "root",
"dbtable" -> "spark_sql_join2" )).load()
... ...
}
}
DataFrame对象上Action操作
-
show:展示数据
以表格的形式在输出中展示jdbcDF中的数据,类似与select * from spark_sql_test的功能
show方法有四种调用方式
(1)show
只显示前20条记录
示例
jdbcDF.show
(2)show(numRows:Int)
显示numRows条
示例
jdbcDF.show(3)
(3)show(truncate:Boolean)
显示最多只显示20个字符,默认为true
示例
jdbcDF.show(true)
jdbcDF.show(false)
(4)show(numRows:Int,truncate:Boolean)
综合前面的显示记录条数,以及对过长字符串的显示格式
示例
jdbcDF.show(3,false) -
collect:获取到所有数据到数组
不同于前面的show方法,这里的collect方法会将jdbcDF中的所有数据都获取到,并返回一个Array对象
jdbcDF.collect() -
collectAsList:获取所有数据到list
功能和collect类似,只不过将返回结构变成list对象
jdbcDF.collectAsLIst
4.describe(cols:String*):获取指定字段的统计信息
可以动态传入一个或多个String类型的字段名,结果仍为DataFrame对象,用于统计数值类型字段的统计值,比如count,mean,stddev,min,max等
使用方法如下,其中c1字段为字符类型,c2字段为整型,c4字段为浮点型
JdbcDF.describe(“c1”,”c2“,”c4“).show()
5.first,head,take,takeAsList:获取若干数据
这里列出的四个方法比较类似,其中
first获取第一行记录
head获取第一行记录,head(n:Int)获取前n行记录
take(n:Int)获取前n行数据
takeAsList(n:Int)获取前n行数据,并以LIst的形式展现
以Row或者Array[Row]的形式返回一行或多行数据。first和head功能相同。
take和takeAsList方法会将获得到的数据返回到Driver端,所以,使用这两个方法时需要注意数据量,以免Driver发生OutOfMemoryError
DataFrame对象上的条件查询和join等操作
返回的对象是DataFrame类型的方法,可以连续调用
- where条件相关
传入筛选条件表达式,可以用and和or。得到DataFrame类型的返回结果,
示例:
jdbcDF .where(“id = 1 or c1 = ‘b’” ).show()
filter:根据字段进行筛选
传入筛选条件表达式,得到DataFrame类型的返回结果。和where使用条件相同
示例:
jdbcDF .filter(“id = 1 or c1 = ‘b’” ).show()
- 查询指定条件
(1)select:获取指定字段值
根据传入的String类型字段名,获取指定字段的值,以DataFrame类型返回
示例:
jdbcDF.select( “id” , “c3” ).show( false)
有一个重载的select方法,不是传入String类型参数,而是传入Column类型参数。可以实现select id, id+1 from test这种逻辑。
jdbcDF.select(jdbcDF( “id” ), jdbcDF( “id”) + 1 ).show( false)
需求更改不用在学习了
原文:https://blog.youkuaiyun.com/dabokele/article/details/52802150