Hadoop MapReduce统计手机流量案例学习(结合Partitioner)

统计手机上网的上行流量和下行流量
数据格式:



统计手机的 上网流量只需要“手机号”、“上行流量”、“下行流量”三个字段,根据这三个字段创建bean对象, 该对象要实现Writable接口,以便实现序列化并且要有无参构造方法,hadoop会使用反射创建对象


public class PhoneBean implements Writable {
	private String phone;
	private Long upPayLoad;
	private Long downPayLoad;
	private Long totalPayLoad;

	public PhoneBean() {
	}

	public PhoneBean(String phone, Long upPayLoad, Long downPayLoad) {
		super();
		this.phone = phone;
		this.upPayLoad = upPayLoad;
		this.downPayLoad = downPayLoad;
		this.totalPayLoad = upPayLoad + downPayLoad;
	}

	@Override
	public String toString() {
		return this.upPayLoad + "\t" + this.downPayLoad + "\t" + this.totalPayLoad;
	}

	@Override
	public void write(DataOutput out) throws IOException {
		out.writeUTF(phone);
		out.writeLong(upPayLoad);
		out.writeLong(downPayLoad);
	}

	@Override
	public void readFields(DataInput in) throws IOException {
		this.phone = in.readUTF();
		this.upPayLoad = in.readLong();
		this.downPayLoad = in.readLong();
	}
        setter/getter略
}


MapReduce程序


import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.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.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;

public class PhoneCount {

	public static class PCMapper extends Mapper<LongWritable, Text, Text, PhoneBean> {
		@Override
		protected void map(LongWritable key, Text value, Mapper<LongWritable, Text, Text, PhoneBean>.Context context) throws IOException, InterruptedException {
			String val = value.toString();
			String[] vals = val.split("\t");
			String phone = vals[1];
			Long upPayLoad = Long.parseLong(vals[8]);
			Long downPayLoad = Long.parseLong(vals[9]);
			PhoneBean bean = new PhoneBean(phone, upPayLoad, downPayLoad);           // 输出map结果 
			context.write(new Text(phone), bean);
		}
	}

	public static class PCReducer extends Reducer<Text, PhoneBean, Text, PhoneBean> {
		@Override
		protected void reduce(Text key, Iterable<PhoneBean> iterable, Reducer<Text, PhoneBean, Text, PhoneBean>.Context context) throws IOException, InterruptedException {
			Long upTotal = 0L;
			Long downTotal = 0L;
			for (PhoneBean pb : iterable) {
				upTotal += pb.getUpPayLoad();
				downTotal += pb.getDownPayLoad();
			}
                        // reduce输出结果
			context.write(key, new PhoneBean("", upTotal, downTotal));
		}
	}

	public static void main(String[] args) throws Exception {
		Configuration configuration = new Configuration();
		Job job = Job.getInstance(configuration);
// 设置jar对应的class文件
		job.setJarByClass(PhoneCount.class);
// 设置map class文件
		job.setMapperClass(PCMapper.class);
// 设置reduce class文件
                job.setReducerClass(PCReducer.class);
		job.setMapOutputKeyClass(Text.class);
		job.setMapOutputValueClass(PhoneBean.class);
                job.setMapOutputKeyClass(Text.class);
		job.setMapOutputValueClass(PhoneBean.class);
// 设置输入文件位置
		FileInputFormat.setInputPaths(job, new Path(args[0]));
// 设置输出文件位置
                FileOutputFormat.setOutputPath(job, new Path(args[1]));

		job.waitForCompletion(true);
	}
}


把需要的数据上传到hdfs,程序打包后运行

hadoop jar phone2.jar /phone/phone.dat /phone/output


通过partition对手机号进行划分,使用Map来模拟从数据库中查询出来的partition的规则


public static class PCPartitioner extends Partitioner<Text, PhoneBean> {

		private static Map<String, Integer> dataMap = new HashMap<String, Integer>();
		static {
// 第一分区
			dataMap.put("135", 1);
			dataMap.put("136", 1);
			dataMap.put("137", 1);
// 第二分区
			dataMap.put("138", 2);
			dataMap.put("139", 2);
// 第三分区
			dataMap.put("150", 3);
		}

