首页 文章 精选 留言 我的

精选列表

搜索[计费相关],共10000篇文章
优秀的个人博客,低调大师

使用Mapreduce案例编写用于统计文本中单词出现的次数的案例、mapreduce本地运行等,Combiner使用及其相关的知识,流量统计...

工程结构: 在整个案例过程中,代码如下: WordCountMapper的代码如下: package cn.toto.bigdata.mr.wc; import java.io.IOException; import org.apache.hadoop.io.IntWritable; import org.apache.hadoop.io.LongWritable; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Mapper; /** * 这里的Mapper是hadoop-mapreduce-client-core-2.8.0.jar中的内容 * Mapper<KEYIN, VALUEIN, KEYOUT, VALUEOUT> * KEYIN :是指框架读取到的数据的key的类型,在默认的InputFormat下,读到的key是一行文本的起始偏移量,所以key的类型是Long * VALUEIN :是指框架读取到的数据的value的类型,在默认的InputFormat下,读到的value是一行文本的内容,所以value的类型是String * KEYOUT :是指用户自定义逻辑方法返回的数据中key的类型,由用户业务逻辑决定,在此wordcount程序中,我们输出的key是单词,所以是String * VALUEOUT :是指用户自定义逻辑方法返回的数据中value的类型,由用户业务逻辑决定,在此wordcount程序中,我们输出的value是单词的数量,所以是Integer * * 但是,String,Long等jdk中自带的数据类型,在序列化是,效率比较低,hadoop为了提高序列化效率,自定义了一套序列化框架, * 所以,在hadoop的程序中,如果该数据需要进行序列化(写磁盘,或者网络传输),就一定要用实现了hadoop序列化框架的数据类型 * * Long ----> LongWritable * String ----> Text * Integer ----> IntWritable * Null ----> NullWritable */ public class WordCountMapper extends Mapper<LongWritable, Text, Text, IntWritable> { /** * 这就是mapreduce框架中一个主体运行程序MapTask所要调用的用户业务逻辑方法 * MapTask会驱动InputFormat去读取数据(keyIN,VALUEIN),每读到一个KV对,就传入这个用户写的map方法中调用一次 * 在默认的inputformat实现中,此处的一个key就是一行的起始偏移量,value就是一行的内容 */ @Override protected void map(LongWritable key, Text value, Mapper<LongWritable, Text, Text, IntWritable>.Context context) throws IOException, InterruptedException { String line = value.toString(); String[] words = line.split(" "); for (String word : words) { context.write(new Text(word), new IntWritable(1)); } } } WordCountReducer的代码如下: package cn.toto.bigdata.mr.wc; import java.io.IOException; import org.apache.hadoop.io.IntWritable; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Reducer; public class WordCountReducer extends Reducer<Text, IntWritable, Text, IntWritable> { /** reducetask在调我们写的reduce方法 reducetask应该收到了前一阶段(map阶段)中所有maptask输出的数据中的一部分 (数据的key.hashcode%reducetask数==本reductask号) reducetask将这些收到kv数据拿来处理时,是这样调用我们的reduce方法的: 先将自己收到的所有的kv对按照k分组(根据k是否相同) 将某一组kv中的第一个kv中的k传给reduce方法的key变量,把这一组kv中所有的v用一个迭代器传给reduce方法的变量values */ @Override protected void reduce(Text key, Iterable<IntWritable> values, Reducer<Text, IntWritable, Text, IntWritable>.Context context) throws IOException, InterruptedException { int count = 0; for(IntWritable v : values) { count += v.get(); } context.write(key, new IntWritable(count)); } } WordCountDriver的代码如下: package cn.toto.bigdata.mr.wc; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.IntWritable; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Job; import org.apache.hadoop.mapreduce.lib.input.FileInputFormat; import org.apache.hadoop.mapreduce.lib.input.TextInputFormat; import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat; /** * 本类是客户端用来指定wordcount job程序运行时所需要的很多参数: * 比如,指定用哪个组件作为数据读取器、数据结果输出器 * 指定用哪个类作为map阶段的业务逻辑类,哪个类作为reduce阶段的业务逻辑类 * 指定wordcount job程序的jar包所在路径 * .... * 运行前准备工作 * 1、将当前的工程导出成wordcount.jar * 2、准备/home/toto/software/wordcount/input/a.txt 其中a.txt中的内容类似: * The true nobility is in being superior to your previous self guess 3、将 /home/toto/software/wordcount通过 hadoop fs -put wordcount /wordcount 上传到hdfs中 * * 以及其他各种需要的参数 * hadoop jar wordcount.jar cn.toto.bigdata.mr.wc.WordCountDriver * 上面的命令等同: * java -cp wordcount.jar cn.toto.bigdata.mr.wc.WordCountDriver * * 上面的含义是通过hadoop jar将hadoop classpath的jar都拷贝到应用中,并且指定执行cn.toto.bigdata.mr.wc.WordCountDriver * * 最后查看结果的方式是:hadoop fs -cat /wordcount/output/part-r-00000,通过这个命令可以查看查看到 */ public class WordCountDriver { public static void main(String[] args) throws Exception { Configuration conf = new Configuration(); conf.set("fs.defaultFS", "hdfs://hadoop:9000"); /*conf.set("mapreduce.framework.name", "yarn"); conf.set("yarn.resourcemanager.hostname", "mini1");*/ Job job = Job.getInstance(conf); //告诉框架,我们的程序所在jar包的路径 // job.setJar("c:/wordcount.jar"); job.setJarByClass(WordCountDriver.class); //告诉框架,我们的程序所用的mapper类和reducer类 job.setMapperClass(WordCountMapper.class); job.setReducerClass(WordCountReducer.class); //告诉框架,我们的mapperreducer输出的数据类型 job.setMapOutputKeyClass(Text.class); job.setMapOutputValueClass(IntWritable.class); job.setOutputKeyClass(Text.class); job.setOutputValueClass(IntWritable.class); // 告诉框架,我们的数据读取、结果输出所用的format组件 // TextInputFormat是mapreduce框架中内置的一种读取文本文件的输入组件 job.setInputFormatClass(TextInputFormat.class); job.setOutputFormatClass(TextOutputFormat.class); // 告诉框架,我们要处理的文件在哪个路径下,注意若hdfs中已经有了/wordcount/input/这个文件,说明 FileInputFormat.setInputPaths(job, new Path("/wordcount/input/")); // 告诉框架,我们的处理结果要输出到哪里去 FileOutputFormat.setOutputPath(job, new Path("/wordcount/output/"));深 boolean res = job.waitForCompletion(true); System.exit(res?0:1); } } 运行前的准备工作: 运行前准备工作 1、将当前的工程导出成wordcount.jar 2、准备/home/toto/software/wordcount/input/a.txt 其中a.txt中的内容类似: The true nobility is in being superior to your previous self guess 3、将 /home/toto/software/wordcount通过 hadoop fs -put wordcount /wordcount 上传到hdfs中 最后,可以执行的命令是: hadoop jar wordcount.jar cn.toto.bigdata.mr.wc.WordCountDriver 执行后的效果如下: B:使用WordCount本地运行,并且使用Combiner的案例(主要改变是在WordCountDriver中),代码如下: package cn.toto.bigdata.mr.wc; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.IntWritable; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Job; import org.apache.hadoop.mapreduce.lib.input.FileInputFormat; import org.apache.hadoop.mapreduce.lib.input.TextInputFormat; import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat; /** * 本类是客户端用来指定wordcount job程序运行时所需要的很多参数: * 比如,指定用哪个组件作为数据读取器、数据结果输出器 * 指定用哪个类作为map阶段的业务逻辑类,哪个类作为reduce阶段的业务逻辑类 * 指定wordcount job程序的jar包所在路径 * .... * 运行前准备工作 * 1、将当前的工程导出成wordcount.jar * 2、准备/home/toto/software/wordcount/input/a.txt 其中a.txt中的内容类似: The true nobility is in being superior to your previous self guess 3、将 /home/toto/software/wordcount通过 hadoop fs -put wordcount /wordcount 上传到hdfs中 * * 以及其他各种需要的参数 * hadoop jar wordcount.jar cn.toto.bigdata.mr.wc.WordCountDriver * 上面的命令等同: * java -cp wordcount.jar cn.toto.bigdata.mr.wc.WordCountDriver * * 上面的含义是通过hadoop jar将hadoop classpath的jar都拷贝到应用中,并且指定执行cn.toto.bigdata.mr.wc.WordCountDriver * * 最后查看结果的方式是:hadoop fs -cat /wordcount/output/part-r-00000,通过这个命令可以查看查看到 */ public class WordCountDriver { public static void main(String[] args) throws Exception { Configuration conf = new Configuration(); //conf.set("fs.defaultFS", "hdfs://hadoop:9000"); /*conf.set("mapreduce.framework.name", "yarn"); conf.set("yarn.resourcemanager.hostname", "mini1");*/ Job job = Job.getInstance(conf); //告诉框架,我们的程序所在jar包的路径 // job.setJar("c:/wordcount.jar"); job.setJarByClass(WordCountDriver.class); //告诉框架,我们的程序所用的mapper类和reducer类 job.setMapperClass(WordCountMapper.class); job.setReducerClass(WordCountReducer.class); //使用tCombiner,使用Combiner的好处是让数据在mapper task中就做统计求和,然后将求和后的结果传递给 //reducer,然后reducer可以在进行求和。这样的好处是减少了reducer的工作。让每个mapper task自己做聚合, //通过分担的方式让效率得以提升,由于combiner的内容结构,编程规范也是集成reducer,所以在当前场景中可以将combiner直接 //设置成WordCountReducer job.setCombinerClass(WordCountReducer.class); //告诉框架,我们的mapperreducer输出的数据类型 job.setMapOutputKeyClass(Text.class); job.setMapOutputValueClass(IntWritable.class); job.setOutputKeyClass(Text.class); job.setOutputValueClass(IntWritable.class); // 告诉框架,我们的数据读取、结果输出所用的format组件 // TextInputFormat是mapreduce框架中内置的一种读取文本文件的输入组件 job.setInputFormatClass(TextInputFormat.class); job.setOutputFormatClass(TextOutputFormat.class); // 告诉框架,我们要处理的文件在哪个路径下,注意若hdfs中已经有了/wordcount/input/这个文件,说明 FileInputFormat.setInputPaths(job, new Path("e:/wordcount/input/")); // 告诉框架,我们的处理结果要输出到哪里去 FileOutputFormat.setOutputPath(job, new Path("e:/wordcount/output/")); boolean res = job.waitForCompletion(true); System.exit(res?0:1); } } 准备工作: 在E盘下准备e:/wordcount/input/a.txt,其中的内容如下: The true nobility is in being superior to your previous self guess No great discovery was ever made without a bold Knowledge will give you power but character respect The sun is just rising in the morning of another day I I figure life is a gift and I don't intend on wasting 右键运行上面的代码,进入: E:\wordcount\output\part-r-00000中看结果,结果内容如下: I 3 Knowledge 1 No 1 The 2 a 2 and 1 another 1 being 1 bold 1 but 1 character 1 day 1 discovery 1 don't 1 ever 1 figure 1 gift 1 give 1 great 1 guess 1 in 2 intend 1 is 3 just 1 life 1 made 1 morning 1 nobility 1 of 1 on 1 power 1 previous 1 respect 1 rising 1 self 1 sun 1 superior 1 the 1 to 1 true 1 was 1 wasting 1 will 1 without 1 you 1 your 1 经过上面的所有步骤之后,程序已经编写完成 总结: 3.MAPREDUCE中的Combiner[dht1] (1)combiner是MR程序中Mapper和Reducer之外的一种组件 (2)combiner组件的父类就是Reducer (3)combiner和reducer的区别在于运行的位置: Combiner是在每一个maptask所在的节点运行 Reducer是接收全局所有Mapper的输出结果; (4) combiner的意义就是对每一个maptask的输出进行局部汇总,以减小网络传输量 具体实现步骤: 1、自定义一个combiner继承Reducer,重写reduce方法 2、在job中设置:job.setCombinerClass(CustomCombiner.class) (5) combiner能够应用的前提是不能影响最终的业务逻辑 而且,combiner的输出kv应该跟reducer的输入kv类型要对应起来 Combiner的使用要非常谨慎 因为combiner在mapreduce过程中可能调用也肯能不调用,可能调一次也可能调多次 所以:combiner使用的原则是:有或没有都不能影响业务逻辑 =============================================================================== 流量统计和自定义类实现序列化案例: package cn.toto.bigdata.mr.wc.flowsum; import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; import org.apache.hadoop.io.WritableComparable; /** * 自定义的类要被mapreduce使用,需要序列化WritableComparable */ public class FlowBean implements WritableComparable<FlowBean> { private String phoneNbr; private long upFlow; private long dFlow; private long sumFlow; /** * */ public FlowBean() {} /** * 序列化框架在反序列化操作创建对象实例时会调用无参构造 */ @Override public void write(DataOutput out) throws IOException { out.writeUTF(phoneNbr); out.writeLong(upFlow); out.writeLong(dFlow); out.writeLong(sumFlow); } /** * 反序列化方法,注意:字段的反序列化顺序与序列化时的顺序保持一致 */ @Override public void readFields(DataInput in) throws IOException { this.phoneNbr = in.readUTF(); this.upFlow = in.readLong(); this.dFlow = in.readLong(); this.sumFlow = in.readLong(); } @Override public int compareTo(FlowBean o) { return (int)(o.getSumFlow() - this.sumFlow); } public void set(long upFlow,long dFlow) { this.upFlow = upFlow; this.dFlow = dFlow; this.sumFlow = upFlow + dFlow; } public void set(String phoneNbr,long upFlow, long dFlow) { this.phoneNbr = phoneNbr; this.upFlow = upFlow; this.dFlow = dFlow; this.sumFlow = upFlow + dFlow; } public long getUpFlow() { return upFlow; } public void setUpFlow(long upFlow) { this.upFlow = upFlow; } public long getdFlow() { return dFlow; } public void setdFlow(long dFlow) { this.dFlow = dFlow; } public long getSumFlow() { return sumFlow; } public void setSumFlow(long sumFlow) { this.sumFlow = sumFlow; } public String getPhoneNbr() { return phoneNbr; } public void setPhoneNbr(String phoneNbr) { this.phoneNbr = phoneNbr; } @Override public String toString() { return "FlowBean [phoneNbr=" + phoneNbr + ", upFlow=" + upFlow + ", dFlow=" + dFlow + ", sumFlow=" + sumFlow + "]"; } } package cn.toto.bigdata.mr.wc.flowsum; import java.io.IOException; import org.apache.commons.lang.StringUtils; 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 FlowSum { //在kv中传输我们自定义的对象时可以的,但是必须实现hadoop的序列化机制 implements Writable public static class FlowSumMapper extends Mapper<LongWritable, Text, Text, FlowBean> { Text k = new Text(); FlowBean v = new FlowBean(); @Override protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException { //将读到的一行数据进行字段切分 String line = value.toString(); String[] fields = StringUtils.split(line,"\t"); //抽取业务所需要的个字段 String phoneNbr = fields[1]; long upFlow = Long.parseLong(fields[fields.length - 3]); long dFlow = Long.parseLong(fields[fields.length - 2]); k.set(phoneNbr); v.set(upFlow, dFlow); context.write(k, v); } } public static class FlowSumReducer extends Reducer<Text, FlowBean, Text, FlowBean> { FlowBean v = new FlowBean(); /** * reduce方法接收到的key是某一组<a手机号,bean><a手机号,bean><a手机号,bean>中的第一个手机号 * reduce方法接收到的vlaues是这一组kv中的所有bean的一个迭代器 */ @Override protected void reduce(Text key, Iterable<FlowBean> values, Context context) throws IOException, InterruptedException { long upFlowCount = 0; long dFlowCount = 0; for (FlowBean bean : values) { upFlowCount += bean.getUpFlow(); dFlowCount += bean.getdFlow(); } v.set(upFlowCount, dFlowCount); context.write(key, v); } } public static void main(String[] args) throws Exception { Configuration conf = new Configuration(); /* * conf.set("mapreduce.framework.name", "yarn"); * conf.set("yarn.resourcemanager.hostname", "mini1"); */ Job job = Job.getInstance(conf); // 告诉框架,我们的程序所在jar包的路径 // job.setJar("c:/wordcount.jar"); job.setJarByClass(FlowSum.class); // 告诉框架,我们的程序所用的mapper类和reducer类 job.setMapperClass(FlowSumMapper.class); job.setReducerClass(FlowSumReducer.class); // 告诉框架,我们的mapperreducer输出的数据类型 /* * job.setMapOutputKeyClass(Text.class); * job.setMapOutputValueClass(FlowBean.class); */ // 如果map阶段输出的数据类型跟最终输出的数据类型一致,就只要以下两行代码来指定 job.setOutputKeyClass(Text.class); job.setOutputValueClass(FlowBean.class); // 框架中默认的输入输出组件就是这俩货,所以可以省略这两行代码 /* * job.setInputFormatClass(TextInputFormat.class); * job.setOutputFormatClass(TextOutputFormat.class); */ // 告诉框架,我们要处理的文件在哪个路径下 FileInputFormat.setInputPaths(job, new Path("E:/learnTempFolder/flow/input/")); // 告诉框架,我们的处理结果要输出到哪里去 FileOutputFormat.setOutputPath(job, new Path("E:/learnTempFolder/flow/output/")); boolean res = job.waitForCompletion(true); System.exit(res ? 0 : 1); } } package cn.toto.bigdata.mr.wc.flowsum; 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; /** * 实现流量汇总并且按照流量大小倒序排序 前提:处理的数据是已经汇总过的结果文件 * * @author * */ public class FlowSumSort { public static class FlowSumSortMapper extends Mapper<LongWritable, Text, FlowBean, Text> { FlowBean k = new FlowBean(); Text v = new Text(); @Override protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException { String line = value.toString(); String[] fields = line.split("\t"); String phoneNbr = fields[0]; long upFlowSum = Long.parseLong(fields[1]); long dFlowSum = Long.parseLong(fields[2]); k.set(upFlowSum, dFlowSum); v.set(phoneNbr); context.write(k, v); } } public static class FlowSumSortReducer extends Reducer<FlowBean, Text, Text, FlowBean> { @Override protected void reduce(FlowBean bean, Iterable<Text> phoneNbrs, Context context) throws IOException, InterruptedException { context.write(phoneNbrs.iterator().next(), bean); } } public static void main(String[] args) throws Exception { Configuration conf = new Configuration(); Job job = Job.getInstance(conf); job.setJarByClass(FlowSumSort.class); // 告诉框架,我们的程序所用的mapper类和reducer类 job.setMapperClass(FlowSumSortMapper.class); job.setReducerClass(FlowSumSortReducer.class); job.setMapOutputKeyClass(FlowBean.class); job.setMapOutputValueClass(Text.class); // 告诉框架,我们的mapperreducer输出的数据类型 job.setOutputKeyClass(Text.class); job.setOutputValueClass(FlowBean.class); // 告诉框架,我们要处理的文件在哪个路径下(注意:这里的程序执行) FileInputFormat.setInputPaths(job, new Path("E:/learnTempFolder/flow/output/")); // 告诉框架,我们的处理结果要输出到哪里去 FileOutputFormat.setOutputPath(job, new Path("E:/learnTempFolder/flow/sortout/")); boolean res = job.waitForCompletion(true); System.exit(res ? 0 : 1); } } 运行条件模拟: 1、配置环境变量为HADOOP_HOME=E:\learnTempFolder\hadoop-2.7.3 2、从CSDN资源上下载支持win10版本的:E:\learnTempFolder\hadoop-2.7.3\bin\winutils.exe 和 E:\learnTempFolder\hadoop-2.7.3\bin\hadoop.dll 界面效果如下: 3、准备要处理的资料: HTTP_20130313143750.dat 数据文件的具体内容如: 1363157985066 13726230503 00-FD-07-A4-72-B8:CMCC 120.196.100.82 i02.c.aliimg.com 24 27 2481 24681 200 1363157995052 13826544101 5C-0E-8B-C7-F1-E0:CMCC 120.197.40.4 4 0 264 0 200 1363157991076 13926435656 20-10-7A-28-CC-0A:CMCC 120.196.100.99 2 4 132 1512 200 1363154400022 13926251106 5C-0E-8B-8B-B1-50:CMCC 120.197.40.4 4 0 240 0 200 1363157993044 18211575961 94-71-AC-CD-E6-18:CMCC-EASY 120.196.100.99 iface.qiyi.com 视频网站 15 12 1527 2106 200 1363157995074 84138413 5C-0E-8B-8C-E8-20:7DaysInn 120.197.40.4 122.72.52.12 20 16 4116 1432 200 1363157993055 13560439658 C4-17-FE-BA-DE-D9:CMCC 120.196.100.99 18 15 1116 954 200 1363157995033 15920133257 5C-0E-8B-C7-BA-20:CMCC 120.197.40.4 sug.so.360.cn 信息安全 20 20 3156 2936 200 1363157983019 13719199419 68-A1-B7-03-07-B1:CMCC-EASY 120.196.100.82 4 0 240 0 200 1363157984041 13660577991 5C-0E-8B-92-5C-20:CMCC-EASY 120.197.40.4 s19.cnzz.com 站点统计 24 9 6960 690 200 1363157973098 15013685858 5C-0E-8B-C7-F7-90:CMCC 120.197.40.4 rank.ie.sogou.com 搜索引擎 28 27 3659 3538 200 1363157986029 15989002119 E8-99-C4-4E-93-E0:CMCC-EASY 120.196.100.99 www.umeng.com 站点统计 3 3 1938 180 200 1363157992093 13560439658 C4-17-FE-BA-DE-D9:CMCC 120.196.100.99 15 9 918 4938 200 1363157986041 13480253104 5C-0E-8B-C7-FC-80:CMCC-EASY 120.197.40.4 3 3 180 180 200 1363157984040 13602846565 5C-0E-8B-8B-B6-00:CMCC 120.197.40.4 2052.flash2-http.qq.com 综合门户 15 12 1938 2910 200 1363157995093 13922314466 00-FD-07-A2-EC-BA:CMCC 120.196.100.82 img.qfc.cn 12 12 3008 3720 200 1363157982040 13502468823 5C-0A-5B-6A-0B-D4:CMCC-EASY 120.196.100.99 y0.ifengimg.com 综合门户 57 102 7335 110349 200 1363157986072 18320173382 84-25-DB-4F-10-1A:CMCC-EASY 120.196.100.99 input.shouji.sogou.com 搜索引擎 21 18 9531 2412 200 1363157990043 13925057413 00-1F-64-E1-E6-9A:CMCC 120.196.100.55 t3.baidu.com 搜索引擎 69 63 11058 48243 200 1363157988072 13760778710 00-FD-07-A4-7B-08:CMCC 120.196.100.82 2 2 120 120 200 1363157985066 13726238888 00-FD-07-A4-72-B8:CMCC 120.196.100.82 i02.c.aliimg.com 24 27 2481 24681 200 1363157993055 13560436666 C4-17-FE-BA-DE-D9:CMCC 120.196.100.99 18 15 1116 954 2004、先运行FlowSum(右键执行Java程序) 运行生成的文件为E:\learnTempFolder\flow\output\part-r-00000,内容如下: 13480253104 180 180 360 13502468823 7335 110349 117684 13560436666 1116 954 2070 13560439658 2034 5892 7926 13602846565 1938 2910 4848 13660577991 6960 690 7650 13719199419 240 0 240 13726230503 2481 24681 27162 13726238888 2481 24681 27162 13760778710 120 120 240 13826544101 264 0 264 13922314466 3008 3720 6728 13925057413 11058 48243 59301 13926251106 240 0 240 13926435656 132 1512 1644 15013685858 3659 3538 7197 15920133257 3156 2936 6092 15989002119 1938 180 2118 18211575961 1527 2106 3633 18320173382 9531 2412 11943 84138413 4116 1432 55485、运行FlowSumSort(注意不要删除上面的part-r-00000) 运行后产生的文件内容是: 13502468823 7335 110349 117684 13925057413 11058 48243 59301 13726230503 2481 24681 27162 18320173382 9531 2412 11943 13560439658 2034 5892 7926 13660577991 6960 690 7650 15013685858 3659 3538 7197 13922314466 3008 3720 6728 15920133257 3156 2936 6092 84138413 4116 1432 5548 13602846565 1938 2910 4848 18211575961 1527 2106 3633 15989002119 1938 180 2118 13560436666 1116 954 2070 13926435656 132 1512 1644 13480253104 180 180 360 13826544101 264 0 264 13719199419 240 0 240 当然,我们也可以一次性求和并运算出结果输出到指定的文件目录中,代码如下: package cn.toto.bigdata.mr.wc.flowsum; import java.io.IOException; import java.util.Map.Entry; import java.util.Set; import java.util.TreeMap; import org.apache.commons.lang.StringUtils; 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 OneStepSumSort { public static class OneStepSumSortMapper extends Mapper<LongWritable, Text, Text, FlowBean> { Text k = new Text(); FlowBean v = new FlowBean(); @Override protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException { //将读到的一行数据进行字段切分 String line = value.toString(); String[] fields = StringUtils.split(line,"\t"); //抽取业务所需要的各字段 String phoneNbr = fields[1]; long upFlow = Long.parseLong(fields[fields.length - 3]); long dFlow = Long.parseLong(fields[fields.length - 2]); k.set(phoneNbr); v.set(phoneNbr, upFlow, dFlow); context.write(k, v); } } public static class OneStepSumSortReducer extends Reducer<Text, FlowBean, Text, FlowBean> { TreeMap<FlowBean, Text> treeMap = new TreeMap<FlowBean,Text>(); @Override protected void reduce(Text key, Iterable<FlowBean> values, Context context) throws IOException, InterruptedException { int upCount = 0; int dCount = 0; for (FlowBean bean : values) { upCount += bean.getUpFlow(); dCount += bean.getdFlow(); } FlowBean sumBean = new FlowBean(); sumBean.set(key.toString(), upCount, dCount); Text text = new Text(key.toString()); treeMap.put(sumBean, text); } @Override protected void cleanup(Reducer<Text, FlowBean, Text, FlowBean>.Context context) throws IOException, InterruptedException { Set<Entry<FlowBean, Text>> entrySet = treeMap.entrySet(); for (Entry<FlowBean, Text> ent : entrySet) { context.write(ent.getValue(), ent.getKey()); } } } public static void main(String[] args) throws Exception { Configuration conf = new Configuration(); Job job = Job.getInstance(conf); job.setJarByClass(OneStepSumSort.class); // 告诉框架,我们的程序所用的mapper类和reducer类 job.setMapperClass(OneStepSumSortMapper.class); job.setReducerClass(OneStepSumSortReducer.class); job.setMapOutputKeyClass(Text.class); job.setMapOutputValueClass(FlowBean.class); // 告诉框架,我们的mapperreducer输出的数据类型 job.setOutputKeyClass(Text.class); job.setOutputValueClass(FlowBean.class); // 告诉框架,我们要处理的文件在哪个路径下 FileInputFormat.setInputPaths(job, new Path("E:/flow/input/")); // 告诉框架,我们的处理结果要输出到哪里去 FileOutputFormat.setOutputPath(job, new Path("E:/flow/sortout/")); boolean res = job.waitForCompletion(true); System.exit(res ? 0 : 1); } } 到"E:/flow/sortout/"目录下,查看结果: 即: 13502468823 FlowBean [phoneNbr=13502468823, upFlow=7335, dFlow=110349, sumFlow=117684] 13925057413 FlowBean [phoneNbr=13925057413, upFlow=11058, dFlow=48243, sumFlow=59301] 13726238888 FlowBean [phoneNbr=13726230503, upFlow=2481, dFlow=24681, sumFlow=27162] 18320173382 FlowBean [phoneNbr=18320173382, upFlow=9531, dFlow=2412, sumFlow=11943] 13560439658 FlowBean [phoneNbr=13560439658, upFlow=2034, dFlow=5892, sumFlow=7926] 13660577991 FlowBean [phoneNbr=13660577991, upFlow=6960, dFlow=690, sumFlow=7650] 15013685858 FlowBean [phoneNbr=15013685858, upFlow=3659, dFlow=3538, sumFlow=7197] 13922314466 FlowBean [phoneNbr=13922314466, upFlow=3008, dFlow=3720, sumFlow=6728] 15920133257 FlowBean [phoneNbr=15920133257, upFlow=3156, dFlow=2936, sumFlow=6092] 84138413 FlowBean [phoneNbr=84138413, upFlow=4116, dFlow=1432, sumFlow=5548] 13602846565 FlowBean [phoneNbr=13602846565, upFlow=1938, dFlow=2910, sumFlow=4848] 18211575961 FlowBean [phoneNbr=18211575961, upFlow=1527, dFlow=2106, sumFlow=3633] 15989002119 FlowBean [phoneNbr=15989002119, upFlow=1938, dFlow=180, sumFlow=2118] 13560436666 FlowBean [phoneNbr=13560436666, upFlow=1116, dFlow=954, sumFlow=2070] 13926435656 FlowBean [phoneNbr=13926435656, upFlow=132, dFlow=1512, sumFlow=1644] 13480253104 FlowBean [phoneNbr=13480253104, upFlow=180, dFlow=180, sumFlow=360] 13826544101 FlowBean [phoneNbr=13826544101, upFlow=264, dFlow=0, sumFlow=264] 13926251106 FlowBean [phoneNbr=13719199419, upFlow=240, dFlow=0, sumFlow=240] 6、为不同的手机号设置分区,让不同的手机号在不同的文件中。方法如下: A:下面是自定义分区,自定分区的代码如下: package cn.toto.bigdata.mr.wc.flowsum; import java.util.HashMap; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Partitioner; /** * 自定义分区要继承Partitioner */ public class ProvincePartitioner extends Partitioner<Text, FlowBean>{ private static HashMap<String, Integer> provinceMap = new HashMap<String, Integer>(); static { provinceMap.put("138", 0); provinceMap.put("139", 1); provinceMap.put("136", 2); provinceMap.put("137", 3); provinceMap.put("135", 4); } @Override public int getPartition(Text key, FlowBean value, int numPartitions) { Integer code = provinceMap.get(key.toString().substring(0,3)); if (code != null) { return code; } return 5; } }B:测试一下自定义分区: package cn.toto.bigdata.mr.wc.flowsum; import java.io.IOException; import org.apache.commons.lang.StringEscapeUtils; import org.apache.commons.lang.StringUtils; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileSystem; 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 FlowSumProvince { public static class FlowSumProvinceMapper extends Mapper<LongWritable, Text, Text, FlowBean> { Text k = new Text(); FlowBean v = new FlowBean(); @Override protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException { // 将读到的一行数据进行字段切分 String line = value.toString(); String[] fields = StringUtils.split(line, "\t"); // 抽取业务所需要的各字段 String phoneNbr = fields[1]; long upFlow = Long.parseLong(fields[fields.length - 3]); long dFlow = Long.parseLong(fields[fields.length - 2]); k.set(phoneNbr); v.set(phoneNbr, upFlow, dFlow); context.write(k, v); } } public static class FlowSumProvinceReducer extends Reducer<Text, FlowBean, Text, FlowBean> { @Override protected void reduce(Text key, Iterable<FlowBean> values, Context context) throws IOException, InterruptedException { int upCount = 0; int dCount = 0; for (FlowBean bean : values) { upCount += bean.getUpFlow(); dCount += bean.getdFlow(); } FlowBean sumBean = new FlowBean(); sumBean.set(key.toString(), upCount, dCount); context.write(key, sumBean); } } public static void main(String[] args) throws Exception { Configuration conf = new Configuration(); Job job = Job.getInstance(conf); job.setJarByClass(FlowSumProvince.class); // 告诉框架,我们的程序所用的mapper类和reducer类 job.setMapperClass(FlowSumProvinceMapper.class); job.setReducerClass(FlowSumProvinceReducer.class); job.setMapOutputKeyClass(Text.class); job.setMapOutputValueClass(FlowBean.class); // 告诉框架,我们的mapperreducer输出的数据类型 job.setOutputKeyClass(Text.class); job.setOutputValueClass(FlowBean.class); //设置shuffle的分区组件使用我们自定义的分区组件,按照手机号进行分区,注意在自定义的手机号分区中有5个,所以我们的分区不能少于6个 job.setPartitionerClass(ProvincePartitioner.class); //设置reduce task的数量 job.setNumReduceTasks(6); //告诉框架,我们要处理的文件在哪个路径下 FileInputFormat.setInputPaths(job, new Path("E:/flow/input/")); //告诉框架,我们的处理结果要输出到哪里去 Path out = new Path("E:/flow/provinceout/"); FileSystem fs = FileSystem.get(conf); if (fs.exists(out)) { fs.delete(out,true); } FileOutputFormat.setOutputPath(job, out); boolean res = job.waitForCompletion(true); System.exit(res ? 0 : 1); } } C:运行所需的准备: 数据文件: 文件内容如下: 1363157985066 13726230503 00-FD-07-A4-72-B8:CMCC 120.196.100.82 i02.c.aliimg.com 24 27 2481 24681 200 1363157995052 13826544101 5C-0E-8B-C7-F1-E0:CMCC 120.197.40.4 4 0 264 0 200 1363157991076 13926435656 20-10-7A-28-CC-0A:CMCC 120.196.100.99 2 4 132 1512 200 1363154400022 13926251106 5C-0E-8B-8B-B1-50:CMCC 120.197.40.4 4 0 240 0 200 1363157993044 18211575961 94-71-AC-CD-E6-18:CMCC-EASY 120.196.100.99 iface.qiyi.com 视频网站 15 12 1527 2106 200 1363157995074 84138413 5C-0E-8B-8C-E8-20:7DaysInn 120.197.40.4 122.72.52.12 20 16 4116 1432 200 1363157993055 13560439658 C4-17-FE-BA-DE-D9:CMCC 120.196.100.99 18 15 1116 954 200 1363157995033 15920133257 5C-0E-8B-C7-BA-20:CMCC 120.197.40.4 sug.so.360.cn 信息安全 20 20 3156 2936 200 1363157983019 13719199419 68-A1-B7-03-07-B1:CMCC-EASY 120.196.100.82 4 0 240 0 200 1363157984041 13660577991 5C-0E-8B-92-5C-20:CMCC-EASY 120.197.40.4 s19.cnzz.com 站点统计 24 9 6960 690 200 1363157973098 15013685858 5C-0E-8B-C7-F7-90:CMCC 120.197.40.4 rank.ie.sogou.com 搜索引擎 28 27 3659 3538 200 1363157986029 15989002119 E8-99-C4-4E-93-E0:CMCC-EASY 120.196.100.99 www.umeng.com 站点统计 3 3 1938 180 200 1363157992093 13560439658 C4-17-FE-BA-DE-D9:CMCC 120.196.100.99 15 9 918 4938 200 1363157986041 13480253104 5C-0E-8B-C7-FC-80:CMCC-EASY 120.197.40.4 3 3 180 180 200 1363157984040 13602846565 5C-0E-8B-8B-B6-00:CMCC 120.197.40.4 2052.flash2-http.qq.com 综合门户 15 12 1938 2910 200 1363157995093 13922314466 00-FD-07-A2-EC-BA:CMCC 120.196.100.82 img.qfc.cn 12 12 3008 3720 200 1363157982040 13502468823 5C-0A-5B-6A-0B-D4:CMCC-EASY 120.196.100.99 y0.ifengimg.com 综合门户 57 102 7335 110349 200 1363157986072 18320173382 84-25-DB-4F-10-1A:CMCC-EASY 120.196.100.99 input.shouji.sogou.com 搜索引擎 21 18 9531 2412 200 1363157990043 13925057413 00-1F-64-E1-E6-9A:CMCC 120.196.100.55 t3.baidu.com 搜索引擎 69 63 11058 48243 200 1363157988072 13760778710 00-FD-07-A4-7B-08:CMCC 120.196.100.82 2 2 120 120 200 1363157985066 13726238888 00-FD-07-A4-72-B8:CMCC 120.196.100.82 i02.c.aliimg.com 24 27 2481 24681 200 1363157993055 13560436666 C4-17-FE-BA-DE-D9:CMCC 120.196.100.99 18 15 1116 954 200 运行后的结果如下: part-r-00001中内容: 等等

优秀的个人博客,低调大师

关于” 记一次logback传输日志到logstash根据自定义设置动态创建ElasticSearch索引” 这篇博客相关的优化采坑记录

之前写过一篇博客是关于记录日志的简单方式的 主要就是 应用->redis->logstash->elasticsearch 整个流程的配置方法和过程的 https://www.cnblogs.com/zhyg/p/6994314.html 记一次logback传输日志到logstash根据自定义设置动态创建ElasticSearch索引 虽然我们部分线上应用使用 redis单节点 logstash 也是使用单节点基本稳定流畅并且几乎不丢日志(单节点问题就不说了肯定有单点故障之后在分析) 上面的两个单节点 一天承受1-3亿条日志是没有问题的前提是并发量不要太大 可是 可是 tmd我今天就遇到了 主要分享一下解决方案 本方案同样是两个单节点 先说下今天发生的北京情况 我们的业务服务有些挤压这个时候我们把处理节点线程加多 来处理

优秀的个人博客,低调大师

2021 年 3 月头号恶意软件:IcedID 银行木马在新冠肺炎疫情相关攻击活动后跻身恶意软件指数排行榜前十名

网络安全解决方案提供商 Check Point 软件技术有限公司(纳斯达克股票代码:CHKP)的威胁情报部门 Check Point Research (CPR) 发布了其 2021 年 3 月最新版《全球威胁指数》报告。研究人员报告称,IcedID 银行木马首次进入该指数榜单,位列第二,同时 Dridex 老牌木马从 2 月的第七位跃升为 3 月最猖獗的恶意软件。 IcedID 于 2017 年首次出现,并通过多次垃圾邮件攻击活动在 3 月迅速传播,影响了全球 11% 的组织。它发起的一场广泛攻击活动利用新冠肺炎疫情主题诱使新受害者打开恶意电子邮件附件;这些附件大多是 Microsoft Word 文档,带有用于插入 IcedID 安装程序的恶意宏。安装后,该木马将试图从用户 PC 中窃取帐户详细信息、支付凭证及其他敏感信息。此外,IcedID 还使用其他恶意软件进行扩散,并已用作勒索软件攻击感染的第一步。 Check Point 产品威胁情报与研究总监 Maya Horowitz 表示:“IcedID 已存在多年,但最近被广泛使用,这表明网络犯罪分子正不断变换花样,以疫情为幌子实施组织攻击。IcedID 是一种特别隐蔽的木马,利用一系列伎俩窃取财务数据,因此组织必须确保采用强大的安全系统来防止其网络遭到入侵,并将风险降至最低。对所有员工进行全面培训至关重要,这样他们才能够掌握所需技能,从而准确识别传播 IcedID 及其他恶意软件的恶意电子邮件类型。” CPR 还警告称,“HTTP 标头远程代码执行 (CVE-2020-13756)”是最常被利用的漏洞,全球 45% 的组织因此遭殃,其次是“MVPower DVR 远程代码执行”,影响了全球 44% 的组织。“Dasan GPON 路由器身份验证绕过 (CVE-2018-10561)”在最常被利用的漏洞排行榜中位列第三,全球影响范围为 44%。 头号恶意软件家族 * 箭头表示与上月相比的排名变化。 Dridex 是本月最活跃的恶意软件,全球 16% 的组织受到波及,其次是 IcedID 和 Lokibot,分别影响了全球 11% 和 9% 的组织。 1. ↑ Dridex - Dridex 是一种针对 Windows 平台的木马,据称可通过垃圾邮件附件下载。Dridex 不仅能够联系远程服务器并发送有关受感染系统的信息,而且还可以下载并执行从远程服务器接收的任意模块。 2. ↑ IcedID - IcedID 是一种通过垃圾电子邮件攻击活动传播的银行木马,使用进程注入和隐写等狡诈伎俩窃取用户财务数据。 3. ↑ Lokibot - Lokibot 是一种主要通过网络钓鱼电子邮件散播的信息窃取程序,用于窃取各种数据,例如电子邮件凭证以及 CryptoCoin 钱包和 FTP 服务器密码。 最常被利用的漏洞 本月,“HTTP 标头远程代码执行 (CVE-2020-13756)”是最常被利用的漏洞,全球 45% 的组织因此遭殃,其次是“MVPower DVR 远程代码执行”,影响了全球 44% 的组织。“Dasan GPON 路由器身份验证绕过 (CVE-2018-10561)”位列第三,全球影响范围为 44%。 1. ↑ HTTP 标头远程代码执行 (CVE-2020-13756) - HTTP 标头允许客户端和服务器传递带 HTTP 请求的其他信息。远程攻击者可能会使用存在漏洞的 HTTP 标头在受感染机器上运行任意代码。 2. ↑ MVPower DVR 远程代码执行 - 一种存在于 MVPower DVR 设备中的远程代码执行漏洞。远程攻击者可利用此漏洞,通过精心设计的请求在受感染的路由器中执行任意代码。 3. ↑ Dasan GPON 路由器身份验证绕过 (CVE-2018-10561) – 存在于 Dasan GPON 路由器中的身份验证绕过漏洞。远程攻击者可利用此漏洞获取敏感信息,并在不经授权的情况下访问受感染系统。 主要移动恶意软件 Hiddad 位列最猖獗的移动恶意软件指数榜首,其次是 xHelper 和 FurBall。 1. Hiddad — Hiddad 是一种 Android 恶意软件,能够对合法应用进行重新打包,然后将其发布到第三方商店。其主要功能是显示广告,但它也可以访问操作系统内置的关键安全细节。 2. xHelper - 自 2019 年3 月以来开始肆虐的恶意应用,用于下载其他恶意应用并显示恶意广告。该应用能够对用户隐身,甚至可以在卸载后进行自我重新安装。 3. FurBall - FurBall 是一种 Android MRAT(移动远程访问木马),由与伊朗政府存在关联的伊朗 APT 组织 APT-C-50 部署。该恶意软件早在 2017 年的多起攻击活动中便已使用,至今仍然活跃。FurBall 的功能包括:窃取短信和手机通话记录、记录通话和周围环境、收集媒体文件、跟踪位置等。 Check Point《全球威胁影响指数》及其《ThreatCloud 路线图》基于 Check Point ThreatCloud 情报数据撰写而成,ThreatCloud 是打击网络犯罪的最大协作网络,可通过全球威胁传感器网络提供威胁数据和攻击趋势。ThreatCloud 数据库每天检查超过 30 亿个网站和 6 亿份文件,每天识别超过 2.5 亿起恶意软件攻击活动。 【责任编辑:赵宁宁 TEL:(010)68476606】

资源下载

更多资源
腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册