深入浅出Spark(二) 什么是RDD

CharlotteOF 8年前
   <p><img src="https://simg.open-open.com/show/abba4d181b581054f94460b6fab0c2e3.png"></p>    <p>本系列讲座是沁原对Sameer Farooqui的《Advanced Apache Spark》的解说。</p>    <p>完整视频: <a href="/misc/goto?guid=4959676853307876060" rel="nofollow,noindex"> https://www. bittiger.io/videos/NBAT gDTurWQmEqNQ6/HbcfjrPGxJHvKyzQR?utm_source=zhihu&utm_medium=zhihuAirticle&utm_content=Article817Post&utm_campaign=zhihu </a></p>    <p>原始视频参考 <a href="/misc/goto?guid=4959676853393220825" rel="nofollow,noindex"> https://www. 油Tube.com/watch? v=7ooZ4S7Ay6Y </a></p>    <p>(二)什么是RDD?</p>    <p>1. RDD的官方定义</p>    <p>RDD是Spark中的数据抽象,意思是弹性分布式数据集。在逻辑上是一个数据集,在物理上则可以分块分布在不同的机器上并发运行。RDD的数据具有不可变性(immutable)</p>    <p><img src="https://simg.open-open.com/show/298c538bbd04bb69635854a67e9a4347.png"></p>    <p>图.1. 一个逻辑RDD在物理上分块存储在不同的服务器。</p>    <p>如图所示,一个RDD数据集被分成了五块,运行在了三个worker服务器上。第一台上运行了两个RDD数据块,第二台上运行两个RDD数据库块,第三台上运行剩下的一个数据块。</p>    <p>2. RDD的生命周期</p>    <p>在Spark程序中,首先要读取或创建RDD, 然后对数据进行一系列的变换操作(Transform),保存中间结果(Cache),最后对变换结果进行处理(Action)</p>    <p>2.1 RDD的产生可以通过对内存中的数据并行化,或直接读取分布式数据库(S3, HDFS, Cassandra 等等)而来。</p>    <p><img src="https://simg.open-open.com/show/6761b1328441be04a13955edce54fda3.png"></p>    <p>图.2. 通过parallelize接口,将内存数据变成RDD。(图中sc指的是spark context实例。)</p>    <p><img src="https://simg.open-open.com/show/a66f76a6cfd7a3b1b57e2264693bbebc.png"></p>    <p>图.3. 直接读取文件生成RDD.</p>    <p>2.2. RDD支持数据变换接口,如常用的filter, map等等,在变换的过程中,RDD的数据并不立即发生实际变化(Lazily transform),而是保存了数据的依赖关系,直到要求RDD进行动作(Action)时。RDD会从全局的角度来优化Transform的运行过程。从而节省时间。</p>    <p>2.3 RDD的cache操作将数据的中间结果保存在内存中,方便下次使用。</p>    <p>2.4 RDD的Action操作将数据的运算结果进行统计和返回。常见的如count 和 collect.</p>    <p><img src="https://simg.open-open.com/show/88070f9503786478086fc40bae1d14de.png"></p>    <p>图.4. RDD操作实例</p>    <p>举个例子。如图4所示。从日志(Log)数据库中读取的文件生成logLinesRDD, 形成了四个物理分块。通过filter变换提取出日志中的错误信息, 形成errorsRDD。 通过合并coalesce形成两个块。进一步过滤提取只包含错误1的日志errorMsg1RDD。最后进行collect 动作, 将结果合并返回到Driver。中间结果,我们使用了count动作来返回一共有多少条错误日志 。用saveToCassandra将错误日志保存到Cassandra数据库中。图中绿色的箭头表示Action。红色箭头表示Transformation。</p>    <p>3. 根据数据源,RDD可以分成许多类,比如从Jdbc得来的RDD是JdbcRDD.</p>    <p><img src="https://simg.open-open.com/show/bb217349fdce80ed848adc437863e631.jpg"></p>    <p>图.5. RDD分类</p>    <p>每一类的RDD都定义如下几个重要的的特征。</p>    <ol>     <li> <p>如何分块。(Partition)</p> </li>     <li> <p>与父RDD的依赖关系(Dependency)</p> </li>     <li> <p>从父RDD求子RDD的函数(function)</p> </li>     <li> <p>希望当前RDD存储的位置(preferred location)</p> </li>     <li> <p>负责存储RDD的分块类(Partitioner)</p> </li>    </ol>    <p>特征2,3是保存了数据的产生方式, 当数据丢失时可以进行数据恢复。4,5是本地化存储策略。通过尽可能的本地存储来提高运算速度。</p>    <p><img src="https://simg.open-open.com/show/43981126eef413e759dfbdee2ba432b7.png"></p>    <p>例一: HadoopRDD</p>    <p>通过读HDFS生成的RDD。它的分块策略是每个HDFS块生成一个分块。该RDD没有父节点。我们希望这个RDD的数据块存在HDFS数据块相同的位置。不用进一步分块。</p>    <p><img src="https://simg.open-open.com/show/a0cedd651f9f587f39a82327e89b0115.png"> <img src="https://simg.open-open.com/show/3abd7ed9dba89bf78b9d5dfa83bfcdd8.png" alt="深入浅出Spark(二) 什么是RDD" width="550" height="213"> <img src="https://simg.open-open.com/show/32983fe603e2a088f88ddcab270b30bf.jpg"></p>    <p>例二. FilteredRDD</p>    <p>FilteredRDD产生在Filter操作后。分块与父RDD相同。与父RDD一一对应, 存储位置与父块相同。</p>    <p><img src="https://simg.open-open.com/show/3abd7ed9dba89bf78b9d5dfa83bfcdd8.png" alt="深入浅出Spark(二) 什么是RDD" width="550" height="213"> <img src="https://simg.open-open.com/show/5eb5ab441478d99547cf002c33742ff6.png"></p>    <p>例三:JoinedRDD</p>    <p>该RDD产生在shuffle操作之后。每个reduce操作有一个分区。依赖于被shuffle的父RDD。进一步分区是通过HashPartitioner实现的。</p>    <p>4. 总结</p>    <p>本节讲解了</p>    <ol>     <li> <p>什么是RDD</p> </li>     <li> <p>RDD的生命周期。 创建(Create),懒变换(Lazily Transform),缓存(Cache),和动作(Action)。</p> </li>     <li>RDD的分类和特征。</li>    </ol>    <p>本文作者Lion, 更多精彩内容,欢迎访问官网 <a href="/misc/goto?guid=4959676853478185334" rel="nofollow,noindex"> http:// BitTiger.io </a> 或关注 “论码农的自我修养” 微信公众号:bit_tiger</p>    <p> </p>    <p>来自:https://zhuanlan.zhihu.com/p/22062770</p>    <p> </p>