iterator方法的实现在RDD抽象类中,代码如下。
iterator方法首先检查当前RDD的存储级别,如果存储级别为none,说明分区的数据要么已经存储在文件系统当中,要么当前RDD曾经执行过cache、persise等持久化操作,因此需要想办法把数据从存储介质中提取出来。iterator方法继续调用CacheManager的getOrCompute方法,代码如下。
iterator方法首先检查当前RDD的存储级别,如果存储级别为none,说明分区的数据要么已经存储在文件系统当中,要么当前RDD曾经执行过cache、persise等持久化操作,因此需要想办法把数据从存储介质中提取出来。iterator方法继续调用CacheManager的getOrCompute方法,代码如下。
getOrCompute方法会根据RDD编号与分区编号计算得到当前分区在存储层对应的块编号,通过存储层提供的数据读取接口提取出块的数据。这时候会有如下的两种可能情况发生。
1)数据之前已经存储在存储介质当中,可能是数据本身就在存储介质(如读取HDFS中的文件创建得到的RDD)当中,也可能是RDD经过持久化操作并经历了一次计算过程。这时候就能成功提取得到数据并将其返回。
2)数据不在存储介质当中,可能是数据已经丢失,或者RDD经过持久化操作,但是当前分区数据是第一次被计算,因此会出现拉取得到数据为none的情况。这就意味着需要计算分区数据,继续调用RDD类computeOrReadCheckpoint方法,并将计算得到的数据缓存到存储介质中,下次就无需再重复计算。
如果当前RDD的存储级别为none,说明为未经持久化的RDD,需要重新计算RDD内的数据,这时候调用RDD的computeOrReadCheckpoint方法,该方法也在持久化RDD的分区获取数据失败时被调用。computeOrReadCheckpoint的代码如下。(www.xing528.com)
getOrCompute方法会根据RDD编号与分区编号计算得到当前分区在存储层对应的块编号,通过存储层提供的数据读取接口提取出块的数据。这时候会有如下的两种可能情况发生。
1)数据之前已经存储在存储介质当中,可能是数据本身就在存储介质(如读取HDFS中的文件创建得到的RDD)当中,也可能是RDD经过持久化操作并经历了一次计算过程。这时候就能成功提取得到数据并将其返回。
2)数据不在存储介质当中,可能是数据已经丢失,或者RDD经过持久化操作,但是当前分区数据是第一次被计算,因此会出现拉取得到数据为none的情况。这就意味着需要计算分区数据,继续调用RDD类computeOrReadCheckpoint方法,并将计算得到的数据缓存到存储介质中,下次就无需再重复计算。
如果当前RDD的存储级别为none,说明为未经持久化的RDD,需要重新计算RDD内的数据,这时候调用RDD的computeOrReadCheckpoint方法,该方法也在持久化RDD的分区获取数据失败时被调用。computeOrReadCheckpoint的代码如下。
computeOrReadCheckpoint方法会检查当前RDD是否已经被标记成检查点,如果未被标记成检查点,则执行自身的compute方法来计算分区数据,否则就直接拉取父RDD分区内的数据。需要注意的是,对于标记成检查点的情况,当前RDD的父RDD不再是原先转换操作中提供数据的父RDD,而是被Spark替换成一个CheckPoint对象,该对象中的数据存放在文件系统中,因此最终该对象会从文件系统中读取数据并返回给computeOrReadCheckpoint方法。
computeOrReadCheckpoint方法会检查当前RDD是否已经被标记成检查点,如果未被标记成检查点,则执行自身的compute方法来计算分区数据,否则就直接拉取父RDD分区内的数据。需要注意的是,对于标记成检查点的情况,当前RDD的父RDD不再是原先转换操作中提供数据的父RDD,而是被Spark替换成一个CheckPoint对象,该对象中的数据存放在文件系统中,因此最终该对象会从文件系统中读取数据并返回给computeOrReadCheckpoint方法。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。