大数据处理的畅想

传统的三层架构:

  1. 应用层向数据库查取数据;
  2. 应用层处理取得的数据;
  3. 应用层保存处理后的新数据到数据库。
    典型的来说,应用层和数据库部署在不同的计算节点上.
    那这个过程简单来说,就是把数据移到计算程序中,再从程序中移回数据库。

大数据的新状态

  1. 数据量大
    显然把数据移来移去, 首先是浪费网络带宽,更重要的是网络因素成了计算能力的可靠性和可用性的瓶颈
  2. 计算过程,期望可以通过增加计算程序(节点)来增加计算能力
    计算方式,需要支持并行计算(可分可合)

现有的方案

期望

  1. 计算程序就在数据所在的节点上进行计算;
  2. 计算程序可以采用多节点并行计算;
  3. 可以表达数据分区策略。
  4. 并行的计算结果可以正确的合成。

Spark

目标比较关注spark.RDD很好的实现了数据分区,并行计算。

  val charsCount = sc.textFile("data.txt")
          .map(s => s.length)
          .reduce((a, b) => a + b)

上面其实是定义一个 以RDD为定点,以transformation类操作(map,reduce, ...)为邻边的DAG图。这个图会被发送到spark集群的所有计算节点上。目标数据也会被分区处理。
直到这里,计算过程也并没有被执行。只有执行action类操作,才会执行:

   charsCount.take(1)

RDD

从这个DAG,RDD --transformation Ops--> RDD,可以想见它的通用和抽象:
2700189451603187250

  1. 任何数据源只要包装成RDD,就可以加入spark集群计算;
  2. transformation类操作,可以有分支,产生不同目标的计算结果
  3. 除了数据源和计算结果,中间节点都是RDD

数据分区

实现上,它其实并不简单。考虑2类transformation操作:filter 和 groupByKey
他们对数据分区的影响是不一样的:
filter(以及sample,map,flatMap,...) 只需要在现有分区内操作即可;
groupByKey(以及reduceByKey, combineByKey, join, ...), 则会触发数据重新分区;

前者称为narrow transformation, 后者称为 wide transformation

对我们开发者来说,就要考虑DAG中计算路径,也就是transformation类操作序列的设计:

  1. wide transformation 操作越少越好
  2. wide transformation 涉及的数据量越少越好
  3. rdd.cache()rdd.persist() 需要好好用起来

Back to top

comments powered by Disqus