大數據之統計股票開盤和收盤平均價

一、說明:該實驗環境是基於虛擬機Ubuntuhadoopeclipsemapreduce

1、MapReduce模型簡介:

  •MapReduce將複雜的、運行於大規模集羣上的並行計算過程高度地抽象到了兩個函數:MapMap 任務 (分割及映射)ReduceReduce 任務 (重排,還原)

  •編程容易,不需要掌握分佈式並行編程細節,也可以很容易把自己的程序運行在分佈式系統上,完成海量數據的計算

  •MapReduce採用“分而治之”策略,一個存儲在分佈式文件系統中的大規模數據集,會被切分成許多獨立的分片(split),這些分片可以被多個Map任務並行處理

  •MapReduce設計的一個理念就是“計算向數據靠攏”,而不是“數據向計算靠攏”,因爲,移動數據需要大量的網絡傳輸開銷

  •MapReduce框架採用了Master/Slave架構,包括一個Master和若干個Slave。Master上運行JobTracker,Slave上運行TaskTracker

  •Hadoop框架是用Java實現的,但是,MapReduce應用程序則不一定要用Java來寫

2、詳細的整個過程

映射的任務是爲每個分割創建在分割每條記錄執行映射的函數。

有多個分割是好處的, 因爲處理一個分割使用的時間相比整個輸入的處理的時間要少, 當分割比較小時,處理負載平衡是比較好的,因爲我們正在並行地處理分割。

然而,也不希望分割的規模太小。當分割太小,管理分割和映射創建任務的超負荷開始逐步控制總的作業執行時間。

對於大多數作業,最好是分割成大小等於一個HDFS塊的大小(這是64 MB,默認情況下)。

map任務執行結果到輸出寫入到本地磁盤的各個節點上,而不是HDFS。

之所以選擇本地磁盤而不是HDFS是因爲,避免複製其中發生 HDFS 存儲操作。

映射輸出是由減少任務處理以產生最終的輸出中間輸出。

一旦任務完成,映射輸出可以扔掉了。所以,複製並將其存儲在HDFS變得大材小用。

在節點故障的映射輸出之前,由 reduce 任務消耗,Hadoop 重新運行另一個節點在映射上的任務,並重新創建的映射輸出。

減少任務不會在數據局部性的概念上工作。每個map任務的輸出被供給到 reduce 任務。映射輸出被傳輸至計算機,其中 reduce 任務正在運行。

在此機器輸出合併,然後傳遞到用戶定義的 reduce 函數。

不像到映射輸出,reduce輸出存儲在HDFS(第一個副本被存儲在本地節點上,其他副本被存儲於偏離機架的節點)。因此,寫入 reduce 輸出

二、實際運用(股票統計)