		@Override
		public int getPartition(Text key, PhoneBean value, int numPartitions) {
			String phone = key.toString();
			String code = phone.substring(0, 3);
			Integer partition = dataMap.get(code);
			return partition == null ? 0 : partition;
		}
	}


总结:分区Partitioner主要作用在于以下两点

(1)根据业务需要,产生多个输出文件;

(2)多个reduce任务并发运行,提高整体job的运行效率

设置reduce的任务数,通过参数传入程序


		// 指定Partitioner文件
		job.setPartitionerClass(PCPartitioner.class);
// 设置Reduce任务数量
		job.setNumReduceTasks(Integer.parseInt(args[2]));


partition分了0、1、2、3个区总共四个分区, 但如果reduce的数量小于partition的会报一个IO的异常,因为每个reduce对应一个输出文件

#设置reduce的数量为3  
hadoop jar phone3.jar /phone/phone.dat /phone/output1 3  
#程序执行时的异常  
15/09/21 16:51:34 INFO mapreduce.Job: Task Id : attempt_1442818713228_0003_m_000000_0, Status : FAILED  
Error: java.io.IOException: Illegal partition for 15013685858 (3)  


如果设置的reduce的数量大于partition数量,写出的reduce文件将为空文件

#设置reduce数量为5
hadoop jar phone3.jar /phone/phone.dat /phone/output2 5

[root@centos1 sbin]# hadoop fs -ls /phone/output2
Found 6 items
-rw-r--r--   1 root supergroup          0 2015-09-21 16:53 /phone/output2/_SUCCESS
-rw-r--r--   1 root supergroup        156 2015-09-21 16:53 /phone/output2/part-r-00000
-rw-r--r--   1 root supergroup        241 2015-09-21 16:53 /phone/output2/part-r-00001
-rw-r--r--   1 root supergroup        127 2015-09-21 16:53 /phone/output2/part-r-00002
-rw-r--r--   1 root supergroup         27 2015-09-21 16:53 /phone/output2/part-r-00003
-rw-r--r--   1 root supergroup          0 2015-09-21 16:53 /phone/output2/part-r-00004



partiton的注意事项:
1、partition规则要清晰
2、reduce的数量要等于或大于partition数量


