笔记:MapReduce Design Patterns

来源:互联网 发布:淘宝整点 抢购技巧 编辑:程序博客网 时间:2024/06/02 12:48

一、数值统计模式

1、求最大值、最小值、总值、个数、平均值

案例:给出用户发帖的第一次时间、最后一次时间、评论总数、帖子平均长度 等。

解决:定义一个 类CaculateObj实现 Writable 接口,以用户ID为Key,在Map/Reduce阶段向HDFS写入的是 CaculateObj 对象,这样一个MapReduce 程序可以完成所有操作。

最大值、最小值、总数、个数 可以用Combiner , 平均值不能用Combiner 。

其中均值在Reduce 阶段使用 总值除以个数 来计算。

public class CaculateObj implements Writable{        private int max ;    private int min ;    private int sum;    private int count;    private int average;    private Date firstDate;    private Date lastDate;    @Override    public void write(DataOutput d) throws IOException {        d.writeInt(max);        d.writeInt(min);        d.writeInt(sum);        d.writeInt(count);        d.writeInt(average);        d.writeLong(firstDate.getTime());        d.writeLong(lastDate.getTime());     }    @Override    public void readFields(DataInput di) throws IOException {        this.max = di.readInt();        this.min = di.readInt();        this.sum = di.readInt();        this.count = di.readInt();        this.average = di.readInt();        this.firstDate = new Date(di.readLong());        this.lastDate = new Date(di.readLong());             }  // Getter / Setter        }

2、求中值和均方差

案例:统计用户每天发帖长度的中值和标准差。

解决方法1:以时间 “天”为 Key,map 阶段的Key是天、Value是帖子长度,Reduce 阶段先计算每天发帖的数目,总长度,手动计算得到中值= 顺序为发帖数/2 的那个元素,均值=总长度/个数,均方差 按公式计算。此方法的缺点是内存消耗大。


解决方法2:以时间 “天” 为Key,map 阶段的Key是天、Value是SortedMapWritable(key为帖子长度,value为1) ,在Combiner 阶段写入key是天,Value是SortedMapWritable(key为帖子长度,value为个数),reduce阶段输入的Value就是SortedMapWritable(帖子长度、相同长度的个数)  。此方法的节约内存,减少传输。 


二、反向索引模式

根据数据集生成索引,用于快速搜索或数据的富集能力。

案例:给出用户评论数据,在一系列回答问题的id上创建wikipedia的反向索引

解决:很简单。从url中抽出id,map阶段url为key、id为value,reduce 阶段url为key,id拼凑字符串为value。


三、计数器模式 

案例:用hadoop自定义计数器统计每个州的用户数。

解决:使用计数器,

