Spark指令参数,RDD--学习笔记

本文详细介绍了Spark的指令参数,包括运行模式、应用名称、配置选项以及RDD(弹性分布式数据集)的使用,如数据转换、分区、算子(map和flatMap)的应用。同时提到了如何在实际场景中合理配置和优化Spark任务的性能。
摘要由CSDN通过智能技术生成

1,Spark的指令参数

参数对spark所有指令都有效

Spark指令参数

 # 表示引用运行的模式,要么是本地local要么是集群(Standalone、YARN、Mesos)了
    --master MASTER_URL
    # 本地模式∶local[2]  数字表示可以使用到本地的cpu核心数,  loacl[*]  *表示自动判断
    # Standalone集群∶spark∶//xxx∶7077,yyy∶7077 
    # YARN 集群∶ yarn 
    
    # 表示的是应用运行的名称,通常在应用开发的时候指定
    --name NAME 
    
    # 表示应用运行时指定的某些参数配置,http∶//spark.apache.org/docs/2.2.0/configuration.html
    # 当value中的值有空格组成的时候,使用双引号将key=value引起来
    # 可以不用在bashrc写配置可以通过conf配置,每次运行都要指定很麻烦
    --conf "PROP=VALUE"
    # 第一种方式∶属性的值中没有空格
    --conf spark.eventLog.enabled=false
    # 第二种方式∶属性的值中有空格,将属性和值统一使用双引号引起来
    --conf "spark.executor.extraJavaOptions=-XX:+PrintGCDetails -XX:+PrintGCTimestamps"
    
    
    # Driver相关配置  对driver一般不用配置
    # 指定Driver Program JVM进程内存大小,默认值为1g
    --driver-memory MEM
    
    # 表示Driver 运行CLASS PATH路径,使用不多
    --driver-class-path
    
    # Spark standalone with cluster deploy mode∶运行在standalone 中cluster Deploy Mode 默认值为1  cpu核心数量
    # 运行在YARN in cluster mode,默认值是1 
    --driver-cores NUM 
    
    # 运行在standalone的 中cluster Deploy Mode下,表示当Driver运行异常失败,可以自己重启
    --supervise 
    
    
    # Executor运行所需内存大小
    --executor-memory MEM 
    
    # Execturor 运行的CPU Cores,默认的情况下,在Standalone集群上为worker节点所有可用的Cpu Cores,在YARN集群下为1 
    --executor-cores NUM
    
    # 表示运行在Standalone集群下,所有Executor的CPU Cores,结合--executor-cores计算出Executor个数
    --total-executor-cores
    
    # 表示在YARN集群下,Executor的个数,默认值为2
    --num-executors
    
    
    # 表示Drive Program运行的地方,也叫做应用部署模式,默认值为client,通常在生产环境中使用cluster
    --deploy-mode DEPLOY_MODE

saprk指令使用参数举例

交互式中的设置

pyspark --master yarn --name yarn_demo --conf "PYSPARK_PYTHON=/export/server/anaconda3/bin/python3"

saprk脚本式使用参数举例

    from pyspark import SparkContext
    from pyspark import SparkConf
    
    #指定driver和executor的参数(这里指定没用,只能在spark-submit中指定才会生效)
    #conf = SparkConf().set('driver-memory','2g').set('num-executors','3')
    
    
    sc = SparkContext(master='yarn',appName='yarn_demo')
    
    rdd1 = sc.parallelize([1,2,3,4])
    res = rdd1.reduce(lambda a,b:a+b)
    print(res)

spark-submit指令

实际生产中使用的提交spark计算任务的方式

1,Spark-submit --参数名 参数值.py文件

2,–deploy-mode 只能和yarn模式一起使用

两种模式cluster ,driver进程由yarn服务选择资源充足的服务器创建,生成环境中

或者client,driver进程中由提交服务器创建,测试环境中

命令:

spark-submit  --master yarn  --name yarn_demo   --deploy-mode  cluster  执行文件.py

2,RDD的介绍

概念:弹性分布式数据集合,是Spark中最基本的数据抽象,代表一个不可变可分区,里面的元素可并行计算的集合

RDD是一种弹性分布式数据集合, 是spark中最基本的数据类型。

弹性:可以对海量数据根据需求分成多份(分区),每一份数据会由对应的task线程执行计算

分布式:使用多台服务器的计算资源

数据集合:规定了spark中数据的形式,类似于python中的列表[]

RDD可以看作是Spark的一个对象,它本身运行于内存中

RDD的特性

