Spark RDD


def compute(split: Partition, context: TaskContext): Iterator[T]


protected def getPartitions: Array[Partition]


protected def getDependencies: Seq[Dependency[_]] = deps


protected def getPreferredLocations(split: Partition): Seq[String] = Nil

@transient val partitioner: Option[Partitioner] = None

only for key-value  


narrow-dependency:
分区: 与父RDD一致
依赖: 与父RDD一对一
函数: transformation 映射 
最佳位置: no
分区策略: no


joined-RDD:
分区: 每个reduce一个分区
依赖: 宽依赖,多个或所有父RDD
函数:  shuffle后的数据
最佳位置: no
分区策略: HashPartitioner(partitions: Int)

宽依赖 窄依赖
宽依赖    子RDD的partition 依赖于所有父RDD partitions 
         影响:如果父节点挂掉,将需要恢复所有父节点后才能计算子节点; 不能并行计算
窄依赖    子RDD的partition  只依赖于最多一个RDD partition
         影响:如果父节点挂掉,只需恢复最多一个父节点; 可以完全并行计算

-> 关键点是 在stage分界点位置(shuffle处需要宽依赖的父节点要落地persist)


transformation


--map:

*自定义函数处理方式
JavaRDD<Integer> lineLengths = lines.map(newFunction<String, Integer>() {
  publicInteger call(String s) {returns.length(); }
});
--mapPartitions:
//iter 表示 每个分区的迭代器,不是每个元素
val a = sc.parallelize(1 to 9, 3)
def myfunc[T](iter: Iterator[T]) : Iterator[(T, T)] = {
    var res = List[(T, T)]() 
    var pre = iter.next while (iter.hasNext) {
        val cur = iter.next; 
        res .::= (pre, cur) pre = cur;
    } 
    res.iterator
}
a.mapPartitions(myfunc).collect
 Array((2,3), (1,2), (5,6), (4,5), (8,9), (7,8))

--mapPartitionsWithIndex
var rdd1 = sc.makeRDD(1 to 9,3)
//rdd1有两个分区
var rdd2 = rdd1.mapPartitionsWithIndex{
        (x,iter) => {
          var result = List[String]()
            var i = 0
            while(iter.hasNext){
              i += iter.next()
            }
            result.::(x + "|" + i).iterator
           
        }
      }
//rdd2将rdd1中每个分区的数字累加,并在每个分区的累加结果前面加了分区索引
scala> rdd2.collect
res13: Array[String] = Array(0|6, 1|15, 2|24)
--mapValues
val a = sc.parallelize(List("dog", "tiger", "lion", "cat", "panther", " eagle"), 2)
val b = a.map(x => (x.length, x))
b.mapValues("x" + _ + "x").collect
b.mapValues("x" + _ + "x").reduceByKey(_+_).collect  //这里的mapValues只是map value,reduceByKey里的key仍然是元祖的key,即tuple.1

--mapWith
val x = sc.parallelize(List(1,2,3,4,5,6,7,8,9,10), 3) 
x.mapWith(a => a * 10)((a, b) => (b + 2)).collect 
=> partition index  乘以10  -> (0,1,2)
def mapWith[A: ClassTag, U: ](constructA: Int => A, preservesPartitioning: Boolean = false)(f: (T, A) => U): RDD[U]
第一个函数constructA是把RDD的partition index(index从0开始)作为输入,输出为新类型A;
第二个函数f是把二元组(T, A)作为输入(其中T为原RDD中的元素,A为第一个函数的输出),输出类型为U。
注意使用 sc.parallelize(***,N) 表示把数据集分成N块,每块执行相应function

引用: http://blog.youkuaiyun.com/lfz_carlos/article/details/50753695


       http://lxw1234.com/archives/2015/07/348.htm

Action







