spark学习笔记__chap4_spark基础原理__4.2_SparkContext编程入口

  1. SparkContext是pyspark的编程入口,作业的提交,任务的分发,应用的注册都会在SparkContext中进行。一个SparkContext实例代表着和Spark的一个连接,只有建立了连接才可以把作业提交到集群中去。实例化了SparkContext之后才能创建RDD和Broadcast广播变量。

  2. Sparkcontext获取,启动pyspark --master spark://hadoop-maste:7077之后,可以通过SparkSession获取Sparkcontext对象从打印的记录来看,SparkContext它连接的Spark集群的master地址是spark://hadoop-maste:7077
    在这里插入图片描述
    另外一种获取SparkContext的方法是,引入pyspark.SparkContext进行创建。新建parkContext.py文件,内容如下:

    from pyspark import SparkContext
    from pyspark import SparkConf
    conf = SparkConf()
    conf.set('master','local')
    sparkContext = SparkContext(conf=conf)
    rdd = sparkContext.parallelize(range(100))
    print(rdd.collect())
    sparkContext.stop()
    

    运行之前先将spark目录下的conf配置目录中的log4j.properties配置文件中的日志级别改为如下:
    在这里插入图片描述
    这样后台打印的日志不至于太多印象查看!重启Spark集群
    运行spark-submit sparkContext.py
    上面代码中的Sparkconf对象是Spark里面用来配置参数的对象,接下来我们会详细讲解到。

  3. accumulator是Sparkcontext上用来创建累加器的方法。创建的累加器可以在各个task中进行累加,并且只能够支持add操作。该方法
    支持传入累加器的初始值。这里以Accumulator累加器做1到50的加法作为讲解的例子。
    新建accumulator.py文件,内容如下:

    from pyspark import SparkContext,SparkConf
    import numpy as np
    conf = SparkConf()
    conf.set('master','spark://hadoop-maste:7077')
    context = SparkContext(conf=conf)
    acc = context.accumulator(0)
    print(type(acc),acc.value)
    rdd = context.parallelize(np.arange(101),5)
    def acc_add(a):
    	acc.add(a)
    	return a
    rdd2 = rdd.map(acc_add)
    print(rdd2.collect())
    print(acc.value)
    context.stop()
    

    使用spark-submit accumulator.py运行

  4. addFile方法添加文件,使用SparkFiles.get方法获取文件
    这个方法接收一个路径,该方法将会把本地路径下的文件上传到集群中,以供运算过程中各个node节点下载数据,路径可以是本地路径也可是是hdfs路径,或者一个http,https,或者tfp的uri。如果上传的是一个文件夹,则指定recursize参数为True.上传的文件使用SparkFiles.get(filename)的方式进行获取。

    如果使用本地路径,则要求所有节点本地相同的的路径中都有该文件,各个节点在各自的本地目录中寻找该文件。

    新建addFile.py文件,内容如下:

    from pyspark import SparkFiles
    import os
    import numpy as np
    from pyspark import SparkContext
    from pyspark import SparkConf
    tempdir = '/root/workspace/'
    path = os.path.join(tempdir,'num_data')
    with open(path,'w') as f:
    	f.write('100')
    conf = SparkConf()
    conf.set('master','spark://hadoop-maste:7077')
    context = SparkContext(conf=conf)
    context.addFile(path)
    rdd = context.parallelize(np.arange(10))
    def fun(iterable):
    	with open(SparkFiles.get('num_data')) as f:
    		value = int(f.readline())
    		return [x*value for x in iterable]
    print(rdd.mapPartitions(fun).collect())
    context.stop()
    

    运行spark-submit addFile.py
    这个例子是使用的本地的文件,接下来我们尝试一下hdfs路径下的文件。
    新建hdfs_addFile.py文件,内容如下:

    from pyspark import SparkFiles
    import numpy as np
    from pyspark import SparkContext
    from pyspark import SparkConf
    conf = SparkConf()
    conf.set('master','spark://hadoop-maste:7077')
    context = SparkContext(conf=conf)
    path = 'hdfs://hadoop-maste:9000/datas/num_data'
    context.addFile(path)
    rdd = context.parallelize(np.arange(10))
    def fun(iterable):
    	with open(SparkFiles.get('num_data')) as f:
    		value = int(f.readline())
    		return [x*value for x in iterable]
    print(rdd.mapPartitions(fun).collect())
    context.stop()
    
    #查看hdfs的根目录
    hdfs dfs -ls / 
    #在根目录下创建/datas文件夹
    hdfs dfs -mkdir /datas
    # 将本地目录中的num_data文件put至hdfs目录/datas/下
    hdfs dfs -put num_data /datas/num_data
    # 查看是否拷贝成功
    hdfs dfs -ls /datas
    # 打印hdfs目录中/datas/num_data中的内容
    hdfs dfs -cat /datas/num_data
    

    在这里插入图片描述
    运行spark-submit hdfs_addFile.py