分区:可以将计算的海量数据分成多份,需要分成多少个分区可以通过方法指定

每个分区都可以对应一个task线程执行计算

只读:

rdd中的数据不能直接修改,需要同通过方法计算后得到一个新的rdd

rdd本身存储的数据只能读取

依赖:

rdd之间是有以来关系的

新的rdd是通过旧的rdd计算得到

缓存:

将中间计算得到的rdd进行缓存操作,

保存在内存中或磁盘中

容错机制

缓存rdd随着spark应用程序执行结束后自动清空

checkpoint:监测点

将中间计算的到的rdd进行checkpoint操作

保存在HDFS中,永久持久化

3,rdd创建

1,python数据转换

    from pyspark import SparkContext
    
    sc= SparkContext()
    
    str1 = 'sdf'
    int1 = 234    #不能转换
    float1 = 34.34   #不能转换
    boo11 = True     #不能转换
    
    list1 = [1,23,4,5,5]
    dict1 = {'asdf':'adsff','et':10}
    
    set1 = {1,3,4,6,67}
    tuple1 = (1,3,5)
    
    #字符串属于可迭代对象,不可迭代的对象无法转为rdd数据
    rdd_str1 = sc.parallelize(str1)
    print(rdd_str1)
    res = rdd_str1.collect()
    print(res)
    
    
    #直接遍历字典获取到的时key值
    rdd_str2 = sc.parallelize(dict1.values())
    print(rdd_str2)
    res = rdd_str2.collect()
    print(res)

2,文件数据转化为rdd

   from pyspark import SparkContext
    
    
    # 创建sc对象
    sc = SparkContext()
    
    # 读取文件数据转换成rdd textFile()
    """
    默认读取HDFS上的文件数据 hdfs://ip:8020(可以省略) port为8020->服务端的端口号
    也可以读取服务器本地上的文件数据  file://
    
    路径可以是文件路径,也可以是目录路径(读取目录下的所有文件生成一个rdd对象)
    文件中的一行数据就是rdd中一个元素
    """
    # 读取hdfs上的文件
    # 指定文件路径
    # 省略 hdfs://node1:8020
    rdd1 = sc.textFile('/test/words.txt')
    res1 = rdd1.collect()
    print(res1)
    # 指定目录路径
    rdd2 = sc.textFile('hdfs://node1:8020/test')
    res2 = rdd2.collect()
    print(res2)
    
    # 读取服务器上本地文件
    # file://
    # 指定文件路径
    rdd3 = sc.textFile('file:///root/test/words.txt')
    res3 = rdd3.collect()
    print(res3)
    # 指定目录路径
    rdd4= sc.textFile('file:///root/test')
    res4 = rdd4.collect()
    print(res4)

3,创建rdd时指定分区


    from pyspark import SparkContext
    #分区数等于task线程数
    sc = SparkContext()
    #查看分区数
    print(sc.defaultParallelism)
    #结果为2
    
    #调整列表分区数通过修改numSlices
    rdd1 = sc.parallelize([1,2,3,4],numSlices=3)
    #借助glom()方法查看rdd的分区数据
    res1 =  rdd1.glom().collect()
    res2 = rdd1.collect()
    
    print(res1)
    print(res2)
    
    #读取文件数据时进行分区数指定通过修改defaultParallelism
    #参数说明minPartitions:最小分区数,不指定是从defaultParallelism和2中取最小值
    rdd2 = sc.textFile('file:///root/test/words.txt',minPartitions=4)
    # #借助glom()方法查看rdd的分区数据
    res3 = rdd2.glom().collect()
    #打印未查看分区数的数据
    res2 = rdd2.collect()
    
    print(res3)
    print(res2)
    
    # [['hadoop,flink,spark,hive'], ['hive,spark,python,java'], ['python,itcast,itheima']]
    # ['hadoop,flink,spark,hive', 'hive,spark,python,java', 'python,itcast,itheima']
    

4,小文件数据读取转化为rdd

一个分区对应一个task线程,当小文件过多时,会占用大量的线程,造成资源浪费

使用wholeTextFiles方法解决


    # rdd的分区数指定
    from pyspark import SparkContext
    
    # 生成SparkContext类对象
    sc = SparkContext()
    
    # 文件数据指定分区数  ,读取目录下的多个小文件
    rdd  = sc.textFile('/data')
    # glom()按照分区查看数据
    res = rdd.glom().collect()
    # 每个小文件的数据会单独存放一个分区
    # 一个分区会对应一个task执行计算
    # 当目录下小文件数据较多时,会产生很多task。task较多时会抢占计算资源影响计算速度
    # 10条数据文件100个  1万条数据文件10个
    # 将小文件合并 一个分区数据 1000条数据在一个分区,对应一个task线程
    print(res)
    print(len(res))
    
    # wholeTextFiles读取目录中的多个小文件数据
    rdd2= sc.wholeTextFiles('/data')
    res = rdd2.glom().collect()
    print(res)
    print(len(res))

