1、MapReduce实验报告 硕 士 研 究 生 实 践 报 告 题 目 作者姓名 作者学号 指导教师 学科专业 所在学院 提交日期 一 题目要求我们的项目背景是,可穿戴设备的实时数据分析。1.txt记录的是某一个用户的心跳周期数据,每一个数值表示一次心跳的周期,单位是秒。例如,0.8表示用户当时的心跳间隙是0.8秒。心跳间期按照顺序存储。1. 利用Hadoop的MapReduce框架编写程序,计算出总测量时间和平均心跳间期,即求和与求平均。请写出程序,并在实验报告中简单描述你的思路。2. 探索Spark的Transformation中的mapPartition,写出示例程序,并思考何时会用到m
2、apPartition,为什么要用它?3. 探索Spark的Transformation中的flatMap,写出示例程序,并思考何时会用到它,为什么要用到它。4. (选做)SD1和SD2是表征心率变异性的一种指标。结合发给你们的论文,用Java或者Scala实现SD1和SD2的计算(不用考虑并行化,普通的Java或Scala程序即可)。5. (选做)假设我们同时监控100个用户的心率,是否能够利用Spark的RDD的特性,并行地计算SD1和SD2?(提示:把每一个用户的心率数据作为RDD里面的一个元素,RDD中不同的元素表示不同用户的心率数据,利用map对每一个用户的心率数据进行并行分析)。请
3、描述设计思路,并尽可能实现一个多用户心率监控的计算程序。二 题目实现第一题:本题就是利用Hadoop的MapReduce框架编写程序,计算出总测量时间和平均心跳间期,即求和与求平均,程序代码如下:package cn.ideas.item1;import java.io.DataInput;import java.io.DataOutput;import java.io.IOException;import org.apache.hadoop.io.Writable;public class InfoBean implements Writable private double sumHear
4、tRate; private double avgHeartRate; public double getSumHeartRate() return sumHeartRate; Override public String toString() return sumHeartRatet+this.sumHeartRate+tavgHeartRatet+this.avgHeartRate; public void setSumHeartRate(double sumHeartRate) this.sumHeartRate = sumHeartRate; public double getAvgH
5、eartRate() return avgHeartRate; public void setAvgHeartRate(double avgHeartRate) this.avgHeartRate = avgHeartRate; public void set(double sumHeartRate, double avgHeartRate) this.sumHeartRate = sumHeartRate; this.avgHeartRate = avgHeartRate; public void readFields(DataInput in) throws IOException thi
6、s.sumHeartRate = in.readDouble(); this.avgHeartRate = in.readDouble(); public void write(DataOutput out) throws IOException out.writeDouble(this.sumHeartRate); out.writeDouble(this.avgHeartRate); package cn.ideas.item1;import java.io.IOException;import org.apache.hadoop.conf.Configuration;import org
7、.apache.hadoop.fs.Path;import org.apache.hadoop.io.LongWritable;import org.apache.hadoop.io.Text;import org.apache.hadoop.mapreduce.Job;import org.apache.hadoop.mapreduce.Mapper;import org.apache.hadoop.mapreduce.Reducer;import org.apache.hadoop.mapreduce.Reducer.Context;import org.apache.hadoop.map
8、reduce.lib.input.FileInputFormat;import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;public class SumStep public static class SumMapper extends Mapper private Text K = new Text(); private InfoBean V = new InfoBean(); Override protected void map(LongWritable key, Text value, org.apache.had
9、oop.mapreduce.Mapper.Context context) throws IOException, InterruptedException String line = value.toString(); double sum = Double.parseDouble(line); K.set(sum); V.set(sum,0.0); context.write(K, V); public static class SumReducer extends Reducer private InfoBean v = new InfoBean(); Override protecte
10、d void reduce(Text key, Iterable values, Context context) throws IOException, InterruptedException double in_sum = 0; int count = 0; for(InfoBean bean : values) in_sum += bean.getSumHeartRate(); count+; v.set(in_sum,in_sum/count); context.write(key, v); public static void main(String args) throws Ex
11、ception Configuration conf = new Configuration(); Job job = Job.getInstance(conf); job.setJarByClass(SumStep.class); job.setMapperClass(SumMapper.class); job.setMapOutputKeyClass(Text.class); job.setMapOutputValueClass(InfoBean.class); FileInputFormat.setInputPaths(job, new Path(args0); job.setReduc
12、erClass(SumReducer.class); job.setOutputKeyClass(Text.class); job.setOutputValueClass(InfoBean.class); FileOutputFormat.setOutputPath(job,new Path(args1); job.waitForCompletion(true); 本题设计思路相当简单,InfoBean中封装了两个属性sumHeartRate 和avgHeartRate,分别表示了总的心率和平均心率,因为在传输过程中要保证对象是可序列化的,所以实现了Writable接口。在map中的处理,只是
13、将读取的文本中的值进行了转型,我这里处理的是double类型,然后,将所有的键同一位”sum” 以便在reduce的时候将所有的对象放在一个集合中。Reduce中实现的就是对map传过来合并后的集合进行一个遍历,累加求和,顺便用count计数,最后实现平均值的计算将程序打包后上传到linux系统,把数据上传到hdfs下,然后执行,结果如图所示:第二题:mapPartitions是map的一个变种。map的输入函数是应用于RDD中每个元素,而mapPartitions的输入函数是应用于每个分区,也就是把每个分区中的内容作为整体来处理的。它的函数定义为:def mapPartitionsU: Cl
14、assTag(f: IteratorT = IteratorU, preservesPartitioning: Boolean = false): RDDUf即为输入函数,它处理每个分区里面的内容。每个分区中的内容将以IteratorT传递给输入函数f,f的输出结果是IteratorU。最终的RDD由所有分区经过输入函数处理后的结果合并起来的。实验例子上述例子中的函数myfunc是把分区中一个元素和它的下一个元素组成一个Tuple。因为分区中最后一个元素没有下一个元素了,所以(3,4)和(6,7)不在结果中。mapPartitions主要是对不同分区进行处理,应用场景:当对大量数据进行处理的时
15、候,我们一般是采用分区的手段,将分区后的数据分发到分布式系统的不同机器上,然后用mapPartitions来处理不同的分区,这样效率会更加快,体现出mapPartitions的优势了。第三题:faltMap与map类似,区别是原RDD中的元素经map处理后只能生成一个元素,而原RDD中的元素经flatmap处理后可生成多个元素来构建新RDD。举例:对原RDD中的每个元素x产生y个元素(从1到y,y为元素x的值)通过flatMap我们可以处理元素是序列的列表。将提供的函数应用于每个序列元素会返回包含原始列表所有序列内的元素的列表。例2:我们可以看到有list4的元素是两个列表。我们调用flatM
16、ap分别处理这两个列表,并用map将这两个列表的元素平方,最后的结果是一个包含所有元素的平坦的列表。flatMap还可以去除无用的None,例3:总的来说,flatMap就是对序列进行处理的函数,场景大致就是上面三种情况,从上面例子可以看出,flatMap在处理序列方面是相当方便的,故用之。第四题:通过论文,我们可以得出:由论文提取公式,我们知道这是一个纯数学题了,接下来编写算法实现代码:val inFile=sc.textFile(/rate.txt)var rates=inFile. map (_. toDouble).toArrayvar length = rates.length-1v
17、ar yavg=(rates.sum-rates(0)/lengthvar xavg = (rates.sum-rates(length)/lengthdef myfunc(iter: IteratorDouble,sd:Int) : Double = var SDsum=0.0; var temp=0.0; var pre= iter.next; while (iter.hasNext) var cur = iter.next; if(sd = 1) temp =(pre - cur)+(yavg - xavg); else if(sd = 2) temp =(pre + cur)-(yav
18、g + xavg); var Xi = math.pow(temp,2)/2; SDsum+=Xi; pre = cur; math.sqrt(SDsum/length)var SD1= myfunc(rates.iterator,1)var SD2= myfunc(rates.iterator,2)运行过程:实验结果:.0355*SD2 = 0.199*863102第五题:由于spark 中RDD的分布式特点,RDD的数据是分布在集群中的不同机器上,我们利用RDD来存储数据则可获取到分布式计算的优点。题目要求实现多用户的心率数据测试,而目前测试数据只有一个(不是重点,重要的是思路),我就将其
19、复制为5份,分别命名为rate1.txt、rate2.txt、rate3.txt、rate4.txt、rate5.txt,将它们上传到HDFS中,然后利用循环来读取这几个文件,将其存入Listorg.apache.spark.rdd.RDDString()中,最后利用map函数对list中的各个RDD都进行心率计算(计算逻辑是和第四题是一样的),这样便实现了多用户心率的并行计算。代码:var listRDD = Listorg.apache.spark.rdd.RDDString();for(ivar rates=rdd.map(_.toDouble).toArray;var length=r
20、ates.length-1;var yavg=(rates.sum-rates(0)/length;var xavg = (rates.sum-rates(length)/length;var SD1= myfunc(rates.iterator,1);SD1)listRDD.map(rdd=var rates=rdd.map(_.toDouble).toArray;var length=rates.length-1;var yavg=(rates.sum-rates(0)/length;var xavg = (rates.sum-rates(length)/length;var SD2= myfunc(rates.iterator,2);SD2)实验结果:5个用户的SD1数据为:List(0.03552829191459,0.03552829191459,0.03552829191459,0.03552829191459,0.03552829191459)5个用户的SD2数据为:List(0.19914955267863102,0.19914955267863102,0.19914955267863102,0.19914955267863102,0.19914955267863102)数据都是复制第一份的,所以5个用户的结果是一样的。
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1