  1. context.getCounter(STATE_COUNTER_GROUP, state) .increment(1);

四、过滤器模式

就是过滤掉不符合要求的记录。

案例:Grep 作为流行的文本过滤工具,对一个文件进行行扫描,匹配指定的样式就输出。我们要在MapReduce中应用正则表达式。

解决:setup方法中取得要使用的正则表达式,在map中简单使用就行,无需reduce。


案例:随机采样。

解决:setup方法中取得采样参数,在map中简单使用就行,无需reduce。


特别的,有高效的布隆过滤器“ BloomFilter

案例:给出用户评论数据,过滤出绝大多数不包含指定关键词的评论。

解决:使用BloomFilter。


案例:给出用户评论列表,过滤掉声誉不超过1500的用户的评论。

解决:使用BloomFilter。


五、Top ten 模式

案例:问题:给出用户信息数据,根据用户的声誉值输出top ten。

解决:在Map、Reduce 阶段都计算top ten,使用一个容量为10的PriorityQueue。Map阶段的map方法中将数据保存在PriorityQueue中,不写入HDFS,在clean方法中以Null为key,PriorityQueue中用户信息为Value写入HDFS中。Reduce 阶段直接再将数据放入PriorityQueue,循环完成后,以Null为key,PriorityQueue中用户信息为Value写入HDFS中。


六、Distinct 模式

就是去掉重复值。

案例:给出用户评论数据,根据用户id去重。

解决:map阶段以用户Id为key,Null为value写入HDFS;Combine阶段直接输出用户Id;Reduce阶段直接输出用户Id。



七、结构分层模式

把基于行的数据转换成有层次的格式,例如,json xml。

案例:给出用户发帖和评论数据,创建结构化的xml层次结构,将相关的评论嵌套在对应的发帖之内。

解决:两个Map, map1用于处理发帖, map2处理评论。map输出的key均为帖子Id,map1输出的value标记1表示发帖,map2的输出value标记2表示评论。Reduce的时候以帖子id为key,组合所有的发帖、回帖记录为XML。


案例:使用前面例子的输出,执行自关联操作,创建问题帖,回答帖,和评论的层次结构。

解决


八、分区模式

分区模式是把记录移动到目录里(分片,分区,或箱)。但不关心记录的顺序。

案例:给出用户信息数据,根据一年内最后访问日期分区数据,一年一个大分区。

解决:配置使用自定义的partitioner。不同年份写入不同目录。


九、分箱模式

归档数据集中的每条记录到一个或多个类别。

案例:给出stackOverflow发帖数据,基于hadoop,pig,hive,hbase四个标签分到四个箱。对于文本内容或标题提到hadoop的,放在跟上面不同的箱。

解决:使用MultipleOutputs 。Map阶段的setup方法配置MultipleOutputs ,map方法写入不同目录,clean方法关闭MultipleOutputs 


十、全局排序

案例:stackOverflow 的用户数据是按账户排序的。而我们希望根据最后访问网站的时间排序。

解决


十一、混洗

打乱排序,随机合并数据集。

案例:给出大量评论数据,隐藏评论的某些信息:移除id,移除时间。然后随机混洗数据。

解决:map 阶段随机生成key,将评论作为value,则可将顺序弄乱。


十二、表连接

1、Reduce 端连接

案例: 给出用户数据和用户评论数据,把评论所属用户信息关联到评论数据上。

解决:两个Map,一个读入用户数据,一个读入评论数据,以用户Id为key,用值U、C分别标记用户数据和评论数据。在Reduce阶段再进行连接。


2、使用布隆过滤器的Reduce 端连接 

可大大减少数据传输。

案例:只对声誉值在1500以上的用户感兴趣。

解决


3、Map 端连接

案例:给出少量的用户信息数据和一个大的评论数据,用用户数据丰富评论数据。

解决:Setup阶段,从分布式缓存 DistributedCache 读用户数据并存进内存。


 4、Hadoop自带的连接

Hadoop本身有CompositeInputFormat 类支持复合join。这种模式的限制类型为:内连接和全外连接。Mapper的输入必须用指定的方式分区和排序,并且每个输入数据集必须分成相同数量的分区。另外,相同的外键必须在两个数据集相同的分区。这通常发生在几个job有相同的reducer个数并输出键也相同,并且输出文件时不能分割的。例如,比hdfs的block小或是一种不支持split的压缩格式。

案例:给出两个大数据集:用户信息和评论数据,使用用户数据丰富评论数据。

解决:使用CompositeInputFormat


5、笛卡尔积

笛卡尔积会使数据集的大小暴增,甚至是一个100万数据的自连接也会产生1万亿条记录。会用掉很多map slot 并运行很长时间,所以要谨慎使用。

案例:给出处理过的stackOverflow 评论数据,根据每对之间的相似单词的数量找出评论之间的相似程度。

解决:笛卡尔积。



十二、Job链

1、Job链

案例:给出stackOverflow 用户发帖数据,把用户分成两部分,根据高于或低于发帖数的平均值。并且丰富用户信息,加上从另一个数据集获得的声誉值,然后输出。

解决:两个MapReduce 程序。


2、并行Job链

并行job链的驱动跟前面例子的相似。唯一大的改进是jobs被并行提交然后监控它们直到完成。

案例:用到前面例子产生的分箱的用户数据,在两个箱上同时跑job计算平均声誉值。

解决


3、带Shell 的Job链


4、使用 JobControl的Job链


5、Job链合并

案例:给出用户发帖和用户信息数据,根据声誉值在5000上或下分类用户。



6、Job Merging


十三、输入输出模式

1、生成数据模式

案例:为了生成随机stackOverflow数据,我们使用1000个单词的list生成随机短评。我们需要生成一个随机分数,row id,userid,和创建时间。

解决:


2、外部源输出模式

外部源输出模式写到hadoop系统之外。

案例:给出用户信息数据,并行随机分发用户-声誉值的映射数据到一个数量可配置的redis集群。


3、外部源输入模式

这种模式不从hdfs加载数据,而是从hadoop以外系统,例如RDB或web service加载。

案例:给出csv格式redis实例列表,通过可配置的hash并行读取所有数据。


4、分区裁剪模式

案例:指根据文件名配置框架挑选和丢弃的要加载到MapReduce的文件的方式。








0 0