5,手动修改rdd分区数

    from  pyspark import  SparkContext
    
    
    sc = SparkContext()
    
    rdd1  = sc.parallelize([1,2,3,4,5,5,67])
    print(rdd1.glom().collect())
    
    #调整rdd的分区数,可以增加和减少分区数
    #调整后的数据一定会发生shuffle过程
    #增加分区数
    rdd2 = rdd1.repartition(numPartitions=5)
    print(rdd2.glom().collect())
    #减少分区数
    rdd3 = rdd2.repartition(numPartitions=2)
    print(rdd3.glom().collect())
    
        """"
    调整rdd的分区数时,如果数据发生shuffle,需要使用repartition方法,效率低
    减少rdd的分区数时,如果数据不发生shuffle,需要使用coalesce方法,效率高
    """
    
    
    #coalesce()修改分区数
    #减少分区数,不能增加
    #默认不发生shuffle
    rdd4 = rdd1.coalesce(numPartitions=1)
    print(rdd4.glom().collect())
    
    #repartition()修改rdd分区数 此方法等同于coalesce(numPartitions,shuffle=True)的操作

4,RDD算子

4.1概念

rdd算子就是对rdd对象进行操作的方法1

rdd算子分类

transformation算子->转化算子 得到一个新的rdd对象,定义了一个计算任务

action算子->执行算子 得到最终的结果,执行了定义好的计算任务

5.2常用的transformation算子(方法)

map()

转化算子,对旧rdd数据1进行转化操作,得到新的rdd

此方法不会改变新rdd的数据结构

rdd的每个元素经过传入函数转化后,将函数的返回值保存到列表中


    """
    rdd.map(func)方法
    rdd对象经过func函数处理得到新的rdd,不会改变新rdd的数据结构
    
    """
    
    from pyspark import SparkContext
    
    sc = SparkContext()
    
    rdd1 = sc.parallelize([1,2,34,4])
    
    #定义函数
    def func1(a):
        print(a)
        return str(a)
    
    def func2(b):
        print(b)
        return [b]
    
    #使用map算子对rdd1进行处理
    rdd2 = rdd1.map(func1)
    print(rdd2.collect())
    print(rdd2)
    
    rdd3 = rdd1.map(func2)
    print(rdd3)
    print(rdd3.collect())
    
    #map可以接受匿名函数(以后计算常用)
    #匿名函数最主要的是清楚x这个参数里面的内容
    rdd4 = rdd1.map(lambda x:[x])
    print(rdd4.collect())

flatMap()

转化算子,对旧rdd数据进行转化操作,得到新的rdd,将新的rdd扁平化(降维)

此方法会改变新rdd的数据结构例如[[1,2],[3,4]]会变成[1,2,3,4]

将新的rdd中的每个元素进行拆解保存到列表中

主要处理的是二位嵌套列表数据

    from pyspark import SparkContext
    
    """
    
    flatMap适用于处理嵌套的rdd对象[[],[]]
    例:[[1,2,34,4],[1,23,54]] 返回[1, 2, 34, 4, 1, 23, 54]
    """
    
    sc = SparkContext()
    
    rdd1 = sc.parallelize([[1,2,34,4],[1,23,54]])
    
    
    def func1(x):
        return x
    
    rdd_map1 =  rdd1.map(func1)
    print(rdd_map1.collect())
    
    
    rdd_ma2 = rdd1.map(lambda x:x.append(10))
    print(rdd_ma2.collect())
    
    def func2(x):
        print(x)
        x.append(10)
        print(x)
        return x
    
    rdd_map3 = rdd1.map(func2)
    print(rdd_map3.collect())
    
    
    #调用flatMap()
    
    rdd_flatMap1 = rdd1.flatMap(func1)
    print(rdd_flatMap1.collect())
    
    rdd_flatMap2 = rdd1.flatMap(func2)
    print(rdd_flatMap2.collect())
    
    #匿名函数,结果和func1一样
    rdd_flatMap3 = rdd1.flatMap(lambda x:x)
    print(rdd_flatMap3.collect())
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

祈愿lucky

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值