基于可靠性评估序贯蒙特卡洛模拟法的配电网可靠性评估研究(Matlab代码实现)内容概要:本文围绕“基于可靠性评估序贯蒙特卡洛模拟法的配电网可靠性评估研究”,介绍了利用Matlab代码实现配电网可靠性的仿真分析方法。重点采用序贯蒙特卡洛模拟法对配电网进行长时间段的状态抽样与统计,通过模拟系统元件的故障与修复过程,评估配电网的关键可靠性指标,如系统停电频率、停电持续时间、负荷点可靠性等。该方法能够有效处理复杂网络结构与设备时序特性,提升评估精度,适用于含分布式电源、电动汽车等新型负荷接入的现代配电网。文中提供了完整的Matlab实现代码与案例分析,便于复现和扩展应用。; 适合人群:具备电力系统基础知识和Matlab编程能力的高校研究生、科研人员及电力行业技术人员,尤其适合从事配电网规划、运行与可靠性分析相关工作的人员; 使用场景及目标:①掌握序贯蒙特卡洛模拟法在电力系统可靠性评估中的基本原理与实现流程;②学习如何通过Matlab构建配电网仿真模型并进行状态转移模拟;③应用于含新能源接入的复杂配电网可靠性定量评估与优化设计; 阅读建议:建议结合文中提供的Matlab代码逐段调试运行,理解状态抽样、故障判断、修复逻辑及指标统计的具体实现方式,同时可扩展至不同网络结构或加入更多不确定性因素进行深化研究。
<think>好的,用户想了解Spark RDD的使用和概念。首先我需要回顾一下RDD的基本定义和核心特性。根据引用[3],RDD是弹性分布式数据集的缩写,是Spark对不可变分布式数据集的抽象。这意味着RDD代表一个可以并行操作的元素集合,具有容错性。 接下来,我需要解释RDD的五大特性,包括分区、依赖关系、计算函数、分区器以及优先位置。这些都是RDD的核心概念,用户需要清楚这些特性如何支持容错和高效计算。 然后要讲RDD的创建方式。常见的有从外部数据源加载,比如HDFS或本地文件系统,或者通过转换已有的RDD生成新的RDD。需要举一些例子,比如parallelize方法或者textFile方法。 关于RDD的操作,分为转换(Transformations)和动作(Actions)。转换是惰性的,只有触发动作时才会执行。这里可以举一些常用的转换和动作的例子,如map、filter、reduceByKey,以及collect、count等。同时要注意区分宽依赖和窄依赖,宽依赖会触发shuffle,影响性能。 容错机制方面,RDD通过血统(Lineage)来恢复丢失的分区。每个RDD记录了自己是如何从其他RDD转换而来的,这样在节点失败时可以根据这些信息重新计算丢失的数据,而不需要复制多份数据。 另外,用户可能对RDDSpark生态系统中的位置感兴趣。比如,DStream是Spark Streaming的基础,由一系列RDD组成,如引用[1]和[2]提到的。而结构化流(Structured Streaming)则是基于DataFrame,优化更多,但底层可能还是利用了RDD的特性。 需要提到RDD的适用场景,比如需要低延迟操作、精细控制数据分区,或者使用非结构化数据时。同时也要指出当需要更高级优化时,DataFrame或Dataset可能更合适,如引用[5]提到的转换器和预测器的例子,虽然那更多是ML库的内容,但能说明生态系统的多样性。 最后,生成的相关问题需要覆盖RDD与其他组件的比较,比如DStream和DataFrame,以及优化方法、容错机制和适用场景。这样用户如果有进一步的问题,可以继续深入。</think>### Spark RDD 核心概念与使用详解 #### 一、RDD 基础定义 **弹性分布式数据集(Resilient Distributed Dataset, RDD)** 是 Spark 的底层核心抽象,代表一个**不可变、分区的数据集合**,支持并行操作[^3]。其核心特性可总结为五大要素: - **分区列表**:数据被划分为多个分区(Partition),每个分区在集群节点上分布式存储 - **依赖关系**:记录父 RDD 到子 RDD 的转换关系(窄依赖/宽依赖) - **计算函数**:用于从父 RDD 计算当前分区的函数 - **分区器**:定义数据分布规则(如 HashPartitioner) - **优先位置列表**:标识数据分片的最佳计算位置(数据本地性优化) #### 二、RDD 创建方式 1. **从外部数据源加载**: ```python # 从本地文件创建 rdd = sc.textFile("hdfs://path/to/file.txt") # 从集合创建 rdd = sc.parallelize([1,2,3,4,5]) ``` 2. **通过转换操作生成**: ```python mapped_rdd = rdd.map(lambda x: x*2) filtered_rdd = rdd.filter(lambda x: x>3) ``` #### 三、核心操作类型 | 操作类型 | 特点 | 示例 | |---------|------|------| | **Transformations**(转换) | 惰性执行,生成新 RDD | `map()`, `filter()`, `groupByKey()` | | **Actions**(动作) | 触发实际计算 | `collect()`, `count()`, `saveAsTextFile()` | | **宽依赖操作** | 涉及数据重分布(Shuffle) | `join()`, `reduceByKey()` | #### 四、容错机制 通过**血统(Lineage)**实现容错: $$ \text{RDD}_n = f(\text{RDD}_{n-1}) = f_{n} \circ f_{n-1} \circ \cdots \circ f_1(\text{原始数据}) $$ 当某个分区丢失时,Spark 可根据这个依赖链重新计算该分区[^3]。 #### 五、应用模式示例 ```python # 词频统计经典案例 lines = sc.textFile("hdfs://...") words = lines.flatMap(lambda line: line.split(" ")) pairs = words.map(lambda word: (word, 1)) counts = pairs.reduceByKey(lambda a,b: a+b) counts.saveAsTextFile("hdfs://output") ``` #### 六、与流处理的关联 在 Spark Streaming 中,DStream 本质上是**时间维度上的 RDD 序列**: $$ \text{DStream} = \{ \text{RDD}_t \mid t \in \text{时间窗口} \} $$ 每个微批处理实际上是对 RDD 的操作[^1][^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值