分享

如何通过MapReduce实现腾讯QQ推荐好友

导读:
如果我们会了基本的mapreduce模型,不论是qq好友,还是文章推荐,道理都是一样的。只要我们勤于思考,能创造出更多例子。






大家都知道qq用户量上亿,每个用户又有很多的好友,因此,数据量十分的庞大,如何才能实现QQ的好友推荐呢?
下面举一个例子:
A有QQ好友B
B有QQ好友C
则A,C有可能是好友。
当A登录的时候,则会向A推荐C,当C登录的时候,则会向C推荐A。

Demo

输入数据

[mw_shl_code=bash,true]tom         jason
james         ivy
kette         jason
tom         lgd
lgd        lkx
lgd        lyn[/mw_shl_code]


[mw_shl_code=bash,true]map阶段
key:主
value:从
key:从
value:主
将一条记录分别作为key,value进行输出。
tom-->jason
jason-->tom
tom-->lgd
lgd-->tom

reduce阶段
将同一个key的values值进行两两组合。[/mw_shl_code]

[mw_shl_code=java,true]package FriendsRecommended;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
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 FindFriends {
    private final static String INPUT_PATH = "hdfs://liguodong:8020/liguodong";
    private final static String OUTPUT_PATH = "hdfs://liguodong:8020/liguodong/QQFriendRecommended";


    public static void main(String[] args) throws IOException,
    URISyntaxException, ClassNotFoundException, InterruptedException {

        Configuration conf = new Configuration();
        final FileSystem fileSystem = FileSystem.get(new URI(INPUT_PATH),conf);
        if(fileSystem.exists(new Path(OUTPUT_PATH)))
        {
            fileSystem.delete(new Path(OUTPUT_PATH),true);
        }
        Job job = Job.getInstance(conf, "qq friend recommended");

        job.setJarByClass(FindFriends.class);

        FileInputFormat.addInputPath(job, new Path(INPUT_PATH));  
        job.setMapperClass(MyMapper.class);
        job.setReducerClass(MyReudcer.class);

        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(Text.class);
        FileOutputFormat.setOutputPath(job, new Path(OUTPUT_PATH));

        //提交作业
        System.exit(job.waitForCompletion(true) ? 0 : 1);


    }

    public static class MyMapper extends Mapper<LongWritable,Text,Text,Text>{
        @Override
        protected void map(LongWritable k1, Text v1, Context context)
                throws IOException, InterruptedException {
            String line = v1.toString();
            String[] ss = line.split("\\s+");

            context.write(new Text(ss[0]), new Text(ss[1]));
            context.write(new Text(ss[1]), new Text(ss[0]));
        }
    }

    public static class MyReudcer extends Reducer<Text, Text, Text, Text>{
        @Override
        protected void reduce(Text k2, Iterable<Text> v2s,Context context)
                throws IOException, InterruptedException {
            Set<String> set = new HashSet<String>();
            for (Text v2:v2s) {
                set.add(v2.toString());
            }
            if (set.size()>1) {
                for (Iterator i = set.iterator();i.hasNext();) {

                    String qqName = (String)i.next();
                    for (Iterator j = set.iterator();j.hasNext();){
                        String otherqqName = (String)j.next();
                        if(!qqName.equals(otherqqName)){
                            context.write(new Text(qqName), new Text(otherqqName));
                        }
                    }
                }
            }
        }

    }
}[/mw_shl_code]


输出结果:
1.png









翼宇轩


本帖被以下淘专辑推荐:

已有(4)人评论

跳转到指定楼层
levycui 发表于 2015-8-3 14:01:12
非常好,简单明了
回复

使用道具 举报

zhangxq66@qq.co 发表于 2015-8-4 15:52:54
楼主思路很不错。
不过如果A和C刚好也是朋友,上面的算法依然会把A推荐给C
回复

使用道具 举报

zhangxq66@qq.co 发表于 2015-8-4 16:16:04
本帖最后由 zhangxq66@qq.co 于 2015-8-4 16:19 编辑

应该在现有得到的结果的基础上,和原始数据一起再做一次mapreduce ,去掉已经是朋友关系的那些推荐
回复

使用道具 举报

hyj 发表于 2015-8-10 19:52:44
http://mp.weixin.qq.com/s?__biz=MzAxMzE4MDI0NQ==&mid=208526736&idx=1&sn=63f55bce6cae6e1d4da394ea80d1c553&scene=0#rd
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

推荐上一条 /2 下一条