spark RDD ,wordcount案例解析

spark RDD ,wordcount案例解析


spark RDD 内存计算模型



数据来源:可以从HDFS文件,Hive表,Hbase,本地磁盘,MQ
spark集群,RDD中的数据都是存放在worker,都分区的,你就可以简单的理解为worker就是分区,一个worker里面可以有多个partition

Master 主节点将rdd划分为3个patition,存放数据源,在worker迭代计算

流程简单总结:
数据源如果是HDFS,那么RDD就读取hdfs的文件,如果是Hive,那么就是Hive中具体的表;如果MQ(Kafka),就是Kafka中的某一个topic;如果是一个Hbase,就是Hbase中的某一张表;如果是local那么就是本地文件,注意:RDD加载好数据之后,在内存中对数据进行分区partition-==>分布式保存rdd数据,—>master会分配相应的worker节点对这些partition中的数据进行分布式迭代计算—->结果落地到各种介质中


SparkRDD 基于内存的计算流程+MR的区别

Spark RDD 和 MR2的区别 :

  1. mr2只有2个阶段,数据需要大量访问磁盘,数据来源相对单一 ,spark RDD ,可以无数个阶段进行迭代计算,数据来源非常丰富,数据落地介质也非常丰富
  2. spark计算基于内存,mr2需要频繁操作磁盘IO
  3. 需要 大家明确的是如果是SparkRDD的话,你要知道每一种数据来源对应的是什么

Spark的核心流程

  1. RDD从数据源加载数据,将数据放到不同的partition
  2. 针对这些partition中的数据进行迭代式计算
  3. 计算完成之后,落地到不同的介质当中

wordcount案例之scala&java实现[local]

object ScalaWordCountLocal {
  def main(args: Array[String]): Unit = {
/**
* 创建sparkconf
* 创建sparkContontext
* */
val sc = new SparkContext("local","ScalaWordCountLocal",new SparkConf())
val lines = sc.textFile("E:/123.txt")
lines.flatMap(_.split(" ")).map((_,1)).reduceByKey(_+_).foreach(tuple
=> println(tuple._1+"\t"+tuple._2))
  }
}

以上代码可以进行拆分,接下来我们进行拆分

 def chafen(): Unit ={
val sparkConf = new SparkConf().setAppName("ScalaWordCountLocal").setMaster("local")
val sc= new SparkContext(sparkConf)
val lines = sc.textFile("E:/123.txt")
val words = lines.flatMap(_.split(" "))
val wordTuple = words.map((_,1))
val wcRDD = wordTuple.reduceByKey((_+_))
wcRDD.foreach(println)
  }

再赠送一份java版的代码

/**
 *  基于java的spark的本地wordcount案例
 *  要进行spark迭代式计算,就需要首先获取最开始的rdd数据源
 *  ==> 通过sparkContext对象来获取rdd
 *  ==> 想要通过sparkContext上下文对象,需要先获取SparkConf配置文件信息
 */
public class JavaWordCountLocalApplication {
public static void main(String[] args) {
//第一步:加载sparkConf配置信息
SparkConf conf = new SparkConf();
conf.setAppName(JavaWordCountLocalApplication.class.getSimpleName());
/**
 * 这里书写的是spark的运行模式
 * local 表示在本地运行,sparkContext也在本地,会开启一个线程来运行
 * local[k] 表示在本地运行,sparkContext也在本地,会开启K个线程
 * spark ==> spark://master:7070 --->spark standalone模式,程序的调度是spark自身
 *  DAGScheduler、TASKScheduler
 *
 *  yarn 将spark 的运行调度交给了yarn
 *  yarn-client --> sparkContext在本地,rdd运行在集群
 *  yarn-cluster--> sparkContext和rdd都运行在集群中
 *  mesos
 *  spark调度就交给了mesos
 * */
conf.setMaster("local");
//第二步:创建sparkContext
JavaSparkContext sc = new JavaSparkContext(conf);
//第三步:加载RDD数据源
JavaRDD linesRDD = sc.textFile("E:/123.txt");
System.out.println("default patitions nums: "+ linesRDD.getNumPartitions());

//进行迭代计算
JavaRDD wordsRDD = linesRDD.flatMap(new FlatMapFunction() {
public Iterable call(String lines) throws Exception {
//将每一行的数据进行切割
return Arrays.asList(lines.split(" "));
}
});
//进行map 动作,将每一个单词加一发送出去
JavaPairRDD wordRDD = wordsRDD.mapToPair(new PairFunction() {
public Tuple2 call(String word) throws Exception {
return new Tuple2(word,1);
}
});
JavaPairRDD wcRDD = wordRDD.reduceByKey(new Function2() {
public Integer call(Integer v1, Integer v2) throws Exception {
return v1+v2;
}
});
/**
 * 注意 :
 *  spark中额这些rdd都是懒加载的
 *  将上面的迭代计算中各个步骤称之为transformation
 *  需要通过各种各样的action去触发
 * */
wcRDD.foreach(new VoidFunction>() {
public void call(Tuple2 tuple) throws Exception {
System.out.println("word: "+ tuple._1 +",count:"+tuple._2);
}
});
}
}

WordCound运行原理

client端 Driver:

  1. 向spark集群提程序,spark - submit
  2. 需要初始化 sparkContext
    在生产环境中一般都是一台单独的物理机,只要能够连接上spark集群就可以了

sc.textFile(“hdfs://ns1/data/hello”) [source:HDFS的文件或者一个目录下面所有的文件]

处理过程

  1. 数据经过初始化RDD的创建,会分发到不同的patition中(操作都是RDD分区中的数据)
  2. flatMap(_.split(” “)),经过处理,分割成以单词为单元
  3. map(word => (word,1)) ,map 阶段,将各个partitions中的单元进行 标记 1
    生成一个个tuple(word,1)
  4. reduceByKey(v1,v2) =>v1+v2 ,在本地进行ShuffleRDD,ShuffleRDD对数据进行预处理,(word,2) 也是RDD的宽依赖
  5. 落地

你可能感兴趣的:(土肥圆的猿,的博客专栏)