【笔记】大数据运算系统3_内存计算系统Spark

— Outline

  • 1.原理
    • 1.1 基础数据结构RDD
    • 1.2 两类RDD运算
  • 2.编程
    • 2.1 java RDD的输入
      • 2.1.1 从输入文件产生RDD
      • 2.1.2 程序产生RDD
    • 2.2 JavaRDD Transformation
    • 2.3 JavaRDD Action
    • 2.4 举例
      • 2.4.1 word count
      • 2.4.2 PageRank
  • 3.系统实现
  • 4.Spark SQL & Streaming

— 内容

  • Spark:面向大数据分析的内存系统。Berkeley AMP Lab研发,可以从HDFS读数据,但是运算中数据放在内存中,不使用Hadoop,而是新实现了分布式的处理。目标是低延迟的分析操作。
  • Spark思路
    • 内存容量越来越大;把数据放入多台机器的内存以避免HDFS的开销。
1.原理
1.1 基础数据结构RDD(Resilient Distributed Data sets)
  • 一个分布式数据集
  • 只读(数据集创建后不能修改)
  • 通常进行整个数据集的运算
  • 优点
    • 并发控制被简化
    • 可记录lineage(数据集上的运算序列),可重新计算
      RDD与一般分布式内存的区别
1.2 两类RDD运算
  • Transformation
    • 输入是RDD;输出是RDD;RDD–>RDD。
  • Action
    • 输入是RDD;输出是某种计算结果(如一个数值或一列数值);RDD–>计算结果。
    • RDD可能非常大,但是计算结果总是比较小的。
  • 运算过程:读入内存一次,在内存中可以多次处理
2.编程
  • scala
    • spark支持的主要语言之一
    • 一种新的程序设计语言(面向目标的、函数型)
    • 在JVM上执行
  • 用java做和scala一样的事情

    图中红下划线部分是java lambda表达式,可以将其看作是一个匿名的函数,箭头左侧是函数的输入参数,右侧是函数体({return s.contains(“b”)})
2.1 java RDD的输入
  • Class JavaRDD< T >:元素类型为T的RDD
  • Class JavaPairRDD<K, V>:元素包含一个K和一个V
    transform
2.1.1 从输入文件产生RDD
JavaRDD<String> distFile = sc.textFile("data.txt")
  • sc是Class JavaSparkContext的一个对象
  • 从文本文件读入数据,生成JavaRDD,每个元素是一行文本String
2.1.2 程序产生RDD
Lsit<Integer> data = Arrays.asList(1,2,3,4,5);
JavaRDD<Integer> distData = sc.parallelize(data);
  • 用parallelize函数把一个list转换为JavaRDD
2.2 JavaRDD Transformation

举例

  • 1.map举例
B = A.map(x->x+1)  //integer->integer
B = A.map(x->new Double(x+1))  //integer->double
  • 2.flatMap举例
words = list.flatMap(s->Arrays.aslist(SPACE.split(s)).iterator());  //分词

举例2

  • 3.reduceByKey举例
counts = ones.reduceByKey((x,y)->x+y)  //对相同key的value进行求和归并
2.3 JavaRDD Action

在这里插入图片描述

2.4 举例
2.4.1 word count
public static void main(String[] args) throws Exception{
	if(args.length < 1){
		System.err.println("Usage: JavaWordCount <file>");
		System.exit(1);
	}
	SparkSession spark = SparkSession
	.builder()
	.appName("JavaWordCount")
	.getOrCreate();
	JavaRDD<String> lines = spark.read().textFile(args[0]).javaRDD();  //读文本文件生成JavaRDD
	JavaRDD<String> words = lines.flatMap(s->Arrays.aslist(SPACE.split(s)).iterator());  //FlatMap把每行切分成单词,words是所有词组成的RDD
	JavaPairRdd<String,Integer> ones = words.mapToPairs(s -> new Tuple2<>(s,1));  //mapToPair将每个word变为(word,1)
	JavaPairRdd<String,Integer> counts = ones.reduceByKey((i1,i2) -> i1+i2);  //计算词频
	List<Tuple2<String,Integer>> output = counts.collect();  //collect把计算结果作为数组返回
	for(Tuple2<?,?> tuple :output){
		System.out.println(tuple._1() + ":" + tuple._2());
	}
	spark.stop();
}
2.4.2 PageRank
public static void main(String[] args) throws Exception{
	if(args.length < 1){
		System.err.println("Usage: JavaPageRank <file>");
		System.exit(1);
	}
	SparkSession spark = SparkSession
	.builder()
	.appName("JavaPageRank")
	.getOrCreate();
	JavaRDD<String> lines = spark.read().textFile(args[0]).javaRDD();  //读文本文件生成JavaRDD,每一行元素是一行文本包括URL起点和beighbor URL终点
	//mapToPair生成JavaPairRDD,每个元素是边(起点,终点);
	//distinct去除相同的边;groupByKey按照起点对边分组,links<起点,Iterable<终点>>
	JavaPairRdd<String,Interable<String>> links = lines.mapToPair(s -> {String[] parts = SPACE.split(s);return new Tuple2<>(parts[0],parts[1]);}).distinct().groupByKey().cache();
	JavaPairRDD<String,Double> ranks = links.mapValues(rs -> 1.0);  //ranks<起点,1.0>
	/***
	*links和ranks做join后:<起点,Iterable<终点>,rank>,其value部分为<Iterable<终点>,rank>
	*urlCount是出度;
	*contribs<终点,rank / 出度>
	*mapValues是key不变,在value上调用func得到<终点,sum -> 0.15 + sum * 0.85>作为新的rank
	**/
	for(int current = 0; current < Integet.parseInt(args[1]); current++){
		JavaPairRDD<String, Double> contribs = links.join(ranks).values()
		.flatMapToPairs(s -> {
			int urlCount = Iterable.size(s._1());
			List<Tuple2<String,Double>> results = new ArrayList<>();
			for(String n : s._1){
				results.add(new Tuple2<>(n, s._2() / urlCount));
			}
			return results.iterable();
		});
		ranks = contribs.reduceByKey(a, b->a+b).mapValues(sum -> 0.15 + sum * 0.85);
	}
	List<Tuple2<String,Double>> output = ranks.collect();  //collect把计算结果作为数组返回
	for(Tuple2<?,?> tuple :output){
		System.out.println(tuple._1() + ":" + tuple._2());
	}
	spark.stop();
}
3.系统实现
  • 运算过程:读入内存一次,在内存中可以多次处理
    RDD存储
  • spark运算的运行
    • 1.transformation:仅记录,不运算;Lazy execution;
    • 2.action:当遇到action时,需要返回结果,才真正执行已经记录的前面的运算
    • 3.容错/内存缓冲替换:当内存缓冲的RDD丢失时。可以重新执行记录的运算,重新计算这个RDD
4.Spark SQL & Streaming
  • dataFrame
    • 1.可以看作是在RDD上定义了Relational Schema
    • 2.列可以命名访问
DataSet<Row> df = spark.read().load("file path");  //从文件中读取数据
df.printSchema();  //表属性
df.show();  //数据
df.select("name").show();  df.select(col("name"), col("age").plus(1)).show();  //投影
df.filter(col("age").gt(21)).show();  //选择条件
df.groupBy("age").count().show();  //group by + aggregation
  • SQL语句
df.createOrReplaceTempView("people");  //先对表命名
DataSet<Row> sqlDF = spark.sql("select * from people");
sqlDF.show();
  • Spark Streaming
    streaming
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值