在这里插入图片描述
需要注意的是addFile默认识别本地路径,若是hdfs路径,需要指定hdfs://hadoop-maste:9000协议、uri及端口信息。
再来看一下读取网络文件信息。在182.150.37.49这台机器上,我安装了httpd服务器。httpd的配置及安装参考我的这个笔记:【链接】
进入到安装了httpd服务器的机器的/var/www/html/目录,在这个目录中新建num_data文件,文件内容为100
然后编写http_addFile.py文件,在代码中读取刚才新建的httpd服务器上的num_data文件。
内容如下:

from pyspark import SparkFiles
import numpy as np
from pyspark import SparkContext
from pyspark import SparkConf
conf = SparkConf()
conf.set('master','spark://hadoop-maste:7077')
context = SparkContext(conf=conf)
path = 'http://192.168.0.6:808/num_data'
context.addFile(path)
rdd = context.parallelize(np.arange(10))
def fun(iterable):
with open(SparkFiles.get('num_data')) as f:
value = int(f.readline())
return [x*value for x in iterable]
print(rdd.mapPartitions(fun).collect())
context.stop()

运行sparksubmit http_addFile.py
从上面的三个例子中,可以看出addFile方法的强大之处。借助该方法,在pyspark里任务运行中可以读取几乎任何位置的文件来参与计
算!
5. applicationId,用于获取注册到集群的应用的id

from pyspark import SparkContext ,SparkConf
import numpy as np
conf = SparkConf()
conf.set('master','spark://hadoop-maste:7077')
context = SparkContext(conf=conf)
rdd = context.parallelize(np.arange(10))
print('applicationId:',context.applicationId)
print(rdd.collect())
context.stop()
  1. binaryFiles读取二进制文件。
    该方法用于读取二进制文件例如音频、视频、图片,对于每个文件器返回一个tuple,tuple的第一个元素为文件的路径,第二个参数为二
    进制文件的内容。
    我在hdfs的/datas/pics文件目录下上传了两张图片,使用binaryFiles读取/datas/pics目录中的二进制图片数据
    新建binaryFiles.py文件,内容如下:
from pyspark import SparkContext ,SparkConf
import numpy as np
conf = SparkConf()
conf.set('master','spark://hadoop-maste:7077')
context = SparkContext(conf=conf)
rdd = context.binaryFiles('/datas/pics/')
print('applicationId:',context.applicationId)
result = rdd.collect()
for data in result:
print(data[0],data[1][:10])
context.stop()

运行spark-submit binaryFiles.py
该方法对于读取二进制文件的数据非常方便,特别是处理图片、音视频的时候。

  1. broadcast广播变量
    SparkContext上的broadcast方法用于创建广播变量,对于大于5M的共享变量,推荐使用广播。广播机制可以最大限度的减少网络IO,从而提升性能。接下来例子中,广播一个‘hello’字符串,在各个task中接收广播变量,拼接返回。新建broadcast.py文件,内容如下。
from pyspark import SparkContext ,SparkConf
import numpy as np
conf = SparkConf()
conf.set('master','spark://hadoop-maste:7077')
context = SparkContext(conf=conf)
broad = context.broadcast(' hello ')
rdd = context.parallelize(np.arange(27),3)
print('applicationId:',context.applicationId)
print(rdd.map(lambda x:str(x)+broad.value).collect())
context.stop()

运行spark-submit broadcast.py
从结果来看,分布式运行中的每个任务中都接收到了广播的变量hello.
在这里插入图片描述

  1. defaultMinPartitions.py 获取默认最小的分区数