1、需要處理的股票數據文件夾內容(export

2、其中一個文件部分內容

 

3、編碼解析:

1map函數分割:

 public static class Map extends Mapper<Object,Text,Text,Text>{           
        private Text text = new Text();   
        private Text keys = new Text();  
        private int no = 0;  
 
        public void map(Object key,Text value,Context context)throws IOException,InterruptedException{  
            String line = value.toString();  
            this.no +=1;              
            System.out.println(this.no+line);             
            String[] lines = line.split("\\s+");  
            for(int i =0;i<lines.length;i++){  
                System.out.print(lines[i]+" ~~");  
            }  
            if(this.no == 1){             
                this.keys.set("股票編碼:"+lines[0]);              
            }  
            if(this.no > 2){  
                if(lines.length == 7){  
                    this.text.set(lines[0]+"+"+lines[1]+"+"+lines[4]);   
                    System.out.println(this.no+"---->"+lines[0]+"+"+lines[1]+"+"+lines[4]);  
                    context.write(this.keys, this.text);  
                }                 
            }                  
        }  
}  

2reduce函數還原:

public static class Reduce extends Reducer<Text,Text,Text,Text>{        
        private Text text = new Text();       
        public void reduce(Text key,Iterable<Text> values,Context context) throws IOException, InterruptedException{  
                double sum1 = 0.0;  
                double sum2 = 0.0;  
                int n = 0;                
                System.out.println("...................start"+key.toString());  
                Iterator<Text> $it = values.iterator();  
                while($it.hasNext()){                     
                    String record =$it.next().toString();  
                    System.out.println(n);                    
                    System.out.println("原始數據:"+record);  
                    n++;                      
                    System.out.println("第"+n+"次循環");  
                    String []result = record.split("[+]");  
                    System.out.println(Double.valueOf(result[1])+" "+Double.valueOf(result[2]));  
                    sum1 +=(Double.valueOf(result[1])*100);                   
                    sum2 +=(Double.valueOf(result[2])*100);                   
                    System.out.println(sum1/100+" "+sum2/100);                    
                }  
                System.out.println("最後的結果:"+sum1/100+" "+sum2/100);  
                double openPrise = sum1/(100*n);  
                double closePrise = sum2/(100*n);  
                openPrise = (double)Math.round(openPrise*100)/100;  
                closePrise = (double)Math.round(closePrise*100)/100;  
                System.out.println("平均值:"+openPrise+" "+closePrise);         
                Double.toString(closePrise);  
                String result ="開盤平均價:"+Double.toString(openPrise)+",   收盤平均價:"+Double.toString(closePrise);  
                this.text.set(result);  
                context.write(key, this.text);     
        }  
    }  

4、部分結果顯示

 

5、完整代碼:

import java.io.IOException;  
import java.util.Iterator;  
import org.apache.hadoop.conf.Configuration;  
import org.apache.hadoop.fs.Path;  
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.lib.input.FileInputFormat;  
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;  
import org.apache.hadoop.util.GenericOptionsParser;  
  
public class  Data{  
 
    public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {  
        Configuration conf = new Configuration();  
        conf.set("fs.default.name", "hdfs://localhost:9000");  
        String[] otherArgs = (new GenericOptionsParser(conf,args)).getRemainingArgs();  
        if(otherArgs.length<2){  
            System.err.println("Usage:Data<in><out>");  
            System.exit(2);  
        }  
        Job job = Job.getInstance(conf,"Data");  
        job.setJarByClass(Data.class);  
        job.setMapperClass(Data.Map.class);  
        System.out.println("Mapper over");  
        job.setReducerClass(Data.Reduce.class);  
        System.out.println("Reduce over");  
        job.setOutputKeyClass(Text.class);  
        job.setOutputValueClass(Text.class);  
        System.out.println("all over");  
        for(int i = 0;i<otherArgs.length-1;i++){  
            FileInputFormat.addInputPath(job, new Path(otherArgs[i]));  
        }         
        FileOutputFormat.setOutputPath(job, new Path(otherArgs[otherArgs.length-1]));         
        System.exit(job.waitForCompletion(true)?0:1);  
} 
 
    public static class Map extends Mapper<Object,Text,Text,Text>{           
        private Text text = new Text();   
        private Text keys = new Text();  
        private int no = 0;  
 
        public void map(Object key,Text value,Context context)throws IOException,InterruptedException{  
            String line = value.toString();  
            this.no +=1;              
            System.out.println(this.no+line);             
            String[] lines = line.split("\\s+");  
            for(int i =0;i<lines.length;i++){  
                System.out.print(lines[i]+" ~~");  
            }  
            if(this.no == 1){             
                this.keys.set("股票編碼:"+lines[0]);              
            }  
            if(this.no > 2){  
                if(lines.length == 7){  
                    this.text.set(lines[0]+"+"+lines[1]+"+"+lines[4]);   
                    System.out.println(this.no+"---->"+lines[0]+"+"+lines[1]+"+"+lines[4]);  
                    context.write(this.keys, this.text);  
                }                 
            }                  
        }  
}  
    
    public static class Reduce extends Reducer<Text,Text,Text,Text>{        
        private Text text = new Text();       
        public void reduce(Text key,Iterable<Text> values,Context context) throws IOException, InterruptedException{  
                double sum1 = 0.0;  
                double sum2 = 0.0;  
                int n = 0;                
                System.out.println("...................start"+key.toString());  
                Iterator<Text> $it = values.iterator();  
                while($it.hasNext()){                     
                    String record =$it.next().toString();  
                    System.out.println(n);                    
                    System.out.println("原始數據:"+record);  
                    n++;                      
                    System.out.println("第"+n+"次循環");  
                    String []result = record.split("[+]");  
                    System.out.println(Double.valueOf(result[1])+" "+Double.valueOf(result[2]));  
                    sum1 +=(Double.valueOf(result[1])*100);                   
                    sum2 +=(Double.valueOf(result[2])*100);                   
                    System.out.println(sum1/100+" "+sum2/100);                    
                }  
                System.out.println("最後的結果:"+sum1/100+" "+sum2/100);  
                double openPrise = sum1/(100*n);  
                double closePrise = sum2/(100*n);  
                openPrise = (double)Math.round(openPrise*100)/100;  
                closePrise = (double)Math.round(closePrise*100)/100;  
                System.out.println("平均值:"+openPrise+" "+closePrise);         
                Double.toString(closePrise);  
                String result ="開盤平均價:"+Double.toString(openPrise)+",   收盤平均價:"+Double.toString(closePrise);  
                this.text.set(result);  
                context.write(key, this.text);     
        }  
    }  
}  


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章