Spark中RDD数据结构的理解

Spark在国内的大量普及,越来越多人学习Spark技术,作为Spark Core中最重要的数据结构RDD,是学习Spark重点之一

RDD(Resilient Distributed Datasets,弹性分布式数据集),是Spark最为核心的概念,自然也是理解Apache Spark 工作原理的最佳入口之一。

分布式数据集:顾名思义,可以把数据分配到不同的节点上,但是在spark中,分布式数据集则是封装了计算逻辑的概念

其特点如下:

➢ 弹性
⚫ 存储的弹性:内存与磁盘的自动切换;
⚫ 容错的弹性:数据丢失可以自动恢复;
⚫ 计算的弹性:计算出错重试机制;
⚫ 分片的弹性:可根据需要重新分片。
➢ 分布式:数据存储在大数据集群不同节点上
➢ 数据集:RDD 封装了计算逻辑,并不保存数据
➢ 数据抽象:RDD 是一个抽象类,需要子类具体实现
➢ 不可变:RDD 封装了计算逻辑,是不可以改变的,想要改变,只能产生新的 RDD,在
新的 RDD 里面封装计算逻辑
➢ 可分区、并行计算

 

用以下代码来模拟RDD,辅助理解RDD在Spark运行过程中是如何在Driver 和 Excetor 中传输

使用一个 Driver 和两个excetor 类来模拟

任务类

class Task extends Serializable {

    val datas = List(1,2,3,4)

    //val logic = ( num:Int )=>{ num * 2 }
    val logic : (Int)=>Int = _ * 2
}

 子任务类

class SubTask extends Serializable {
    var datas : List[Int] = _
    var logic : (Int)=>Int = _

    // 计算
    def compute() = {
        datas.map(logic)
    }
}

excetor1

object Executor {

    def main(args: Array[String]): Unit = {

        // 启动服务器,接收数据
        val server = new ServerSocket(9999)
        println("服务器启动,等待接收数据")

        // 等待客户端的连接
        val client: Socket = server.accept()
        val in: InputStream = client.getInputStream
        val objIn = new ObjectInputStream(in)
        val task: SubTask = objIn.readObject().asInstanceOf[SubTask]
        val ints: List[Int] = task.compute()
        println("计算节点[9999]计算的结果为:" + ints)
        objIn.close()
        client.close()
        server.close()
    }
}

excetor2

object Executor2 {

    def main(args: Array[String]): Unit = {

        // 启动服务器,接收数据
        val server = new ServerSocket(8888)
        println("服务器启动,等待接收数据")

        // 等待客户端的连接
        val client: Socket = server.accept()
        val in: InputStream = client.getInputStream
        val objIn = new ObjectInputStream(in)
        val task: SubTask = objIn.readObject().asInstanceOf[SubTask]
        val ints: List[Int] = task.compute()
        println("计算节点[8888]计算的结果为:" + ints)
        objIn.close()
        client.close()
        server.close()
    }
}

driver

object Driver {

    def main(args: Array[String]): Unit = {
        // 连接服务器
        val client1 = new Socket("localhost", 9999)
        val client2 = new Socket("localhost", 8888)

        val task = new Task()

        val out1: OutputStream = client1.getOutputStream
        val objOut1 = new ObjectOutputStream(out1)

        val subTask = new SubTask()
        subTask.logic = task.logic
        subTask.datas = task.datas.take(2)

        objOut1.writeObject(subTask)
        objOut1.flush()
        objOut1.close()
        client1.close()

        val out2: OutputStream = client2.getOutputStream
        val objOut2 = new ObjectOutputStream(out2)

        val subTask1 = new SubTask()
        subTask1.logic = task.logic
        subTask1.datas = task.datas.takeRight(2)
        objOut2.writeObject(subTask1)
        objOut2.flush()
        objOut2.close()
        client2.close()
        println("客户端数据发送完毕")
    }
}

其中Task类就类似余RDD模型,当然只是粗略的,其中还有很多细节

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值