新浪架构师谈微博架构

yeaskyone

贡献于2012-01-06

字数:22876 关键词: 软件架构

微博(Micro-Blog)顾名思义是微型博客,是一种基于用户关系的信息分享和传播平台,用户可通过浏览器、手机、及时通讯软件(MSN、QQ、Skype等)及外部API接口等多种渠道发布140字以内信息[1]。支持跨平台交流、与移动设备无缝连接的技术优势,饱含Web2.0特质。 有这么一道题 - 微博数据库设计:有A,B,C3个用户,A关注C,C关注A和B;A,B更新后C会收到信息提示,比如:   2010-11-16 22:40 用户A 发表a1;   2010-11-16 22:41 用户A 发表a2;   2010-11-16 22:42 用户A 发表a3   2010-11-16 23:40 用户B 发表b1;   2010-11-16 22:40 用户B 发表b2; 问题1:如何设计数据表和查询? 问题2:如果C关注了10000个用户,A被10万个人关注,系统又该如何设计? 问题1,我的解答是:设计两张表,一张用于表示用户user,有ID,用户名(username),发布内容(message),发布时间(time)等字段;另一张表用于表示用户之间关注,有ID,用户名(username),关注的用户名,开始关注时间等字段。回去想了想,发现如果数据表照我这样设计的话,问题2的情况就会产生大量的数据,但如果把关注的用户都写在一个记录里那样字符串可能会更大。所以想听听诸位达人的意见,如果是你们会怎样设计数据表呢? 问题1简单而且随意,直接跳过,估计面试的人都不会看。问题2的困难在于: 第一点. C关注的用户太多,设计上必须在显示C的页面的过程中,避免去数据库查询所有被关注的用户是否有更新。 第二点. 第二点.A被关注的人太多,设计上必须在A更新的时候,避免去通知所有关注…… 为避免不必要的复杂连接关系,最好还是设计符合第三范式的关系数据。 我想至少应该设计三张表,分别是: 用户表 user:ID,username...; 关注关系表 attention: ID->ID; 发布信息表 info:ID->message; 三张表的设计是比较规范的,至于用户和关注之间的关联要看需求,做join也可以,做DataMap也可以。 个人觉得,需要的逻辑关系在哪儿,而且要进数据库,想不数据量大都不行。当然关注可以不做在一张表中也是一个选择,按关系类型分开走,可以减少特定需求的查询量。 这玩意得丢内存里头吧 memcached 发新的话题的话丢队列里头写数据库去 user { befollow[0...n]; post[0...n]; topics[0..n]; } 然后,user[befollow[k]].topics=current_user.topics[j]; 用户只要检查topics就好了 要不每次上来来个join什么的,估计数据库就挂了 是直接写到数据库的,不能用join,发贴后就丢队列里,向每一个follow我的人的tweet写数据 不能用纯粹的关系数据库来解决问题,因为数据量和访问量都很大。所以设计必须首要考虑性能问题。 我假定前提, 1、一个用户不经常更改他的关注对象, 2、用户添加关注对象的操作远多于移除关注对象的操作。 3、用户发微博的频率是比较高的,要比更改关注用户操作的频率高。 4、消息的通知到达时间用户是不敏感的 有了这些前提,我们做平衡处理。 我们可以忍受 1、较慢的删除关注用户操作 2、比删除操作快但比发微博操作慢的添加关注用户操作。 3、快的微博提交操作 4、慢的消息通知 我们每一个用户建立一个InBox和OutBox,InBox包含关注我的用户ID,OutBox是我关注的用户ID。 Box分为三个部分,一个是基准Box,一个是添加Box,一个是删除Box,实际的Box数据是基准Box和添加Box的并集和删除Box做差集后得到的集合。 1、用户插入关注用户,在用户的OutBox的添加Box加入一条,同时在被关注用户的InBox的添加Box也加入一条添加 2、用户删除关主用户,在用户的OutBox的删除Box加入一条,同时在被关注用户的InBox的删除Box也加入一条添加 3、微博产生后发送消息,将发送微博的用户的InBox(其中含基准Box,插入Box和删除Box)连同微博操作连接一起发送给消息处理器。 4、消息处理器合并Box,并把Box的内容回写到发送微博用户的InBox的基准Box中。 5、在后台添加一个Box合并进程,缓慢的合并用户的Box数据。 6、前台在展示的时候,因为没有合并,展示列表展示OutBox的基准Box和我新添加用户的Box以及删除用户的Box内容。 前台展示是需要商榷的,看PUM是否接受这种方式,如果不接受,我们只能在刷新时预测查询基准表,并且在页面合并。因为前台展示通常是分页的,这样会比较难获得准确的分页量,每页的显示量会不同。如果需要更高的要求,我们只能再添加其他数据结构。 如果需要更快的算法,我们必须抛弃关系数据库,将用户用B+树做索引,对于Box进行另外处理,需要论述的话,能写一个论文了。 更正一下,抛弃关系数据库可能更好的方式是,用用户ID做Hash索引,因为用户不删除,只增加。 同时,我们可以采用的物理架构和产品,我们需要找到一个轻量级的数据库存储引擎,例如我们可以用BDB,操作系统可以用vxWorks,然后专门针对消息发送和Box做一套系统。 更正设计,InBox可以不需要,采用客户端拉的机制,可以去掉InBox,带来的问题就是你必须在线才能得到通知。 InBox会很大,需要平衡,像姚晨这样的,会把消息处理器累死,所以,需要筛选,消息处理器的需要另外设计。 消息处理器可以去掉,当用户上线时,查阅关注博主的博文变更记录,根据阅读标志,阅读标志为每个用户建立一组。进行伪消息通知。 消息处理器存在于需要主动推送的场合。例如,短信和邮件。不是所有的用户都会进行短信订阅的,所以消息处理器的负载可以减轻。 陆兄的意思是不是:用DBMS底层的数据库引擎或相关数据结构(比如哈希,B+树等)重新设计一个适合微博应用环境的数据库,而不是利用现有的DBMS进行设计? 数据库是需要的,但不应该是关系型的。自己做数据库是可行的,在这个应用中,或者说需要高速处理的“热”数据中,是不需要关系的,也不应该用关系数据库的设计范式来约束设计。 对于Box这样的数据结构,是不需要保存在一个关系数据库的数据表中的。做成Hash表会很好,当然可以采用现有的数据库产品,把Box的索引类型定义为Hash的。很多数据库产品是可以这样处理的。 但是,这样会有麻烦,因为Box和用户紧密关联的,不可能为一个用户去建立一个Hash索引的表,这样你又不得不回到关系数据库的老路上去了。你可能会说,我可以定义在Hash主键中包含用户的账号,这样Box的数据自然会按照用户分开了。但是,需要获取用户整个Box数据的时候又碰到麻烦,没有和用户关联的索引去快速检索。 能做的就是把Box保存在内存或者独立的文件中,在这种应用中对数据完整性的要求是很低的,Box应该在内存中保存,在适当的时机脱水持久化。而且活跃的Box可能很少很少。 所以我的建议是分别处理,持久化一块,“热”的实时播发一块,持久化为了简便采用传统的关系数据库是可以的。 为了性能,需要特别处理。全部的设计,会很复杂,作为面试题,太难了! 为了提高处理能力,并行是不可避免的,需要把Box这样的结构分解分发在不同的机器上处理。但是在这样的应用中,事务又是不需要的,数据完整性也是不需要的,甚至不需要日志来恢复数据,并行处理的时候用传统的RDBMS又会有瓶颈。 所以这不是一个数据库设计问题。靠做关系数据库的设计是完成不了这样的任务的。 就是一个查询时间换空间的问题 本人认为在10万条以内,直接的标准关系型数据库设计就好 更大的话可以考虑做空间换时间的设计 具体可以做内存空间缓存,文件缓存,数据库缓存都可以 就数据库缓存来说,除了标准的关系型数据库外,另外需要加个表做个用户-》关注信息的表 每次有被关注的用户发布信息,就把其信息的ID写入被关注用户的用户关注信息表,对这个表可以优化,把比较老的数据及时删除。 还有一种折中的做法就是分别对关注关系的关注用户字段和用户信息的用户字段和时间字段做索引,问题就基本能解决,百万级没有问题 如果数量再大,需要对用户信息做时间的分表,保证每个表的信息数量在千万数量级 当然,每次访问都读取数据表就是一种愚蠢的做法,短期内数据不更新的情况下应当从内存读取数据或者文件缓存来读取数据 缓存的更新又是另外一个话题啦 问题2的困难在于: 第一点.C关注的用户太多,设计上必须在显示C的页面的过程中,避免去数据库查询所有被关注的用户是否有更新。 第二点.A被关注的人太多,设计上必须在A更新的时候,避免去通知所有关注他的人自己更新了(也就是数据库中为每个人设置标志或者增加记录)。 这两点其实是矛盾的,因为你总需要在某个时候交流“A更新了”这条信息。就需要在系统设计的时候进行折衷和权衡。甚至对不同的用户分类采用不同的方案。 可以采用以下的方案: 普通用户放到一张表中,视为B类。假设绝大多数用户都是B类,即关注的人不太多,被关注也不太多。进一步假设绝大多数的微博记录来自于普通的B类用户。 对那些关注别人太多的,分为C类。专门为C类用户增加一个表,他关注的人如果不是A类,则每次更新都在这张表里面推送一条记录。这样显示C的主页时,只用先查询这张表,再在A类人的专属表中查找A类人的更新即可。因为C类的人数比较少,所以这张表应该会比较小,查找起来会比较快。 对A类的人,则独立出来成为单独的一张表,供别人查询,因为A类的人数较少,所以这张表应该会比较小,查找起来比较快。 这就是一个简单的设计,足以表示你针对问题进行考虑,并给出了有一定效果的解决方案。 当然,这是按照楼上要求的只通过表的设计来实现。 而实际构建系统的时候,该用视图的用视图,该建立索引的建立索引,花样会更多,效果会更好。 以下设计以sqlserver2005为例 记录用户信息的 用户表 Users(uid bigint identity(1000,1) primary key,uname varchar(50) not null unique); 记录A对B的关注信息的 关注表 Attention(byuser bigint foreign key references Users(uid),touser bigint foreign key  references Users(uid) primary key(byuser,touser)); 注:byuser 发起关注者, touser 被关注者 记录某人发表文章信息的 文章表 Article(aid bigint identity(1000,1) primary key,uid bigint foreign key references Users (uid),title varchar(100) not null,context ntext not null,publishDate datetime not null); 由于需要获取更新信息,所以要能记录哪些文章是查看过,那些不是的文章状态,并且此状态不是文章 的状态,而是每一个文章对于每一个关注者的状态。所以,新表的设计目的是某用户对某文章的查看状 态。 AttentionUpdate(auid bigint identity(1,1) primary key,attentionUser bigint foreign key  references Users(uid),ariticle bigint foreign key references Article(aid) unique (attentionUser,ariticle),attentionState char(1) not null); 注:unique约束的目的是保证某一个用户对某一个文章的关注唯一;attentionState状态的目的是记录 该用户对该文章的操作状态,比如查看、评论、分享等。 并且由题目得知(题目有不明之处,先查询出的用户A的更新信息是正序,而后查询出的用户B的更新信 息是倒叙,此处就按正序来做),在查询更新信息的时候,需要按照关注用户Id、文章更新时间的正序 排序。 所以  在要求:查询出用户C关注的A和B的关注信息的查询语句 (拟定用户C的ID为1003、A:1001、B:1002) (拟定文章状态为'1'为未读) 有语句: select art.publishDate,u.uname,art.title  from Users u,Article art where u.uid=art.attentionUser and arti.aid in (select aid from AttentionUpdate where attentionUser=1003 and attentionState='1') order by u.uid asc,art.publishDate asc 限制:必须保证AttentionUpdate中的记录表示的关注状态和关注表中的记录相符,即是说 当某用户发表一篇文章的时候,就要根据该用户被关注的情况在AttentionUpdate表中插入attentionState为1 attentionUser为关注其用户的数据;在某用户删除一篇文章的时候,做相应删除;在某用户修改的时候 要做相应修改。 而且还可以做相应扩展,比如对用户分组,对组别设置访问权限。根据权限对AttentionUpdate表中的记录插入做选择性插入即可,修改、删除如是。 以上是我个人的设计,小子是5月份刚从学校毕业的学生,虽然现在在做一家b2c网站的开发,但对性能问题也不是很通透,只能给出一个我能想到的最优的解决方案...但对高并发访问 没有经验,也没有把握,猜测是在视图、存储过程、以及查询上做优化.. 新浪架构师谈微博架构 技术开发者往往对微博这个产品非常关心,对微博的构架非常感兴趣,就是一个明星他有300万粉丝,这个技术怎么来实现?今天在这里跟大家分享一下微博的底层机构,让大家对微博的底层技术有更好的了解。另外不管是做客户端、Web1.0、Web 2.0、论坛、博客都要考虑架构的问题,架构实际上是有一些共性的。今天我通过讲解微博里面的一些架构,分析一下架构里面哪些共性大家可以参考。 首先给大家介绍一下微博架构发展的历程。新浪微博在短短一年时间内从零发展到五千万用户,我们的基层架构也发展了3个大的版本。第一版就 LAMP架构,优点是可以非常快的实现我们的系统。我们看一下技术特点,微博这个产品从架构上来分析,它需要解决的是发表和订阅的问题。我们第一版采用的是推消息模式,假如说我们一个明星用户他有10万个粉丝,那就是说用户发表一条微博的时候,我们把这个微博消息存成10万份,这样就是很简单了,第一版的架构实际上就是这两行字。第一版的技术细节,典型的LAMP架构,是使用MyISAM搜索引擎,它的优点就是速度非常快。另外一个是MPSS,就是多个端口可以布置在同一服务器上。为什么使用MPSS?假如说我们做一个互联网应用,这个应用里面有三个单元,我们可以由2种部署方式。我们可以把三个单元分别部署在三台服务器上,另外一种部署模式就是这三个单元部署在每个服务器上都有。我推荐第2种方法。这个方法解决了两个问题,一个是负载均衡,因为每一个单元都有多个节点处理,另外一个是可以防止单点故障。如果我们按照模式1来做的话,任何一个节点有故障就会影响我们系统服务,如果模式二的话,任何一个结点发生故障我们的整体都不会受到影响的。 我们微博第一版上线之后,用户非常喜欢这个产品,用户数增长非常迅速。我们技术上碰到几个问题。第一个问题是发表会出现延迟现象,尤其是明星用户他的粉丝多系统需要处理很长时间。另外系统在处理明星用户发表时系统繁忙可能会影响到其他的用户,因为其他的用户同一时间发表的话,也会受到这个系统的影响。我们就考虑这个系统怎么改进。首先是推(消息)模式,这肯定是延迟的首要原因,我们要把这个问题解决掉。其次我们的用户越来越多,这个数据库表从一百万到一亿,数据规模不一样处理方式是有差别的。我们第一版单库单表的模式,当用户数量增多的时候,它不能满足就需要进行拆分。第二个是锁表的问题,我们考虑的是更改引擎。另外一个是发表过慢,我们考虑的是异步模式。 第二版我们进行了模块化,我们首先做了一个分层,最底层叫基础层,首先对数据做了拆分,图上最右边是发表做了异步模式。第二个服务层,我们把微博基础的单元设计成服务层一个一个模块,最大改进是对推模式进行了改进。首先看一下投递模式的优化,首先我们要思考推模式,如果我们做一下改进把用户分成有效和无效的用户。我们一个用户比如说有一百个粉丝,我发一条微博的时候不需要推给一百个粉丝,因为可能有50个粉丝不会马上来看,这样同步推送给他们,相当于做无用功。我们把用户分成有效和无效之后,我们把他们做一下区分,比如说当天登陆过的人我们分成有效用户的话,只需要发送给当天登陆过的粉丝,这样压力马上就减轻了,另外投递的延迟也减小了。 我们再看数据的拆分,数据拆分有很多方式,很多互联网产品最常用的方法,比如说如可以按照用户的UID来拆分。但是微博用户的一个特点就是说大家访问的都是最近的数据,所以我们考虑微博的数据我们按照时间拆分,比如说一个月放一张表,这样就解决了我们不同时间的维度可以有不同的拆分方式。第二个考虑就是要把内容和索引分开存放。假如说一条微博发表的uid,微博id是索引数据,140个字的内容是内容数据。假如我们分开的话,内容就简单的变成了一种key-value的方式,key-value是最容易扩展的一种数据。索引数据的拆分具有挑战,比如说一个用户发表了一千条微博,这一千条微博我们接口前端要分页访问,比如说用户需要访问第五页,那我们需要迅速定位到这个记录。假如说我们把这个索引拆分成一个月一张表,我们记录上很难判断第五页在哪张表里,我们需要加载所有的索引表。如果这个地方不能拆分,那我们系统上就会有一个非常大的瓶颈。最后我们想了一个方法,就是索引上做了一个二次索引,把每个月记录的偏移记下来,就是一个月这个用户发表了多少条,ID是哪里,就是按照这些数据迅速把记录找出来。 异步处理,发表是一个非常繁重的操作,它要入库、统计索引、进入后台,如果我们要把所有的索引都做完用户需要前端等待很长的时间,如果有一个环节失败的话,用户得到的提示是发表失败,但是入库已经成功,这样会带来数据不一致问题。所以我们做了一个异步操作,就是发表成功我们就提示成功,然后在后台慢慢的消息队列慢慢的做完。另外新浪发表了一个很重要的产品叫做MemcacheQ,我们去年做了一个对大规模部署非常有利的指令,就是statsqueue,适合大规模运维。 第二版我们做了这些改进之后,微博的用户和访问量并没有停止,还有很多新的问题出现。比如说系统问题,单点故障导致的雪崩,第二个是访问速度问题因为国内网络环境复杂,会有用户反映说在不同地区访问图片、js这些速度会有问题。另外一个是数据压力以及峰值,MySql复制延迟、慢查询,另外就是热门事件,比如说世界杯,可能会导致用户每秒发表的内容达到几千条。我们考虑如何改进,首先系统方面允许任意模块失败。另外静态内容,第一步我们用 CDN 来加速,另外数据的压力以及峰值,我们需要将数据、功能、部署尽可能的拆分,然后提前进行容量规划。 另一方面我们还有平台化的需求,去年11月我们就说要做开放平台,开放平台的需求是有差异的,Web系统它有用户行为才有请求,但是API系统特别是客户端的应用,只要用户一开机就会有请求,直到他关闭电脑这种请求一直会不间断的过来,另外用户行为很难预测。 系统规模在持续的增大,另外也有平台化的需求,我们新架构应该怎么做才能满足这些需要?我们看一下同行,比如说Google怎么样考虑这个问题的?Google首席科学家讲过一句话,就是一个大的复杂的系统,应该要分解成很多小的服务。比如说我们在Google.com执行一个搜索查询的话,实际上这个操作会调动内部一百多个服务。因此,我们第三版的考虑就是先有服务才有接口最后才有应用,我们才能把这个系统做大。 现在我们看一下第三版,首先我们把底层的东西分成基础服务,基础服务里面有分布式的存储,我们做了一些去中心化、自动化的操作。在基础服务之上有平台服务,我们把微博常用的应用做成各种小的服务。然后我们还有应用服务,这个是专门考虑平台各种应用的需求。最上面我们有API,API就是新浪微博各种第三方应用都在上面跑。平台服务和应用服务是分开的,这样实现了模块隔离,即使应用服务访问量过大的话,平台服务不会首先影响。另外我们把微博的引擎进行了改进,实现了一个分层关系。用户的关注关系,我们改成一个多惟度的索引结构,性能极大的提高。第四个层面就是计数器的改进,新版我们改成了基于偏移的思路,就是一个用户他原来读的一个ID比如说是10000,系统最 新的ID是10002的话,我们很清楚他有两条未读。原来的版本是采用绝对计数的,这个用户有几条未读都是用一个存储结构的话,就容易产生一致性的问题,采用这种偏移的技术基本上不会出错。 另外基础服务DB冷热分离多维度拆分,在微博里面我们是按照时间拆分的,但是一个大型的系统里面有很多业务需要有不同的考虑。比如说私信这个就不能按照时间来拆分,这个按照UID来拆分可能更简单。然后我们突出存储还做了一个去中心化,就是用户上传图片的速度会极大的提高,另外察看其他用户的图片速度也会极大的提高。另外是动态内容支持多IDC同时更新,这个是在国内比较新颖的。 下面给大家介绍一下新浪微博怎么样打造一个高性能架构。到目前为止有五千万用户使用新浪微博,最高发表3000条以上每秒,然后一个明星用户发表的话,会被几百万用户同时读到。这些问题的本质是我们架构需要考虑高访问量、海量数据的情况下三个问题。易于扩展、低延迟、高可用和异地分布。我们每天有数十亿次外部网页以及API接口的需求,我们知道微博的特点是用户请求是无法cache的。因此面对这个需求我们怎么样扩展?几点思路。第一我们的模块设计上要去状态,我们任意一个单元可以支持任意节点。另外是去中心化,避免单点及瓶颈。另外是可线性扩展。最后一个是减少模块。 我们要做一个高性能的系统,要具备一个低延迟、高实时性,微博要做到高实时性这是核心的价值,实时性的核心就是让数据离CPU最近,避免磁盘的IO。我们看淘宝核心系统专家余锋说过的一句话“CPU访问L1就像从书桌拿一本书,L2是从书架拿一本书,L3是从客厅桌子上拿一本书,访问主存就像骑车去社区图书馆拿一书”。我们微博如果要做到非常实时的话,我们就需要把数据尽量离CPU节点最近。所以我们看一下cache设计里面怎么达到这个目标。首先INBOX,这个数据我们需要放再一个最快的地方,因为用户随时访问。OutBOX里面的最近发表就是L1cache,还有一个是中期的,这个因为访问少一点,它可以被踢。最后一部分内容体有三部分。L0是本地的,我们需要把一些经常访问的,比如说明星发表微博的内容体本地化,因为它被访问的概率非常大。然后L1里面存放着最近发表的,还有一个是中期的。我们通常用L2就可以了,L1我们可以理解成它就是一个RAM存储。 一个好的架构还需要举行高可用性。我们看一下业界的指标,S3是99.9%,EC2是99.5%,我们另外一个同行Facebook在这方面它是没有承诺的,就是接口可用写。微博平台目前承诺的是99.95%,就是说一天365天故障率应该小于9小时。这个怎么达到?第一我们要做容量规划,要做好监控以及入口的管理,就是说有些服务如果访问量过了的话,我们要有一个开关可以拦住他。我们通过这个图表可以清楚的看到,比如说我们要做L1的 cache,我们剩余空间有多少,比如说80%,就说明这个数据有可能会丢失,有可能会对我们的系统造成影响。 另外一个层面就是接口监控,我们目前有Google维度的接口监控,包括访问错误失败率。然后要做架构,给大家一个很重要的经验分享,就是说监控的指标尽量量化。比如说他延迟30秒是小问题,如果是延迟10分钟我们就要立即采取措施了,就是所有可以量化的指标都要量化。 然后我们看监控怎么样更好的做?我们看亚马逊的VP说过的一句话,就是说监控系统确实特别好,可以立即告诉我们哪里有故障,但是有20%的概率我们人是会出错的。所以我们一个大型系统就应该要为自动化设计,就是说尽可能的将一些运作自动化。比如说发布安装、服务、启用、停止。我们再看另外一句,Google的工程师是怎么做的。他是这么做的,比如说第一周是处理线上的业务,这一周他处理了很多事情,处理了很多系统的情况,剩下几周时间没有别的工作,他只要把这一周碰到的情况用程序的方法来解决,下次再碰到这种情况很简单的一个按钮就可以处理了。我们目前也在向自动化这方面努力,就是我们的工具在持续增加。 另外一个异地分布,在国内网络环境下,比如说IDC灾难,机房检修甚至是机房掉电,我们也碰到过中国最好的机房也会掉电,所以要每个服务单元都能支持多机房部署。另外做多机房部署有一个好处,就是用户的访问速度会提高。多IDC分布静态内容就不说了,基本上大的互联网公司都会做,它非常成熟基本上没有什么问题,比如说图片等等的静态内容。动态内容的CDN分布是业内的难点,国内很少有公司能够做到非常成熟的多机房动态内容发布的成熟方案,它的核心就是分布式存储。一款理想的分布式存储产品它有哪些需求呢?首先它要支持海量规模、可扩展、高性能、低延迟、高可用。第二个是需要多机房分布,能够满足国内负责的网络环境,还要具备异地容灾能力。第三个就是要调用简单,具备丰富数据库特性。因此分布式存储需要解决一个多对多的数据复制。 如果要做复制无非是三种策略,第一个是Master/Slave,但是它也两个缺点,第一个是Master是中心化的,如果Master在北京那广州访问就非常慢。第二个缺点是有单点风险的,比如说Master在北京,能立即迁到广州吗?这样有个时间窗口的数据就丢失了,而且需要人工的干预,而且日常广州的用户访问北京的Master是有很大延迟问题的,所以一般来说要做的非常优秀是不会考虑第一种方案的。第二种就是Multi-Master 方案,它需要应用避免冲突,就是我们不能多处改变。这个对于微博来说不会特别难,我们的用户通常只会再一个地方发表微博,用户不会同时在广州又在北京发表或者是修改自己的资料,这样的话我们应用上就已经避免了这种情况。第三个就是Paxos就是可以达到强一致写,就是一条数据如果成功肯定是多个机房都成功了,这个也显而易见就是延迟性非常大。因此总结一下Multi-Master是最成熟的策略,但是它现在没有成熟的产品,因为确实没有。 我们再来看微博的方案,所以我们自己实现了一个多机房同步的方案。就是我们前端应用将数据写到数据库,再通过一个消息代理,相当于通过我们自己开发的一个技术,将数据广播到多个机房。这个不但可以做到两个机房,而且可以做到三个、四个。具体的方式就是通过消息广播方式将数据多点分布,就是说我们的数据提交给一个代理,这个代理帮我们把这些数据同步到多个机房,那我们应用不需要关心这个数据是怎么样同步过去的。 用这种消息代理方式有什么好处呢?可以看一下Yahoo是怎么来做的?第一个是数据提供之后没有写到db之后是不会消失的,我只要把数据提交成功就可以了,不需要关心数据怎么到达机房。第二个特点YMB是一款消息代理的产品,但是它唯一神奇的地方是为广域网设计的,它可以把多机房应用归到内部,我们应用不需要关注这个问题。这个原理跟我们目前自己开发的技术相似。 然后我们再看一下目前即将推出的微博平台的新架构。我们知道API大部分的请求都为了获取最新的数据。API请求有一个特点,它大目前调用都是空返回的,比如说一款手机的客户端每隔一分钟它都要调用服务器一下,就是有没有新数据,大目前的调用都是空返回,就是说不管服务器有没有数据都要调用一次。这次询问到下一次询问中间,如果有新的数据来了,你是不会马上知道的。因此我们想API能不能改用推的方式,就是客户端不需要持续的调用,如果有新数据就会推过去。技术特点,显而易见低延迟,就是从发表到接受1秒内完成,实际上可能用不了1秒。然后服务端的连接就是高并发长连接服务,就是多点都连接在我们的服务器上,这个比传统的API要大很多。 我们看一下推送架构怎么从架构底层做到实时性的。从左上角的一条微博在我们系统发布之后,我们把它放在一个消息队列里面,然后会有一个消息队列的处理程序把它拿过来,处理以后放到db里面。假如说我们不做持久化,因为我们推送数据也不能丢失,我们就要写一个很复杂的程序,将数据异步去存,这样就会非常复杂,而且系统也会有不稳定的因素。从另外一个角度来说,我们做持久化也是做过测试的。我们推送整个流程可以做到100毫秒和200毫秒之间,就是说我们在这个时间能把数据推送出去。 我们再看一下内部细节,就是我们收到数据之后首先要经过最上面RECEIVER。然后推到我们的引擎里面,这个引擎会做两个事情,首先会把用户的关系拿过来,然后按照用户关系马上推送给他相应的粉丝。所以我们调用方已经在那儿等待了,我们需要有一个唤醒操作,就是说在接口这儿把它唤醒,然后把它发送过去。最后是一个高并发的长连服务器,就是一台服务器支持10万以上的并发连接。最右边中间有一个圆圈叫做Stream Buffer,我们需要Stream Buffer是要保存用户最近的数据。因为用户可能会有断线的,比如说他发送数据的时候断线半分钟,我们需要把这半分钟补给他。这就是我们的推送架构。 下面介绍一下平台安全部分。由于我们的接口是完全开放的,所以我们要防范很多恶意行为,有很多人担心我们接口是开放的,是不是有人通过这个接口发垃圾广告,或者是刷粉丝,我们技术架构怎么来防范这一点呢?这是我们的安全架构,做了三个层面的事情。最上面是我们有一个实时处理,比如说根据频度、内容的相似性来进行判断,判断发的是不是广告或者是垃圾内容。中间这个是一个日志处理器,我们会根据一些行为进行判断,比如说如果我们只是实时拦截的话,有些行为很难防止,我们做了个离线纠正的模块,比如说他潜伏的几个月开始发广告了,我们可以事后把这些人清除掉,以保证我们平台的健康。最后是通过监控的维度来保证内容的安全。目前内容安全的架构大概是541的体系,就是说我们的实时拦截可以做到50%的防止,离线分析大概可以做到40%的防止。 微博平台需要为用户提供安全及良好的体验应用,以及为开发者营造一个公平的环境,所以我们的接口需要清晰安全的规则。从一个APP调用我们的接口,需要几个阶层,需要划分不同的业务模块。第二个是安全层。第三个是权限层。这是我们平台安全的两个维度,一个接口安全,一个是内容安全。 我今天讲的是架构方面的问题,在座大部分是开发者,可能大家都在处理不同的架构问题,架构很多地方是相通的。我们需要做一个软件系统需要解决的本质问题是什么?微博第一版解决发布规模问题,第二版是解决数据规模的问题,第三版是解决服务化的问题。将复杂的问题简单化之后,我们才可以设计出一个容易扩展的大规模架构。我今天介绍就这么多,我们微博实际上是很需要各方面的技术人员,大家对我们的架构如果感兴趣的话、对我们的系统感兴趣的话,也希望各方面的技术人员参与我们微博的团队,随时可以给我微博上发私信。 杨为华:今天主要给大家介绍一下微薄cache设计,在我们业界有一个趋势就是平台和应用。以前Web1.0发展到Web2.0,有一种更进一步趋势就是转变成平台和应用。很多应用不是单纯一个Web应用,国内已经有不少公司做这个方向,做Web2.0或者cache,刚开始都是自己模式,希望能够把这个行业一些人聚合起来大家一起交流,大家犯过的一些错误可以避免,让我们做事情更有效率。 最早我们新浪曾经有一个DB产品,刚开始做通过我们社区介绍,慢慢让大家知道DB在一些方面用起来更适合大家的地方,后来比如说我们去年发展一种分布式的,现在随着社区大家互相介绍,如果有人单独讲一个DB会觉得很不好意思。微博最早我们只能看国外的,慢慢有不少公司做这个,刚开始我们介绍一些基本技术,比如说微博的东西可以用推和拉做,等到以后经过我们把这个话题讲到以后,有人再讲微博技术光讲推和拉觉得不好意思,要进行一些更深入的话题,慢慢我们就在这个过程当中。今天讲一下cache的设计,我讲过一次微薄扩展设计,那是一个基本话题,刚才也讲了一个架构讲得比上次更深刻,光讲一个推是不够的,我今天演讲主要从是cache进一步补充一下,一部分是Feed架构简介,第二是cache的设计。 微博技术核心主要三个,一条微博有很多关注的人,分别将你发表的微博分发到你所有关注的人,聚合就是打开微博首页这里看到我关注人的信息,以及这个微博信息的展现,微博在技术上也称之为status或者Feed,下面图就是一个典型的Feed。 Feed架构刚才是两种设计模式推或者拉,还有第三种方式叫做复合型。做到一定程度单纯推或者拉是不够的。推的话如果把Feed比喻成邮件,推就是inbo不惜是收到的微博,OUTPOX是已发表的微博,发表到所有的粉丝,查看就是直接访问到。PUSH优点就是实现简单,通常做一个种型是首选方案,缺点就是分发量。PULL发表是在自己的outbox,查看是所有关注对象的inbox。优点节约存储,缺点是计算大量,峰值问题。当前访问量比较大是不是计算得过来,服务器是不是够用,假如说你的服务器是按照你峰值规划你的服务器,在平时时候是非常多的空闲,这个是不合理,不管推和拉都有一些共同的难题比如说峰值的挑战,比如说世界杯活动在新浪微博每秒钟发表量达到2500条,我们可以使用异步处理2500个峰值,处理速度慢一点,你关注人不能马上看到,峰值过后保证系统不会被峰值压跨,下面就是cache,现在有一句话对于这种real—time就是说:传统硬盘已经不够用,很多东西要分放在硬盘里面才能满足需求。因此cache设计决定了一个微博系统的优劣。 里面是一种复合型,不是一个简单的推或者拉的类型,因为就是说像我们新浪微博到这个级别要做很多优化,从模型上就是一个推或者拉的模型,我们按照它的关系来说,把cache分成需要四种存储的东西,这两个里面跟索引比较类似,第三就是列表和客户自己资料。 看一下第一部分就是inbox微博首页开始ID列表,完全是内存里面,但是有一个缺点,我们要添加元素需要先AET再SET;第二部分outbox发出微博有存储最新ID在于聚合。为了高效,我们通常分两部分,第一就是说最新的一个ID列表比如说我们有100条内容,这个用户很久没有来,这个是空要过来取就要从我工作列表用ID地址聚合起来;第三部分是关注列表,这些都是纯ID,然后following,following加载开销比较大,上百万粉丝,越大的集合越容易变更,改变则需要deleteall减少使用followinglist场景;第四部分contetcache微博内容体里面有一个很重要的内容,热内容。这个用户有200万粉丝,这个内容是热内容,在线粉丝也非常多,多分防止单点访问瓶颈,最终格式预生成,apenAPI需要返回xml,json格式。 刚才说了介绍cache的架构,现在介绍cache的第二个方面就是使用流程。有一个典型的场景,比如说发表我们cache怎么操作,首页展现怎么操作。发表需要改变三个内容,首先我们要声称contentcache,对于常规contentcache我们也要做复制,如果对方粉丝在线会在inbox数值ID变更。 第三方面修改outbox,根据粉丝列表修改inbox数据列表,然后首页Feed操作流程。左边有两个:inbox,outbox。两个是可选的,如果inbox没有我们有一个树型计算,我们会根据ID列表聚合起来反馈给I用户。 获取首页Feed的流程,首先间看inbocache是否可用,获取关注列表,聚合内容从following关系,根据idlist返回最终Feed聚合内容。最常用两个流程就是这样。 下面介绍微博cache经验谈,首先说流量。打开首页,这个时候打一个I来说,比如说contentcache为例,比如multigntn条Feed,cache大小等于N,并发清且如1000次/秒,总流量等于50,20K。假如我们机房里面有1万并发需要800MBPS贷款,如果不改变价格这个流量是实现不了。再一个1G内网我们做了很多压力测试,一般环境跑三四百兆已经不错了,你网内不光是访问cache开销,还有很多其他流量,因此我们需要优化带宽访问,我们可以把热门数据加载到localcache,要用压缩算法,可以做复制,有的时候将一个内部cache分组,不同的服务器组,访问不同的cache减少内网通信的开销。第一个问题就是带宽的问题,其中内销cache开销访问量大第一会碰到瓶颈。第二问题就是hotKeys,我们要访问姚晨的微博,我们要建设一个Ilocolcache,删除时间要把所有的都删除。 cache规划方面一些问题,将不同业务,不同长度KEY存储到不同的MEMcache,不同的业务有不同的生命周期,LRUcache小量,memorystorage大部分,更高效的内存利用。 mutex,什么情况会出现这个问题,比如说一个很热的内容,cache里面没有了,因为memcache不是很可靠的东西,你放在里面可能会消失,经常出现这样的情况:一个很热的cache没有了,因为我们系统有很多并发很热数据没有了,非常多的并发如果我们没有一个很好的策略,比如说几十个,几百个加一个内容这会是一个悲剧。我们给每个KEY加载MUTEX,这个并发连接取数据库,然后把mutex删除成规,这个时候我只需要一个连接,数据库加载到BD里面有可以了。 因为前面已经介绍很多内容,我今天介绍一个很简单的东西就是想关注更多微博平台的技术,有三个方向一个就是S2技术沙龙,每个月举行一次,另外就是说对很多讲师光做讲座不过瘾,讲座只是传授别人东西,没有能够交流,所以我们对一线架构师有一个自己线下交流,我们讨论一些实际中遇到的问题,对这些架构师有帮助提高,交流一下自己正在做,或者有一些东西还不成熟,不适合拿出来讲的东西,可以线下交流。另外我们有各新浪微博开发大会,会介绍更多微博平台架构分享的东西。 S2技术沙龙介绍了希望关注分享Web2.0技术,下面有一个它的网址,另外就是说介绍一下即将举行一个新浪微博开发者大会,主要除了宣传作用,希望更多分享新浪微博技术,比如说这个平台需要架构与存储,可能到时候讲比今天更深入一些,会讲一些sinaappengine技术,数据挖掘,合作与商业模式,开发者与平台。目前有一个开发平台的网站。 今天介绍比较简单主要是这样看看有什么可以提问。 提问:我想问一下新浪微博设计之初有没有考虑过安全的问题,图片存储等等,这种方面的问题这个微博设计之初考虑很多安全方面工作,我想了解一下这方面有什么看法和见解。 杨为华:我们也在解决两个方面,一个用低质量内容,有一些搜索用户可能做了一些不好的东西,故意出现一些关键字让自己搜索排名更靠前,有一些用户发广告,对于传统广告我们有一些技术,新浪博客有一些技术,通过一些词语热度可以判断一些内容是不是广告内容。实时搜索我们也正在做,这方面我们也刚开始起步。 提问:我之前是跟腾讯微博有相关的,但是我已经不在腾讯了。 杨为华:没关系,腾讯微博也可以一起探讨。 提问:我想问一个比较细节的问题,你说到为了节省内部带宽的问题会使用到logcache,这个部署你们是跟Web2.0服务器放在一起还是什么? 杨为华:每个前端布置一个cache,另外还有一些APC那种基础非cache的技术,或者其他内存数据共享这种,非标准的方式都可以做,cache是一个很泛的观念。 提问:获取cache会用MUTEX的技术。这个环节具体是什么?这个环节是在哪个环节做的? 杨为华:写到一个典型的场景,热点内容有很多人同时访问这个网站,这个cache量没有了,如果不做任何保护实际上数据库访问压力很大,还有其他场景,还没有复制过来数据就过来了,很多人认为cache没有加载访问数据库也是比较悲剧。 提问:这些东西是在应用这个层次做还是类似也有一个cache上面做? 杨为华:我们是应用做的。 提问:我请问一下您微博系统使用cacheDV。 杨为华:计数方面用了。 提问:你有一个推模式,你用复合模式,你们简单介绍一下你们怎么用这个复合模式,对微博每个人都会有一些好友有会跟随一些人,能不能讲一下对于个人主界面缩影算法,我看到我的界面怎么知道哪些人在前面,哪些人在后面?能说一下你们的算法,每个人登陆进去有一个我的主界面,我有一些好友,也是一些人的粉丝,你们怎么做排序? 杨为华:我们就是时间排序,最简单的方法,我们没有找到更好的算法之前。 提问:不是根据一些热点? 杨为华:我们也考虑过那个方向,但是我们认为挑战性非常大,你认为好的方法用户不一定认可,这个挑战很大。你用算法做一些东西,但是用户认为不重要的东西,如果用户没有展示,用户可能也会有其他看法。为什么用复合模式,我们也不知道为什么叫复合模式,我们根据实时运行情况,发现哪里有瓶颈我们会想到更好的方法解决。这个瓶颈,能不能给在线用户加一个什么东西,减少系统压力,不影响原来的价值,主要处于每个性能模块的角度考虑的。 提问:你能不能说一下一个用户登陆以后你们做了一些什么步骤,我估计有些是用推的,有些是用拉,各个平台设计微博不一样,有的速度很快,有的会有延迟,你能介绍你们用户交流流程吗? 杨为华:这个图可以看到,最前面还有别的cache,用刚才方式我们看有没有命中,如果没有通过OTUBOX关注列表进行计算,然后把结果合并起来,在上面有一些配件成了cache,反映给用户,整个流程跟这个图上原理来说区别不大。 欢迎补充:微博的数据库设计 这学期学习数据库,老师让我们最后提交一份大作业,于是乎,想做一个小的微博系统,以下是我设计的数据库表: 用户信息 字段名 字段代码 字段类型 描述 编号 User_Id number 主码 用户名 Name varchar(50)   性别 Sex varchar(2) 男or女 生日 Birthday date   注册日期 Rdate date   邮箱 E-Mail varchar(50)   博客地址 Blog varchar(50)   工作 Job varchar(10)   一句话备注 Remarks varchar(100)   信息 字段名 字段代码 字段类型 描述 信息编号 M_Id number 主码 用户编号 User_Id number   发布日期 Release_Date date   内容 Content varchar(300)   评论 字段名 字段代码 字段类型 描述 评论编号 Comments_Id number 主码 信息编号 M_Id number   评论用户编号 C_User_Id number   被评论用户编号 Bc_User_Id number   评论日期 C_Date date   内容 Content varchar(300)   私信 字段名 字段代码 字段类型 描述 私信编号 Private_M_Id number 主码 用户编号 User_Id number   接收用户编号 Receive_User_Id number   发送日期 Send_Date date   内容 Content varchar(300)   回信 字段名 字段代码 字段类型 描述 回信编号 Reply_M_Id number 主码 私信编号 Private_M_Id number   用户编号 User_Id number   接收用户编号 Receive_User_Id number   发送日期 Send_Date date   内容 Content varchar(300)   关注-被关注 字段名 字段代码 字段类型 描述 编号 Id number 主码 关注者编号 concern_User_Id number   被关注者编号 concerned_User_Id number   目前是这样的思路,逐渐改进中,希望高手指点- - 一个微博数据库设计带来的简单思考 在微博系统中,当前用户、关注者(也就是粉丝)、被关注者(崇拜对象) 这三种角色是少不了的。他们之间看似简单的关系,但是其中数据库表将如何设计,却让我很难琢磨,在如下解决方案中,你们会选择哪种 ? 为什么要选择这种 ? 是否有更好的解决方案 ? 解决方案一: 表名  用户信息表  字段名  字段代码  字段类型  描述  用户名  User_id  Varchar(20)  主键  登陆密码  Password  Varchar(20)   ……  ……  ……       表名  关注和被关注者表  字段名  字段代码  字段类型  描述  用户名  User_id  Varchar(20)  主键  关注者  Funs  Text     被关注者  Wasfuns  Text       这是我最初想到的一种设计,这里“关注者”和“被关注者”都是采用拼接一些特殊字符分割存储的,比如 A用户有只有关注者 B、 C、 D、 E,那么存入数据库关注者字段的数据将是 B;C;D;E(暂且认为分割字符为;)。 基于上述方案,我提出一个问题:当这个用户的“关注者”或“被关注者”数量很大的情况下(比如 10 万个关注者)将是怎样的一串字符呢?而且当我们需要查询“关注者”或者“被关注者”最近的博客信息,将面临和博文信息表的一些时间排序查询,处理难度是要浪费性能的。 解决方案二:     基于上述面临的问题,有人给我提供了一个扩展性的解决方案,同时也很好的解决了一个字段海量数据的问题。将方案一中的关注和被关注者表分解成两张表,如下: 表名  关注者表  字段名  字段代码  字段类型  描述   编号  Id  Number  主键   用户名  User_id  Varchar(20)   关注者编号  Funs_id  Varchar(20)      表名  被关注者表  字段名  字段代码  字段类型  描述  编号  Id  Number  主键  用户名  User_id  Varchar(20)  被关注者编号  Wasfuns_id  Varchar(20)     我看到这样的设计我很吃惊,试想一下,假如我一个用户对应有 1W个关注者,那么该用户就会在关注者表中存在一万条他的记录,这难道不是严重的数据冗余吗?这甚至不符合数据库的设计规范。但是事实上证明,这种设计对大数据量的扩展是很不错的,既然如此,那假如用户和用户之间的关系不只是限于关注和被关注的关系,是不是又要新增表 ? 解决方案三:          话说“合久必分,分久必合”,对上述的设计再进一步修改,于是将方案二的两张表又合二为一,如下: 表名  关注和被关注者表  字段名  字段代码  字段类型  描述  编号  Id  Int  主键  用户名  User_id  Varchar(20) 目标对象  Operate_object  Varchar(20)   状态  Status  Number  当目标对象为关注者,标示为1; 当目标对象为被关注者,标示为2; 当双方互相关注,标示为3; 当目标对象为OO,标示为XX。   OK,这样的设计不仅解决了相当一部分的数据冗余,而且还能表示用户之间的多种关系,方便系统日后的扩展。但是问题又出来了,很明显这样设计对状态的维护也是存在疑问的,用一张表代替多张表,数据肯定是成倍的增长,是否不符合当前常说的“拆库拆表”的战略方针(好像这样的状态一般用于“标记男女”或者“是否删除了”之类的,貌似用于这种场合比较的少)。 做一个微博项目,如何设计数据库表,指点指点,谢谢了。 用户模块 |- 用户注册 |- 填写用户名,昵称,生日(选择),性别,密码,密码提示问题,密码答案完成注册(要求验证用户名不能重复,并加入验证码) |- 个人资料 |- 可以对昵称,生日,性别以及自我介绍进行修改。 |- 上传头像 |- 选择上传用户头像,只允许格式jpg,jpeg,gif和png,且大小小于2M |- 我的听众 |- 查找所有收听我的用户,并列表显示(6条,显示信息参考找人的列表),对于你没收听的用户,可以选择立刻收听 |- 我收听的人 |- 查找所有我收听的用户,并列表显示,可以选择取消收听此用户。 |- 私信 |- 收件箱 |- 可以查看收到的所有私信,列表显示(5条,按时间倒序),显示发送用户的昵称,照片,发送内容,发送时间 |- 可以选择删除某封信,也可以选择直接回复私信 |- 发件箱 |- 可以查看所有发送过的私信,列表显示(5条,时间倒序),显示接收用户的昵称,照片,发送内容,发送时间 |- 可以选择删除某封信,也可以选择为其再写一封 |- 写信 |- 输入收信人帐号以及发送内容,将私信发送给该用户 广播模块 |- 我的大厅 |- 显示当前登陆用户的照片,昵称,并显示我当前的听众数量以及所有发送过的微博数量 |- 可以在输入框里发送自己的微博信息,允许上传一张图片(也可以不传) |- 可以显示所有收听的人和自己发送的最新微博信息(时间倒序,5条每页),显示时要显示发送人昵称,照片,时间(显示距当前系统时间的差距,例如:XXX分钟前,XXX小时前,XXX天前。 只需要显示最大范围的单位即可,例如:如果是1小时30分前,只需要显示“1小时前”即可。) |- 显示最进的热门话题(显示5个,按消息数量倒序) |- 我收听的话题(显示5个,按消息数量倒序) |- 我收听的用户(显示9个,按听众数倒序) |- 广播大厅 |- 显示所有人发布的微博信息(5条,按时间) |- 可以选择30秒自动刷新功能(选中的每30秒自动刷新页面) |- 热门话题,我收听的话题(同上) |- 我的广播 |- 显示我发布的最新微博信息(时间倒序,5条) |- 其他同上 |- 提到我的 |- 显示所有微博消息中对我发送的消息(在对话和转播中查找,5条,时间倒序) |- 收藏广播 |- 显示我收藏的所有微博信息(5条,时间倒序) |- 对话,转播 |- 可以针对某条微博进行对话、转播(与正常发送功能相同,但列表显示时显示 对话的那条微博信息,转播也同样处理) |- 新建话题 |- 发表微博信息时可以输入一个话题名称,如果该话题不存在,则保存此话题,如果该话题存在,则直接将这条微博消息加入到这个话题中 话题模块 |- 热门话题:显示15个话题(按信息数量倒序) |- 收听话题:显示15个话题(当前登陆用户收听的话题中按信息数量倒序) |- 话题内容:显示该话题下的所有消息(每页5条,按时间倒序) 其他 |- 公告 |- 公告列表,每页3条按发布时间倒序 |- 公告详情:显示公告标题,公告发布日期,内容 |- 搜索(广播,找人) |- 找人 |- 进入找人页面后,显示出最新的6个注册用户,以及推荐的12个用户(按广播发送数倒序,取得发送最多的12个人) |- 输入查找的内容后,依据用户名,昵称来进行模糊查询,列表显示(5条),显示时要显示照片,昵称,最新发布的广播,收听人数以及广播数,可以选择收听这个用户 |- 查找广播 |- 依据关键字查找符合条件的广播(5条,按时间倒序,显示发布昵称,照片,内容,发布时间) 微博数据库设计 看用什么语言写,用php+mysql比较合适,sql数据库应该学过吧!这个学过的话在网上下载一个开源的记事狗微博( http://www.jishigou.net/),模仿他的数据库设计,微博涉及的数据库很简单,写过留言板的都可以弄,就是权限系统会复杂点! 学习园地:微博项目 介绍 微博是一个时下很火热的web2.0应用,使人们能随时随地的用手机或电脑获取信息和发布信息,基本功能比较简单,但要做细化功能和提高性能也是需要相当多的经验,所以想让大家通过自己制作一个微博系统来锻炼web开发能力及项目经验。 什么是微博:http://help.sina.com.cn/i/232/482_12.html   程序员的门槛现在越来越低,85后90后现在都开始进入这行了,其实真正要把代码写好,需要很多的经验和技巧,是个长期积累的过程。微博这个项目没有太高深的技术,就是大家已经学过的asp.net,sqlserver,HTML等,主要是通过这个项目锻炼一下编程的各种基本功,巩固已经掌握的知识,稍微全面的了解一个小型项目的开发流程。 本活动可培养如下能力 1、通过CodePlex的VSTF代码管理,练习源代码管理器的使用。 2、通过分析新浪微博的功能,锻炼业务分析能力。 3、通过编写各种文档,增强对Word的使用熟练程度。 4、通过编写用例分析文档,锻炼需求分析能力及编写有效用例的能力。 5、通过编写概要设计文档和详细设计文档锻炼文档书写能力和基本的设计能力。 6、通过画分析和设计阶段的UML图锻炼UML能力及提高Visio使用熟练程度。 7、通过设计数据库增强数据库的设计能力,以及优化数据库查询的能力。 8、通过简单的界面设计锻炼css布局的能力及css,html的熟悉程度。 9、通过实现页面的ajax功能提高大规模js代码编写能力以及ajax库的熟悉程度。 10、通过单元测试培养重视代码质量的观念以及提高单元测试的经验和技巧。 11、通过服务端代码的实现锻炼asp.net的熟练程度以及增强.NET类库的熟悉程度。 12、通过解决排查测试出来的问题锻炼代码调试的能力及代码重构的能力。   活动过程 1、了解微博功能 注册新浪微博,分析其功能,罗列出功能列表,并知道每个功能对最终用户的价值。 输出:《新浪微博功能分析》《XX微博逻辑设计》 前者是对新浪微博的功能分析结果,后者是在前者的基础上进行裁剪或者改进定下来将要做的微博系统功能列表及每个功能的逻辑,用户看到逻辑设计后就可以知道每个功能怎么用。 2、在CodePlex注册项目 在codeplex注册一个开源项目,以后所有相关文档和代码都放在上面,源码和文档的目录结构要设计清晰合理。 输出:项目的名字,codeplex的项目地址 3、写用例分析文档和功能测试方案 查阅相关书籍或者网络资料,了解如何写用例分析文档及注意事项,根据第一步对微博功能的了解,写出用例分析文档。 用例分析文档有了之后,要根据它制定功能测试方案,比如用户如何注册账户,如何发微博,每一个操作步骤,每一步的预期,都写清楚,关于如何写测试用例可查阅相关资料。 输出:《XX微博用例分析文档》《功能测试方案》 格式要求用word,要生成目录索引,页眉页脚,格式要求统一专业。 4、概要设计和技术方案 根据逻辑设计和用例分析文档,做出系统的概要设计,大概用到哪些类,类的公开成员,类之间的关系,关键用例的序列图。并在此阶段确定出技术方案,服务端使用什么语言和框架,使用什么客户端ajax框架,数据库使用什么,需要不需要第三方库以及大概的主机需求,硬件方案,容量估算等。 输出:《XX微博概要设计》《XX微博技术方案》 UML图使用visio画,UML知识可参考网络文档,使用最多的是类图,序列图和组件图。 5、详细设计 细化概要设计,把类的私有成员细化出来,关键用例的序列图,关键算法的描述,性能考虑等写出来,服务所需要的配置项,需要设计哪些性能计数器,哪些环节要生成日志,日志的格式约定,哪些地方使用缓存,平台有哪些角色,每个角色的权限是什么。 输出:《XX微博详细设计》 6、数据库设计 根据详细设计做出数据库设计文档,表,索引及主要的存储过程,注意表,索引和存储过程的命名规则要统一,并分析出最常用的DB操作的性能消耗,以及如何控制。 输出:《XX微博数据库设计》,建库脚本 7、界面设计及编码 用HTML和CSS进行页面的布局,不需要搞太漂亮的图片,主要锻炼HTML+CSS的使用能力,模仿一些比较成熟的网站布局就行,看能否模仿出来。 通过前期的准备,用VS2008进行编码,包括HTML,JAVASCRIPT,C#,SQL,CSS等,在编码的过程中同时审视前期做的设计和分析是否有遗漏或者错误,并同步更新文档。 输出:代码。 8、单元测试 在编码过程中要对c#代码中的业务逻辑进行单元测试,找一些单元测试相关的最佳实践资料来学习,单元测试可能会有一些困难,遇到困难可以在相关社区求助,锻炼利用网络解决问题的能力。 输出:单元测试项目及代码测试覆盖率统计 9、功能测试 自己作为一个使用者根据先前制定的测似方案对最终的代码进行测试,包括在各种浏览器好分辨率下的兼容性测试。 输出:《XX微博功能测试文档》 10、部署文档 把代码输出打包,编写用户使用帮助,管理员配置说明,运行监控及维护方法等。 输出:xxx微博.rar,《XX微博使用帮助》,《XX微博部署及维护说明》 在每一个阶段性里程碑的地方,可以把输出拿出来大家讨论一下,然后再往下进行,在进行的过程中可以把自己认为不错的资料转贴到小组里,分享给其它同学,遇到问题也可以在小组里进行讨论,最可怕的就是什么问题都没有。

下载文档,方便阅读与编辑

文档的实际排版效果,会与网站的显示效果略有不同!!

需要 15 金币 [ 分享文档获得金币 ]
4 人已下载

下载文档

相关文档