from pyspark import SparkContext ,SparkConf
import numpy as np
conf = SparkConf()
conf.set('master','spark://hadoop-maste:7077')
context = SparkContext(conf=conf)
print('defaultMinPartitions:',context.defaultMinPartitions)
context.stop()
  1. emptyRDD创建一个空的RDD ,该RDD没有分区,也没有任何数据

    sc = sparkContext
    sc.emptyRDD()
    rdd.collect()
    rdd.getNumPartitions()
    

    ![(https://img-blog.csdnimg.cn/20200315175837246.png)

  2. getConf()方法返回作业的配置对象信息
    sc.getConf().toDebugString()
    在这里插入图片描述

  3. getLocalProperty和setLocalProperty获取和设置在本地线程中的属性信息。通过setLocalProperty设置,设置的属性只能对当前线程提交的作业起作用,对其他作业不起作用。key:value类型的属性

  4. setLogLevel设置日志级别,通过这个设置将会覆盖任何用户自定义的日志等级设置。取值有:ALL, DEBUG, ERROR, FATAL, INFO,OFF, TRACE, WARN通过对比两种不同的日志级别的输出,可以看出不同的日志级别的日志输出量是不同的,可以通过这一点选择合适的日志级别进行调试。
    在这里插入图片描述
    在这里插入图片描述

  5. getOrCreate得到或者是创建一个SparkContext对象,该方法创建的SparkContext对象为单例对象。该方法可以接受一个Sparkconf对象。
    在这里插入图片描述

  6. hadoopFile读取‘老’的hadoop接口提供hdfs文件格式.
    `sc.hadoopFile(’/datas/num_data’, inputFormatClass=‘org.apache.hadoop.mapred.TextInputFormat’, keyClass=‘org.apache.hadoop.io.Text’, valueClass='第一个参数为文件路径,第二个参数为输入文件的格式,第三个参数为键的格式,第四个参数为值的格式

sc.hadoopFile("/datas/num_data", inputFormatClass="org.apache.hadoop.mapred.TextInputFormat", 
	keyClass="org.apache.hadoop.io.Text", valueClass="org.apache.hadoop.io.LongWritable").collect()

在这里插入图片描述
读取出来默认会把行号作为键!

  1. textFile和saveAsTextFile读取位于HDFS上的文本文件
    这个方法读取位于hdfs上的文本类型的文件最简单

在这里插入图片描述

  1. parallelize使用python集合创建RDD,可以使用range函数,当然也可也使用numpy里面的arange方法来创建
    在这里插入图片描述

  2. saveAsPickleFile和pickleFile将RDD保存为python中的pickle压缩文件格式。

    sc.parallelize(range(100),3).saveAsPickleFile('/datas/pickles/bbb', 5)
    sorted(sc.pickleFile('/datas/pickles/bbb', 3).collect())
    

    sorted方法中使用关键字参数reverse,设置为True

  3. range(start, end=None, step=1, numSlices=None)按照提供的起始值和步长,创建RDD
    numSlices用于指定分区数

    rdd = sc.range(1,100,11,3)
    rdd.collect()
    dir(rdd)
    

    在这里插入图片描述

  4. runJob(rdd, partitionFunc, partitions=None, allowLocal=False)在给定的分区上运行指定的函数
    partitions用于指定分区的编号,是一个列表。若不指定分区默认为所有分区运行partitionFunc函数

    rdd = sc.range(1,1000,11,10)
    sc.runJob(rdd,lambda x:[a for a in x])
    

    指定在0,1,4,6分区上运行a**2函数

    rdd = sc.range(1,1000,11,10)
    sc.runJob(rdd,lambda x:[a**2 for a in x],partitions=[0,1,4,6])
    

    在这里插入图片描述

  5. setCheckpointDir(dirName)设置检查点的目录,检查点用于异常发生时错误的恢复,该目录必须为HDFS目录。
    设置检查点目录为/datas/checkpoint/

    sc.setCheckpointDir('/datas/checkpoint/')
    rdd = sc.range(1,1000,11,10)
    rdd.checkpoint()
    rdd.collect()
    

    运行完成之后,查看hdfs 的/datas/checkpoint目录
    发现有运行过程中的数据被保存下来,在Spark程序运行过程中若发生异常,将会使用检查点数据来恢复异常。
    在这里插入图片描述

  6. sparkUser获取运行当前作业的用户名
    sc.sparkUser()
    在这里插入图片描述

  7. startTime返回作业启动的时间
    sc.startTime
    它返回的是Long类型的毫秒时间值,可借助在线时间转换工具查看具体时间
    在这里插入图片描述

  8. statusTracker()方法用于获取StatusTracker对象,通过该对象可以获取活动的Jobs的id,活动的stage 的id。job的信息,stage的信息。可以使用这个对象来实时监控作业运行的中间状态数据。

    t = sc.statusTracker()
    dir(t)
    

    在这里插入图片描述

  9. stop()方法用于停止SparkContext和cluster的连接。一般在书写程序最后一行都要加上这句话,确保作业运行完成之后连接和cluster集群断开。
    sc.stop()

  10. uiWebUrl返回web的url
    sc.uiWebUrl
    在这里插入图片描述

  11. union(rdds)用合并多个rdd为一个rdd

    rdd1 = sc.parallelize(range(5),4)
    rdd2 = sc.parallelize(range(10),3)
    rdd3 = sc.union([rdd1,rdd2])
    rdd3.collect()
    

    在这里插入图片描述
    获取rdd的分区数:
    rdd.getNumPartitions()
    在这里插入图片描述

  12. version获取版本号
    sc.version
    在这里插入图片描述

发布了63 篇原创文章 · 获赞 52 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/weixin_41521681/article/details/104806417