转自: http://mvplee.iteye.com/blog/2245011

  • 大小: 53.8 KB
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
近几年,云计算产业飞速发展,大数据处理技术也在不断成熟。与此同时,国内移动互联网市场规模不断扩大,用户数量已经超过5亿,并带来了海量的移动互联网流量数据。在此背景下,如何基于云计算大数据处理技术来承载海量网络数据处理业务,是一个非常有研究价值的课题。从移动互联网的现状来看,一方面移动数据流量猛增,给运营商带来了巨大的运营压力,需要其投入更多的资金来进行网络建设与升级,另一方面由于移动数据业务增长,传统的语音短信等业务出现下滑,导致运营商出现增量不增收的现状。因此研究如何使用通过流量通道获取到的海量移动互联网数据流量资源,对于电信运营商有着十分重大的意义。针对移动互联网流量数据的特性,本文对基于Hadoop的海量网络数据处理平台的关键技术进行了深入研究。具体来说,本文的主要研究内容和创新点如下: 1.提出了一种针对移动互联网的海量数据处理架构针对移动互联网中海量网络数据处理业务的特点和存在的问题进行相关研究,提出了一种承载海量网络数据处理业务的分布式数据采集、存储和分析的安全云计算平台架构。整个平台包含数据采集,数据存储,数据处理及流量安全检测四个部分,可以完美解决移动互联网流量数据从数据的采集到最后的数据处理这一业务流程,通过引入云计算技术实现了对海量数据的存储及高效的数据处理,并基于云计算技术进行快速的异常流量检测来提高该平台的安全性。通过实验和具体的实际应用证明了该架构的可行性,且优化技术的应用对于提高海量网络数据处理业务的服务质量和安全性都有着明显的效果,后续基于该平台架构对其中的关键技术进行深入研究。 2.提出了一种基于分布式故障检测机制的高可靠数据采集框架数据采集是海量网络数据处理业务的首要工作,只有保证采集数据的完整和可信,后续进行的数据处理工作结果才有意义和价值。因此本文首先针对当前移动互联网流量数据采集的技术特点和难点进行了详细分析,包括分布式、高动态性、采集终端多样性、节点异构等等,然后针对这些数据采集的难度问题,本文引入了分布式网络故障检测技术,设计了一种适合移动互联网网络流量数据采集机制的分布式节点监控框架,该框架中提出了应用于数据采集的节点故障检测与处理算法和节点负载均衡算法,实现对海量网络数据采集框架的节点进行实时监控,并提供快速高效的故障检测机制,避免数据丢失。同时,该算法还实现了对节点的负载进行动态均衡,防止某些节点出现负载过重的情况。实验结果表明,该分布式节点监控框架,能够实现采集节点故障检测的快速处理和节点负载的动态均衡,保障移动互联网流量数据采集的可靠性和完整性。 3.提出了一种异构环境下的高效数据存储机制针对当前基于Hadoop的海量网络数据处理平台中数据存储问题,本文对分布式数据存储技术进行深入研究,并结合服务器性能评估技术提出了一种适用于异构环境下的高效数据存储算法。该算法在存储数据时引入节点的性能参数,并将节点间的数据块分布与节点性能相关联。一方面,该算法可以提高大数据的读写效率,另一方面可以提高后续数据处理作业的运行速率,提高数据本地化的任务比率。最后实验证明,该算法可以有效地提高存储空间利用率和异构云计算集群的数据处理性能。 4.提出了一种基于节点动态性能推断的任务分配算法海量网络数据的处理分析是海量网络数据处理平台最为核心的功能,数据处理的效率关系到整个海量网络数据处理平台的性能,因此对于该平台数据处理性能的优化是本文需要考虑的关键问题。当前,在构建云平台时,需要根据需求对云平台的硬件进行逐步扩容和升级,因此集群往往存在着硬件异构的情况。默认的数据处理计算主要是针对同构集群设计,在异构集群中性能会有很大程度的降低。因此结合当前海量网络数据处理平台的集群现状,本文研究并设计一种基于节点动态性能推断的任务分配算法。首先该算法在主节点中引入了节点动态性能推断模块,该模块采用基于指数平滑预测法实现对该集群中运行的作业历史数据学习分析,从而计算出集群中各个节点的计算能力。然后本文结合集群节点的性能指标对Reduce任务分配算法和推测性任务执行机制进行改进,实现集群可以动态选择最佳节点来运行数据处理任务。实验结果表明该算法可以有效地提高异构集群数据处理性能和集群的稳定性,减少异构集群的计算资源浪费,提高了云计算平台的资源利用率。5.一种基于分类器联合的分布式异常流量检测算法海量网络数据处理平台中存在着大量的实时数据流,该数据具有价值高、流量大等特点。同时,云计算平台本身具有强大的计算能力和存储资源,极易成为黑客的攻击目标。而云计算的环境极其复杂和多样化,具有跨地域、异构化、虚拟化等特点,使用传统的网络安全防御技术已经无法满足云计算的信息安全防御需求。因此在传统网络安全防御技术的基础上,本文需要进一步加强云平台的安全保障。针对当前海量网络数据处理平台的业务特点,本文对异常流量检测技术和云计算技术的结合进行了相关研究,提出了一种基于云计算技术的分类器联合检测算法。该算法联合了无监督的模糊K-均值分类算法和有监督的朴素贝叶斯分类算法,有效地避免单一分类算法在检测大流量数据时的缺陷,更为全面地对网络流量进行异常检测。同时,本文基于Mahout技术实现了这两个分类算法在MapReduce框架上的海量数据流的分类计算,极大地提高了异常流量检测的效率。最后通过实验证明,基于分类器联合的分布式异常流量检测算法可以快速有效地对海量网络数据流进行检测,并保持较高的检测准确率和较低的误报率。该算法可以有效地提高云平台的安全性,是对云平台网络安全防御体系的有效补充。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值