PySpark笔记
PySpark:Python on Spark
基于python语言,使用spark提供的pythonAPI库,进行spark应用程序的编程
==============================================================
一、搭建PySpark的环境
1.windows上进行pyspark环境配置
步骤:
-1.在windows上搭建python的环境(已搭建)
方式一:直接下载python安装包。
方式二:使用anaconda安装
-2.首先找到存放库的目录
进入cmd,输入python,回车
输入import sys
输入sys.path => 找到了
-3.将Spark的安装目录下的python目录下的lib中
pyspark.zip
py4j-0.10.4-src.zip
这两个把放在上面找到的site-packages里面
-4.放好之后,解压这两个压缩包,解压完之后,把这两个包删除
2.Linux上搭建PySpark环境(python的版本应该是3.6.5)
步骤:
-1.检查:linux中python的版本
在linux中输入python -V 回车
看一下版本是多少。
因为大家使用的centos的版本是7的版本,那么自带的python的版本应该是2.7.5,那么我们需要安装python3的版本,不需要写在自带的python2
-2.安装python3
1.下载Python 3.6.5的包
在线下载:
可以直接在linux中执行一下命令
wget https://www.python.org/ftp/python/3.6.5/Python-3.6.5.tgz
如果同学发现,自己没有wget命令
yum install -y wget
离线安装:
先从官网上下载包https://www.python.org/ftp/python/3.6.5/Python-3.6.5.tgz
然后再把下载好的包上传到linux即可
2.解压安装
tar -zxvf Python-3.6.5.tgz -C /opt/cdh5.14.2/modules/
3.解压好之后,切换到解压python目录
因为我们下载的是源码。所以不能直接使用,必须要进行编译
编译步骤: 使用root用户编译
-1.su - : 切换到root用户
-2.执行命令./configure:检查源码包
-3.开始编译,执行命令:make 回车
4.执行完第三步之后,python的版本仍然是2.7.5.因为当前系统环境变量中仍然是自带的python,所以只需要配置一下python3的环境变量即可
命令:
vi /etc/profile
最后添加:
#PYTHON_HOME
PYTHON_HOME=/opt/cdh5.14.2/modules/Python-3.6.5
PATH=$PYTHON_HOME:$PATH
保存,退出
记得source /etc/profile
完成之后,退出root用户,exit
在普通用户下,也要source /etc/profile
5.再次执行python -V,这个时候,应该显示python 3.6.5了
-3. 注意:这一步,本来是应该做下面的步骤的
将Spark的安装目录下的python目录下的lib中
pyspark.zip
py4j-0.10.4-src.zip
这两个把放在上面找到的site-packages里面
放好之后,解压这两个压缩包,解压完之后,把这两个包删除
但是现在可以不需要做这两个步骤
为什么不做呢???如果不做的话,那么python不就读不到pyspark的库了吗?
原因是因为:
在spark的python的目录下,已经解压好了pyspark,所以不需要再做上面的两步操作了。
那为什么py4j-0.10.4-src.zip也不需要放置呢?
因为linux的环境中,我们配置了JDK,SCALA,PYTHON三个环境,所以本身就可以转换。不需要再安装
py4j-0.10.4-src.zip
============================================================================
二、Spark中使用python的pyspark脚本编写代码
1.切换到spark目录
cd /opt/cdh5.14.2/modules/spark-2.2.1-bin-2.6.0-cdh5.14.2
2.执行命令:bin/pyspark
报错:java.net.ConnectException: Call From superman-bigdata.com/172.31.210.61 to superman-bigdata.com:9000 failed on connection exception: java.net.ConnectException: 拒绝连接; For more details see: http://wiki.apache.org/hadoop/ConnectionRefused
表示连接HDFS的namenode服务拒绝了,也就是说hdfs的服务没有打开
开启HDFS的服务
sbin/hadoop-daemon.sh start namenode
sbin/hadoop-daemon.sh start datanode
报错:20/03/11 15:08:20 WARN metastore: Failed to connect to the MetaStore Server...
20/03/11 15:08:21 WARN Hive: Failed to access metastore. This class should not accessed in runtime.
org.apache.hadoop.hive.ql.metadata.HiveException: java.lang.RuntimeException: Unable to instantiate org.apache.hadoop.hive.ql.metadata.SessionHiveMetaStoreClient
表示hive的元数据服务没有开启
开启hive的元数据服务
bin/hive --service metastore &
3.在pyspark命令行中编写一个简单的wordcount
list = [“hadoop”,“hbase”,“spark”,“hadoop”,“hadoop”,“hbase”,“spark”]
rdd = sc.parallelize(list)
rdd1 = rdd.map(lambda word : (word,1))
rdd2 = rdd1.reduceByKey(lambda a,b : a + b)
rdd2.collect()
# [(‘hadoop’, 3), (‘spark’, 2), (‘hbase’, 2)]
4.课堂案例:读取HDFS上的一个数据文件,计算词频统计
path = “/input/wc.txt”
rdd = sc.textFile(path)
rdd1 = rdd.flatMap(lambda line : line.split("\t"))
rdd2 = rdd1.map(lambda word : (word,1))
rdd3 = rdd2.reduceByKey(lambda a,b : a + b)
rdd3.collect()
============================================================================
三、在windows下的IDEA中编写pyspark程序
案例一:
from pyspark import SparkConf,SparkContext
import os
“”"
Could not find valid SPARK_HOME while searching
[‘C:\Users\ibf\Desktop\杨浦大数据43班\SparkSQL\代码\SparkDemo\src\main\python\PySpark’,
‘D:\IDEA\Anaconda3-5.2.0\lib\site-packages\pyspark’,
‘D:\IDEA\Anaconda3-5.2.0\lib\site-packages\pyspark’,
‘D:\IDEA\Anaconda3-5.2.0\lib’]
报错:找不到spark的环境变量,SPARK_HOME,也就是说必须要在windows上配置spark的环境变量
解决方法:必须在windows上解压一个spark。
方式一:在windows上配置spark的系统环境变量,永久生效的
方式二:在当前程序中配置临时环境变量(只是当前程序生效的)
方式三:直接在代码中给定环境变量(只是当前程序生效的)
报错:Exception: Python in worker has different version 2.7 than that in driver 3.6,
PySpark cannot run with different minor versions.Please check environment variables
PYSPARK_PYTHON and PYSPARK_DRIVER_PYTHON are correctly set.
解决方法:
直接在代码中给定环境变量(只是当前程序生效的)
“”"
#添加spark的环境变量
if ‘SPARK_HOME’ not in os.environ:
os.environ[‘SPARK_HOME’] = “D:\spark-2.2.1-bin-2.6.0-cdh5.14.2”
os.environ[‘PYSPARK_PYTHON’] = “D:\IDEA\Anaconda3-5.2.0\python.exe”
#1.构建上下文
“”"
scala代码:
val config = new SparkConf()
.setMaster(“local[]")
.setAppName(“Demo01”)
val sc = SparkContext.getOrCreate(config)
“”"
config = SparkConf()
.setMaster("local[]”)
.setAppName(“Demo01”)
sc = SparkContext.getOrCreate(config)
#2.读取数据形成RDD
list = [1,2,3,4,5,6]
rdd = sc.parallelize(list,3)
print(rdd.collect())
#查看当前RDD的分区数
count = rdd.getNumPartitions()
print(count)
#查看每个分区中具体的数据
#result = rdd.glom().collect()
#print(result)
###RDD下面常用的算子
##转换类算子map、flatMap
#map
rdd1 = rdd.map(lambda x : (x,x+1,x+2))
print(rdd1.collect())
#flatMap
rdd2 = rdd.flatMap(lambda x : (x,x+1,x+2))
print(rdd2.collect())
#总结:flatMap是在map的基础上对结果进行扁平化操作
##聚合类算子reduce fold aggregate
#reduce def reduce(self, f)
result1 = rdd.reduce(lambda a,b: a + b)
print(result1)
#fold def fold(self, zeroValue, op)
result2 = rdd.fold(0,lambda a,b : a + b)
print(result2)
result3 = rdd.fold("",lambda a ,b : a + str(b))
print(result3)
#aggregate def aggregate(self, zeroValue, seqOp, combOp)
#zeroValue:初始值,给的是临时聚合值的初始值
#seqOp:第一阶段聚合,也称之为局部聚合,分区内聚合
#combOp:第二阶段聚合,也称之为全局聚合,各分区临时结果聚合
zeroValue = 0
seqOp = lambda a ,b : a + b
combOp = lambda c ,d :c + d
result4 = rdd.aggregate(zeroValue, seqOp, combOp)
print(result4)
###过滤和去重 filter、distinct
rdd1 = rdd.flatMap(lambda x : (x,x+1,x+2))
print(rdd1.collect())
#[1, 2, 3, 2, 3, 4, 3, 4, 5, 4, 5, 6, 5, 6, 7, 6, 7, 8]
#filter def filter(self, f)
rdd2 = rdd1.filter(lambda x : x % 2 == 0 )
print(rdd2.collect())
#distinct
rdd3 = rdd1.distinct()
print(rdd3.collect())
###两个RDD之间的交集,并集,差集,笛卡尔积
rdd0 = sc.parallelize([‘C’,‘A’,‘B’,‘B’])
rdd1 = sc.parallelize([‘A’,‘A’,‘B’,‘D’])
#交集 intersection
rdd2 = rdd0.intersection(rdd1)
print(rdd2.collect())
#并集 union
rdd3 = rdd0.union(rdd1)
print(rdd3.collect())
#差集 subtract
rdd4 = rdd0.subtract(rdd1)
print(rdd4.collect())
#笛卡尔积 cartesian
rdd5 = rdd0.cartesian(rdd1)
print(rdd5.collect())
###排序和分组 sortBy groupBy
#sort def sortBy(self, keyfunc, ascending=True, numPartitions=None):
rdd2 = rdd.sortBy(keyfunc=lambda x : x,ascending = False)
print(rdd2.collect())
#groupBy def groupBy(self, f, numPartitions=None, partitionFunc=portable_hash):
rdd3 = rdd.groupBy(f=lambda x : x % 2 ==0)
print(rdd3.collect())
###PairRDD常用的算子 ==> 什么是PairRDD 特殊情况的RDD:键值对RDD[K,V]
##reduceByKey、reduceByKeyLocally、groupByKey、foldByKey、aggregateByKey、sortByKey
list = [“zhangsan”,“lisi”,“wangwu”,“xiaoming”,“zhangsan”,“lisi”,“wangwu”,
“xiaoming”,“zhangsan”,“lisi”,“wangwu”,“xiaoming”,“xiaoming”,“zhangsan”,“lisi”,
“wangwu”,“xiaoming”,“zhangsan”,“lisi”,“wangwu”,“xiaoming”,“zhangsan”,
“lisi”,“wangwu”,“lisi”,“wangwu”,“xiaoming”,“zhangsan”,“lisi”,“wangwu”,
“xiaoming”,“zhangsan”,“lisi”,“wangwu”,“xiaoming”,“zhangsan”,“lisi”,
“wangwu”,“xiaoming”,“zhangsan”,“lisi”,“wangwu”,“xiaoming”,“zhangsan”]
rdd = sc.parallelize(list) #RDD[str]
rdd1 = rdd.map(lambda word : (word,1)) #RDD[str,int]
#reduceByKey def reduceByKey(self, func, numPartitions=None, partitionFunc=portable_hash)
rdd2 = rdd1.reduceByKey(lambda a , b : a + b)
print(rdd2.collect())
#[(‘xiaoming’, 11), (‘lisi’, 11), (‘zhangsan’, 11), (‘wangwu’, 11)]
#reduceByKeyLocally def reduceByKeyLocally(self, func)
result = rdd1.reduceByKeyLocally(lambda a ,b : a +b)
print(result)
#{‘zhangsan’: 11, ‘lisi’: 11, ‘wangwu’: 11, ‘xiaoming’: 11}
#groupByKey def groupByKey(self, numPartitions=None, partitionFunc=portable_hash):
#(word,1) => (word,iter(1,1,1))
rdd3 = rdd1
.groupByKey()
.map(lambda t : (t[0],len(t[1])))
print(rdd3.collect())
##foldByKey def foldByKey(self, zeroValue, func, numPartitions=None, partitionFunc=portable_hash):
zeroValue = 0
func = lambda a ,b : a + b
rdd4 = rdd1.foldByKey(zeroValue,func)
print(rdd4.collect())
##aggregateByKey
def aggregateByKey(self, zeroValue, seqFunc, combFunc, numPartitions=None,
partitionFunc=portable_hash):
zeroValue = 0
seqFunc = lambda a, b : a + b
combFunc = lambda c ,d : c + d
rdd5 = rdd1.aggregateByKey(zeroValue,seqFunc,combFunc)
print(rdd5.collect())
##sortByKey def sortByKey(self, ascending=True, numPartitions=None, keyfunc=lambda x: x):
rdd6 = rdd5.sortByKey(ascending=True,keyfunc=lambda x: x)
print(rdd6.collect())
============================================================================
案例二:两个RDD之间的join操作
代码:
from pyspark import SparkConf,SparkContext
import os
#添加spark的环境变量
if ‘SPARK_HOME’ not in os.environ:
os.environ[‘SPARK_HOME’] = “D:\spark-2.2.1-bin-2.6.0-cdh5.14.2”
os.environ[‘PYSPARK_PYTHON’] = “D:\IDEA\Anaconda3-5.2.0\python.exe”
#1.构建上下文
config = SparkConf()
.setMaster(“local[*]”)
.setAppName(“Demo02”)
sc = SparkContext.getOrCreate(config)
#2.读取数据形成RDD ==》 RDD之间的join操作
list1 = [
(“Bob”,“Jack”),
(“Bob”,“John”),
(“Boss”,“lily”),
(“Jane”,“Mary”)
]
list2 = [
(“Bob”,10),
(“Boss”,19),
(“Hello”,18)
]
rdd1 = sc.parallelize(list1)
rdd2 = sc.parallelize(list2)
print(rdd1.collect())
print(rdd2.collect())
#3.join操作 join:inner join 内连接 leftOuterJoin:左外连接 rightOuterJoin:右外连接 fullOuterJoin:全外连接
#join:inner join 内连接
result1 = rdd1.join(rdd2)
print(result1.collect())
#leftOuterJoin:左外连接
result2 = rdd1.leftOuterJoin(rdd2)
print(result2.collect())
#rightOuterJoin:右外连接
result3 = rdd1.rightOuterJoin(rdd2)
print(result3.collect())
#fullOuterJoin:全外连接
result4 = rdd1.fullOuterJoin(rdd2)
print(result4.collect())
============================================================================
案例三:topN程序
代码:
from pyspark import SparkContext,SparkConf
import os
import random
from functools import reduce
#添加spark的环境变量
if ‘SPARK_HOME’ not in os.environ:
os.environ[‘SPARK_HOME’] = “D:\spark-2.2.1-bin-2.6.0-cdh5.14.2”
os.environ[‘PYSPARK_PYTHON’] = “D:\IDEA\Anaconda3-5.2.0\python.exe”
#1.构建上下文
config = SparkConf()
.setMaster(“local[*]”)
.setAppName(“TopNDemo”)
sc = SparkContext.getOrCreate(config)
#2.读取数据形成RDD
path = “hdfs://superman-bigdata.com:9000/input/groupsort.txt”
rdd = sc.textFile(path)
#2.1第一步,对原始的数据进行格式转换 String => (String,Int)
rdd1 = rdd
.map(lambda line : line.split(" "))
.filter(lambda arr : len(arr) == 2)
.map(lambda arr : (arr[0],int(arr[1])))
#2.2第二步开始进行top程序实现 ==> top3
#2.2.1 方式一实现:因为我们实现的是分组排序,当相同的key过多,那么容易导致数据倾斜,那么如何解决数据倾斜的问题??
##解决数据倾斜的问题的,根本解决方法,就是将key进行打散。
##(key + 随机前缀,然后进行分组,接着先计算出每个组中的前n名,然后去掉随机前缀,再分组,再把所有的数据排序,取出前N名即可)
def top3(key,iter):
sortedIter = sorted(iter,reverse=True)
#使用python的切片实现,前闭后开
top3 = sortedIter[0:3]
return map(lambda x : (key,x),top3)
result1 = rdd1
.map(lambda t : ((random.randint(1,10),t[0]),t[1]))
.groupByKey()
.flatMap(lambda t : top3(t[0][1],t[1]))
.groupByKey()
.flatMap(lambda t : top3(t[0],t[1]))
print(result1.collect())
#[(‘xiaoming’, 97), (‘xiaoming’, 80), (‘xiaoming’, 78), (‘xiaoli’, 98), (‘xiaoli’, 97), (‘xiaoli’, 92), (‘xiaoai’, 18), (‘xiaohong’, 98), (‘xiaohong’, 87), (‘xiaohong’, 86), (‘xiaozhi’, 80)]
#2.2.2方式2:两阶段聚合方式实现 ==》 aggregateByKey
def aggregateByKey(self, zeroValue, seqFunc, combFunc, numPartitions=None,partitionFunc=portable_hash):
#写法一:
zeroValue = []
def f(a,b):
a.append(b)
sortedIter = sorted(a,reverse=True)
top3 = sortedIter[0:3]
return top3
seqFunc = lambda a ,b : f(a,b)
def g(c,d):
for i in d:
c.append(i)
sortedIter = sorted(c,reverse=True)
top3 = sortedIter[0:3]
return top3
combFunc = lambda c , d: g(c,d)
result2 = rdd1
.aggregateByKey(zeroValue,seqFunc,combFunc)
print(result2.collect())
#写法2:
zeroValue = []
def f(a,b):
a.append(b)
sortedIter = sorted(a,reverse=True)
top3 = sortedIter[0:3]
return top3
seqFunc = lambda a ,b : f(a,b)
combFunc = lambda c,d : reduce(lambda x , y : f(x,y),c,d)
result3 = rdd1
.aggregateByKey(zeroValue,seqFunc,combFunc)
print(result3.collect())
============================================================================
PySpark在SparkSQL上的使用
案例一:
from pyspark.sql import SparkSession
import os
from pyspark.sql import Window
from pyspark.sql import functions as F
#添加spark的环境变量
if ‘SPARK_HOME’ not in os.environ:
os.environ[‘SPARK_HOME’] = “D:\spark-2.2.1-bin-2.6.0-cdh5.14.2”
os.environ[‘PYSPARK_PYTHON’] = “D:\IDEA\Anaconda3-5.2.0\python.exe”
#1.构建上下文
spark = SparkSession
.builder
.master(“local[*]”)
.appName(“Demo01”)
.getOrCreate()
#2.读取数据形成DataFrame
path = “hdfs://superman-bigdata.com:9000/input/people.json”
df = spark.read.json(path)
df.show()
#3.创建临时视图
##创建临时视图
#df.createTempView(“people”)
##如果临时视图名字存在,则替换
#df.createOrReplaceTempView(“person”)
#创建全局临时视图
#df.createGlobalTempView(“people”)
#如果全局临时视图存在,则替换
#df.createOrReplaceGlobalTempView(“person”)
#spark.read.table(“people”).show()
# org.apache.spark.sql.AnalysisException: Table or view not found: people;
#因为当我们访问全局临时表的时候,必须在表之前加上global_temp
#spark.read.table(“global_temp.people”).show()
df.createTempView(“people”)
df.createGlobalTempView(“person”)
#可以访问到
spark.read.table(“people”).show()
#可以访问到
spark.read.table(“global_temp.person”).show()
spark1 = spark.newSession
#不可以访问到
spark1.read.table(“people”).show()
#可以访问到
spark1.read.table(“global_temp.person”).show()
#createTempView和createGlobalTempView的区别?
#createTempView创建的临时视图,只能被当前的sparksession访问,
createGlobalTempView创建的全局临时视图,可以被程序中的任意sparksession对象访问到
#4.给你一个DataFrame,我们不清楚他里面有哪些字段和类型,我们可以使用printSchema方法查看信息
print(df.printSchema())
#5.使用DSL编程 以df为例
df.select(“name”).show()
df.select(df[“name”].alias(“name1”),df[“age”].alias(“age1”)).show()
df.filter(df[“age”] is not None).show()
df.where(df[“age”] is not None).show()
df.groupBy(“name”).agg({“age”:“avg”}).show()
w = Window.partitionBy(df[“name”]).orderBy(df[“age”].desc)
df.select(df[“name”],df[“age”],F.row_number().over(w)).show()
============================================================================
案例二:RDD如何转成DataFrame
代码:
from pyspark.sql import SparkSession
import os
from pyspark.sql import Row
from pyspark.sql.types import StructType,StructField,StringType,IntegerType
#添加spark的环境变量
if ‘SPARK_HOME’ not in os.environ:
os.environ[‘SPARK_HOME’] = “D:\spark-2.2.1-bin-2.6.0-cdh5.14.2”
os.environ[‘PYSPARK_PYTHON’] = “D:\IDEA\Anaconda3-5.2.0\python.exe”
#1.构建上下文
spark = SparkSession
.builder
.master(“local[*]”)
.appName(“Demo02”)
.getOrCreate()
sc = spark.sparkContext
#2.读取数据形成RDD
path = “hdfs://superman-bigdata.com:9000/input/student.txt”
rdd = sc.textFile(path)
#2.1数据进行格式化转换
rdd1 = rdd
.map(lambda line : line.split(","))
.map(lambda arr : (arr[0],int(arr[1])))
#2.2 RDD转成DataFrame
#2.2.1第一种方式:基于反射机制的方式
##注意!!!:在scala,基于反射机制的方式,必须要导入隐式转换,但是python中不需要
#这个得到的dataframe是没有字段信息的
df1 = rdd1.toDF()
df1.show()
#这个是可以添加字段信息的
df2 = rdd1.toDF([“name”,“age”])
df2.show()
##2.2.2第二种方式:直接给定schema信息
##DataFrame = rdd + schema
rdd2 = rdd1.map(lambda t : Row(name1 = t[0],age1 = t[1]))
df3 = spark.createDataFrame(rdd2)
df3.show()
df4 = spark.createDataFrame(rdd1,[“name2”,“age2”])
df4.show()
schema = StructType([
StructField(“name3”,StringType()),
StructField(“age3”,IntegerType())
])
df5 = spark.createDataFrame(rdd1,schema)
df5.show()
##3.将当前的DataFrame的结果进行输出
##3.1结果输出到windows的目录
df5
.write
.format(“json”)
.mode(“overwrite”)
.save(“file:///C:\Users\ibf\Desktop\杨浦大数据43班\PySpark\data”)
##3.2结果输出到HDFS上
df5
.write
.format(“json”)
.mode(“overwrite”)
.save(“hdfs://superman-bigdata.com:9000/yangpu1005/pyspark/data”)
##3.3结果输出到mysql数据库
#报错:py4j.protocol.Py4JJavaError: An error occurred while calling o67.jdbc.
#: java.sql.SQLException: No suitable driver
##注意:spark程序向mysql写入数据的话,必须要满足四要素
#以下代码,我们缺少了一个mysql的驱动包
#因为我们是python的代码,所以不会去读取pom文件中的依赖,以及resources中的配置文件
#所以我们当前的程序是没有mysql的驱动包的
#解决方法:因为我们在代码中导入了SPARK_HOME,所以程序是会主动去读取SPARK_HOME,
#我们只需要将mysql-connector驱动包,放在SPARK_HOME的jars目录里面即可
#def jdbc(self, url, table, mode=None, properties=None)
url = “jdbc:mysql://superman-bigdata.com:3306/yangpu1005”
table = “student”
mode = “overwrite”
#在scala中,properties是需要实例化的,但是python不可以,那怎么保存配置参数
#因为properties保存的是键值对的数据,那么我们只需要使用python保存键值对的数据结构保存参数即可
properties = {“user”:“root”,“password”:“123456”}
df5
.write
.format(“json”)
.jdbc(url, table, mode, properties)
============================================================================
案例三:PySpark中SparkSQL如何和hive集成
代码:
from pyspark.sql import SparkSession
import os
import pymysql
if ‘SPARK_HOME’ not in os.environ:
os.environ[‘SPARK_HOME’] = “D:\spark-2.2.1-bin-2.6.0-cdh5.14.2”
os.environ[‘PYSPARK_PYTHON’] = “D:\IDEA\Anaconda3-5.2.0\python.exe”
#1.构建上下文
#注意:加上enableHiveSupport就表示集成了hive
spark = SparkSession
.builder
.master(“local[*]”)
.appName(“Demo03”)
.enableHiveSupport()
.getOrCreate()
sc = spark.sparkContext
#2.验证是否已经集成了hive,直接读取一张hive的表,如果可以读到,表示集成完成,如果读取不到表示集成失败
“”"
如何和hive集成??
1.访问hive,必须读取到hive的jar包和hive的配置文件hive-site.xml,因为我们配置了SPARK_HOME,spark下的jars里面是
自带hive的jar的,所以直接就可以读取到,但是hive-site.xml是没有的,所以我们首先要把hive-site.xml文件放置到
SPARK_HOME的conf目录里面
2.想要对hive的表进行读写操作,必须要访问hive的元数据,因为我们的元数据库在mysql中,所以必须要连接mysql
又因为我们配置文件中配置了元数据服务,所以我们还需要开启元数据服务
bin/hive --service metastore &
“”"
#读取表已经成功
spark.read.table(“yangpu1005.dept”).show()
#sparksql写入hive中
path = “hdfs://superman-bigdata.com:9000/input/student.txt”
rdd = sc.textFile(path)
rdd1 = rdd.map(lambda line : line.split(","))
.map(lambda arr : (arr[0],int(arr[1])))
df = rdd1.toDF([“name”,“age”])
#df.show()
#df.write.mode(“overwrite”).saveAsTable(“yangpu1005.student”)
##再上一个案例中,我使用了df的write下的jdbc方法将数据写入mysql中
##这次我使用另外一种方法,就是将df转成RDD之后,使用原生态的JDBC方法
##因为我们直接都是使用java的jdbc方法
##这次我们使用python代码写入mysql,所以需要pymysql库
##因为python本身么有pymysql库,所以我们需要下载pymysql库
##命令:在cmd中使用:pip install pymysql / conda install pymysql
df.printSchema()
“”"
root
|-- name: string (nullable = true)
|-- age: long (nullable = true)
“”"
def writeToMysql(row):
#引入pymysql库 import pymysql
#连接数据库
conn = pymysql.connect(
host=“superman-bigdata.com”,
port=3306,
user=“root”,
password=“123456”,
database=“yangpu1005”,
charset=“utf8”
)
#得到一个可以执行sql的游标对象
cursor = conn.cursor()
#编写一条插入数据的sql语句,首先要在数据库中建表
sql = “insert into student(name3,age3) values (%s,%s)”
data = [(row[0],str(row[1]))]
#拼接执行sql语句
cursor.executemany(sql,data)
#提交程序
conn.commit()
#关闭游标
cursor.close()
#关闭数据库连接
conn.close()
def foreach(iter):
for row in iter:
writeToMysql(row)
df
.rdd
.foreachPartition(lambda iter : foreach(iter))
============================================================================
PySpark中SparkStreaming的应用
1.官网案例socket
代码:
from pyspark import SparkContext,SparkConf
from pyspark.streaming import StreamingContext
import os
#添加spark的环境变量
if ‘SPARK_HOME’ not in os.environ:
os.environ[‘SPARK_HOME’] = “D:\spark-2.2.1-bin-2.6.0-cdh5.14.2”
os.environ[‘PYSPARK_PYTHON’] = “D:\IDEA\Anaconda3-5.2.0\python.exe”
#1.构建上下文
config = SparkConf()
.setMaster(“local[*]”)
.setAppName(“Demo01”)
sc = SparkContext.getOrCreate(config)
#在scala中 StreamingContext的批次产生的间隔时间可以写为Seconds(5),在pyspark中直接写数字,单位是秒
ssc = StreamingContext(sc,5)
#2.读取形成DStream
dstream = ssc.socketTextStream(“superman-bigdata.com”,9999)
#3.计算词频统计
result = dstream
.flatMap(lambda line : line.split("\t"))
.map(lambda word : (word,1))
.reduceByKey(lambda a , b : a + b)
#4.结果输出
#注意,在scala中输出是print,在pyspark中是pprint
result.pprint()
#4.1结果写到HDFS上
result.saveAsTextFiles(“hdfs://superman-bigdata.com:9000/yangpu1005/pyspark/socket”)
#5.开启程序,进行阻塞
ssc.start()
ssc.awaitTermination()
============================================================================
SparkStreaming和Kafka集成