本文是关于CMU15619Cloud Computing项目:Social Networking Timeline with Heterogeneous Backends
的介绍以及总结反思。
项目主要目标:
- 探索AWS的DBaas服务的申请、配置和管理
- 比较MySQL, HBase和MongoDB在使用Java API载入数据时的异同。
- 利用多个后端为同一个复杂的web应用提供数据。
- 比较不同数据库在实际应用中的特点。
背景介绍
DBaas(Database-as-a-Services):
在AWS中,我们可以用其中的RDS的MySQL服务。
MongoDB:
MongoDB是NoSQL数据库的典型,基于文档存储(Document-oriented),不支持事务和表连接,所以查询的编写、理解和优化比较容易。之后会写一篇关于NoSQL的总结(一个坑)。 和HBase的key-value存储模式不同,MongoDB基于文档存储模式的优势在于可以支持复杂的数据类型,并且也支持Index。 MongoDB使用BSON类型存储数据,据说就是把文本直接转成二进制表示,BSON用于以下三种目的:
- 节省空间:BSON即使在最坏的情况下,也比普通的JSON占用空间少。
- 移动性
- Performance:BSON对内容的编码和解码的速度快于很多编程语言。
数据结构: 图
1.邻接矩阵Adjacent Matrix:空间复杂度为O(n^2)
比如这个:
2.邻接表Adjacent List 空间较少:
社交网络应用基础:
如今像Facebook, Twitter和Instagram都需要复杂和涉及良好的后端来处理多种类型的用户数据,提供持续的高性能低延迟的服务。同时还要通过实时数据分析为公司和广告商提供有价值的信息。
- 不同的数据类型(Video,Text,Link,etc.)需要存在不同的数据库中)
- 一个简单的展示社交网络页面的HTTP请求会触发后端一系列的请求和数据库动作。可以参见下图:
社交网络中的数据通常包括以下三种:
- 用户信息:
- 身份验证系统
- 用户信息/简介
- 活动日志
- 社交关系图(在下面会进步介绍)
- 用户活动:
- 用户产生的多媒体数据
- 大数据分析系统:
- 搜索系统
- 推荐系统
- 用户行为分析(基于云数据仓库的OLAP,有机会单独更新这个部分)
社交网络的前端已经做好,我们需要把四中不同的数据集存入三种数据库(MySQL, HBase, MongoDB),你完成的后端要能同时响应四中不同的request。
项目操作
通过RDS的MySQL实现基本登录:
在AWS RDS中配置MySQL并导入users.csv, userinfo.csv数据集。
连接AWS RDS中MySQL时注意:
远程登录需要导入数据时要加入 --local-infile得到授权。
mysql -u username -p password -h hostname --port=portname --local-infile database
数据集格式:
- users.csv [UserID, Password]
- userinfo.csv [UserID, Name, Profile Image URL]
导入MySQL语句:
LOAD DATA LOCAL INFILE 'filename' INTO TABLE tablename CHARACTER SET utf8mb4 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
请求格式:
GET /task1?id=[UserID]&pwd=[Password]
响应格式:
returnRes({"name":"my_name", "profile":"profile_image_url"})
所以,之后在Java文件中连接数据库,再创建JSON相应的代码即可。 测试:
- 启动前后端服务器,访问
http://<your_front_end_dns>:3000
- 输入正确或错误的账号密码登录测试
利用HBase存储社交图谱:
用HBase来保存用户间的follow关系,可以选择用之前在图中介绍的邻接矩阵和邻接表中选择一种,来保存数据。
原始数据格式:
<followee, follower>
请求格式:
GET /task2?id=[UserID]
响应格式:
{"followers":[{"name":"follower_name_1", "profile":"profile_image_url_1"}, {"name":"follower_name_2", "profile":"profile_image_url_2"}, ...]}
思路:
- 在HBase中存成followee: follower1, follower2, ...的格式
- 设计好HBase之后导入数据
- 启动前后端服务器后访问http://<your_front_end_dns>:3000
- 输入userid进行测试
用MongDB搭建主页:
如之前介绍的那样,对于各种形式的帖子,用MongoDB存储会是一个很好的选择。这里会查询一些特定的field,所以可以建立索引来加速查询。
帖子数据的形式:
关于MongoDB建立索引,可以参考这里
请求格式:
GET /task3?id=[UserID]
响应格式:
{"posts":[{post1_json}, {post2_json}, ...]}
测试方法:
- 启动前后端服务器,输入userid
最终整合
之前三个部分分别实现了三个数据库的存储,现在我们希望实现输入一个userid就可以返回用户信息(MySQL),用户粉丝列表(HBase)以及用户关注的人最新三十条帖子(MongoDB)。
排序规则:
- 对followers进行排序:
- 姓名升序排列
- Profile image URL升序排列
- 对最新30篇post排序:
- 按照timestamp升序排序
- 按照PostID升序排序
请求格式:
GET /task4?id=[UserID]
响应格式:
{"name":"my_name", "profile":"my_profile_image_url", "followers":[{"name":"follower_name_1", "profile":"profile_image_url_1"}, {"name":"follower_name_2", "profile":"profile_image_url_2"}, ...], "posts":[{post1_json, post2_json, ...}]}
简单推荐的实现
推荐系统的内容太多了,可以看看shaung的博客(一个广告) 这次我们用协同过滤算法实现一个简单的推荐系统,利用“朋友的朋友”来推荐好友。
Graph Distance:
比如:
我们可以得到与A的距离关系为:
{A:1, C:1, E:1, F:1, G:2, H:1}
其中去掉A本身,去掉A已经关注的C,剩下的就是
{G: 2, E: 1, F: 1, H: 1}
思路:
- 找到userid的关注的人的集合
- 将关注的人的集合中的每个人关注的人添加到信集合中,第一次出现则为1,之后的为原来的加1
- 用优先队列存储,注意第一个关注的人集合中的元素都不应该在此队列中
- 返回前十个的name和url,并返回
请求格式:
http://backend-public-dns:8080/MiniSite/task5?id=<user_id>
响应格式:
returnRes({"recommendation":[{name:<name1>, profile:<profile1>},{name:<name2>, profile:<profile2>},...,{name:<name10>, profile:<profile10>]})
Done!
Reference:
CMU15619课件:Social Networking Timeline with Heterogeneous Backends
小土刀博客:http://wdxtub.com/vault/cc-17.html