海哥学习笔记

新鲜事服务相关知识学习

  • 服务部署方式icegrid学习(registry>>node>>icebox>>service>>*.so
  • 新鲜事服务处理流程(feedassistant完成数据的前期处理,feedassistantN再次处理,然后dispatch,存入feedcache,由feednews取出cache中的数据,交给feedview处理

日报2011-11-15

1.学习了feedview下的代码,重要内容(feedviewI.cc;expandfeed.cc;body.inc;storage.inc;typetable.inc)

  • 渲染工作就是将取来的xml数据文件中的数据填充到ctemplate模板中,然后以html格式输出。
  • FeedCache中有两个方法:Add()和Get();其中Add方法负责将cachedata(成员为uid和feeddataseq)存入feedcache中,Get方法则是从cache中取出数据来。
  • ExpandFeed负责渲染的实现,就是将模板中的key用value填充。在body.inc文件中存着fill方法,每一种类型的新鲜事 对应着一种fill方法;在table.inc文件中保存着fill方法和类型id的对应。ExpandFeedData方法为对外接口,根据不同的模板 和不同的新鲜事类型采取不同的填充方法。
  • FeedViewI完成渲染工作,输出html结果。GetHot方法中调用ExpandFeedData方法完成对模板文件的填充。
  • logicaction和head_hdf_parser分别完成xml的解析。后者重要是完成对于数据库或则storage.inc文件中的 headurl的解析,取出正确的headurl,前者分析xml文件的逻辑结构,其中builddict方法很重要,就是实现了xml到字典的转换。

2.完成google ctemplate的学习。

  • 变量名#片断名>模板名!注释名
  • C++对于模板的填充规则和方法。主要就是字典的key-value的转换。

3.学习心得:

  • ctemplate采用的就是MVC模型,这样我们可以更专心与处理业务逻辑。
  • ctemplate就是简单保存key,其逻辑也只能简单的处理IFelse(变通方式,在expandfeed中有自己定义的IF等)。
  • 观察者模型设计的学习,在ServerStateSubscriber中用到了此设计模式(很多的服务观察一个registry的xml配置文 件,一旦xml文件的内容发生改变就通知服务,那么服务也发生相应的改变)。其完成的就是对于registry了的服务的监控和配置。
  • log的学习。MCE_INFO();MCE_WARN();MCE_ERROR();MCE_TARCE();知道log查看方法。
  • so编译:编译--shared生成共享库.

 

日报2011-11-17

学习内容:

1.FeedAssistant目录的代码

  • a.DbHelper
  • b.Tasks
  • c.FeedCreatorI
  • d.FeedAssistantI

a.DbHelper负责处理与数据库相关的内容,其中用到了监控器monitor来解决线程的互斥问题,使用监控器,线程可以检查某一个条件,并 且可以在监控器内挂起自己。使用方法:IceUtil::Monitor<IceUtil::Mutex>::lock lock(线程);接口addFeedIndex(执行insert),getFeedIndex(其中的select语句中用到了limit 10,因为一旦结果集中的条目太多容易发生错误,所以指定最大的返回记录行数为10,不过此接口是完全匹配选 择),getFeedIndexbySource,getFeedIndexbypSource,getFeedIndex(feed)返回单个 feedindex,removeFeedIndex(执行delete,执行不止一条语句的时候用的loader,单条语句直接用store;用到了 taskmanager将执行的任务存入线程池,isselect==1的话就执行当前任务),主要学习的就是qureyrunner和 taskmanager配合使用,更快的完成数据库的读写,同时减少用户等待时间。关于seqid我们自己用createId来自己更新,我不知道 mysql中有没有序列?查过了 没有。oracle中有序列(唯一的多表可以查看的不会引发并发问题的sequence)。

b.Tasks就是将一些需要用到线程池计数处理的任务给出具体实现。基本上都是MyUtil::Task,几个removeFeed的task, 还有几个read和dispatch的task;其中有一个replydelaydispatch是定时任务,可以异步响应。 feeddispatchtask中我们点用了dbhelper的createId()创建了一个feedid,对于上传单张照片或者多张照片的时候 (stype=701或者709),将在news和mini中都显示。(8189,1702,<8001,8005>)类型的新鲜事要写入 db,其他的只存入cache,对于news和mini的新鲜事要写feedcontent(DB),将reply的部分延迟发送。分发工作就是将要写入 到cache的写入cache,要db操作的db,对于新鲜事要由我们给出其id。

c.FeedCreatorI新鲜事的创建。LoadAllConfig接口:从数据库feed_config找出所有的typeconfig,从 data_config独处所有的dataconfig,调用BuildDataConfig()和BuildFeedTypeConfig()方法完成 config的填充,其中config-keys的赋值的时候,有一个重复转换的方法调用(做了两次的c_str()),在xml文件中遍历一次节点,返 回key-name和bool的映射。data2xml函数就是见data转换成xml格式存入到数据库中。

 

日报2011-11-18

学习内容:

1.学习网上文章<TUP第二期人人网张铁安:Feed系统架构分析>和<微博feed系统推拉模式和时间分区拉模式架构探讨>:

2.新鲜事系统的基本概念阅览:

FeedItem:为一条新鲜事的基本数据,一个32字节的结构。

FeedIndex:ugc到feedid的映射关系。ugc:user generated content(用户原创内容)

合并(mergeid,替换和追加)和排序(排序因素:好友亲密度 时间 交互数 分发数)。

系统结构的理解(发送接口->分发->Cache(列表cache:本体cache)>业务Cache>获取接口)

observer模式的push和poll模型,flyweight模式(享元模式;索引cache的时候应用,分出了FeedIndex和FeedContent);

MemCached了解;

熟悉了系统架构以及各子系统的功能,以及对于observer和flyweight的学习。

 

日报 2011-11-21

学习内容:

1.FeedAssistant学习:(了解其功能及接口)

a.入口中启动一个线程池执行一个定时任务:输出一条log,记录当前cache大小

b.调用ReloadAllConfig:实际上调用到的是FeedCreatorI的LoadAllConfig接口,将配置信息加载进来。配置 信息包括FeedTypeConfig(从feed_admin的feed_config读出信息)和FeedDataConfig(从 data_config读出信息),调用了BuildFeedTypeConfig完成数据库的结果集到typeconfig的转 化,BuildDataTypeConfig完成到dataconfig的转化.

c.提供的接口:dispatch():创建一个feed,不过先验证用户状态,并且对于app feed丢弃一半,调用DbHelper的createId()创建一个feedid,判断stype,如果需要saving_db则将 extraProps[saving_db]=1;调用FeedAssistantNadapter的dispatch()方法,单项调用分发,调用 FeedStatAdapter的dispatch打log.

d.dispatchWithReply():分发新鲜事和回复.

e.addFeedReply():新鲜事追加回复。

f.InitNotSavingStype():不需要保存到db的类型初始化.

g.create()和createWithreply():创建FeedSeed.前者是后者的特列即reply=0.

2.maven学习:(以及完成java的feed中的输出语句的注释任务)

a.命令:mvn package;mvn compile;mvn eclipse:eclipse;mvn clean;mvn install;mvn site;mvn -U clean package;mvn deploy

b.mvn规范的学习。

 

日报2011-11-23

1.学习内容:

FeedAssistantN代码学习:a.服务初始化中,启动定时器starttime定时打log,定时器 FeedReplyBufferTimer更新reply(目的是再removeFeedReply的时候可以调用changereply()将最新的评 论换上去);初始化一个replylogger;初始化db入口;设置服务配置信息,时间间隔5;

b.接口:removeFeedReply:先从indexcache中获取feedindex如果没有就从db中获取并且将其插入到cache中,这样减少了db的访问,然后changeReply(),同时更新本体中的reply信息(memc的操作)。

c.removeFeed接口:将feed删除(DB:FeedIndex,FeedContent,FeedMini,cache:IndexCache;memc);

d.read()接口:读取新鲜事.调用响应的adapter的接口.

e.dispatchEDM:(与新鲜事置顶的广告推荐有关的新鲜事分发),传入FeedSeed,如果在cache中就取出其index,负责从 DB中取出来并加入到indexcache中,如果都不在,就是新的新鲜事,创建FeedId,FeedIndex,FeedData,做数据库和 cache操作,memc操作,加上配置信息,dispatch.

f.directedSend:将新鲜事直接add到FeedNewsAdapter.dispatchNewsAgain():从db中读出 feedindex,设置发到首页=1个人主页=0,做成seed调用FeedDispatcherAdapter的dispatch()分 发.dispatchAgain():从cache取,没有就从db中取,对于stype为601,701,709的新鲜事,将content写入 memc,然后feedseed加上配置信息,分发出去.

2.回顾相关:

再次回顾发送接口和分发前相关工作.理解FeedSeed,FeedItem,FeedContent,FeedIndex,FeedConfig关系已经各自的结构和使用场合.

Index到fid的映射关系标示为FeedIndex.业务部门可以根据已知的Index获取Fid;FeedSeed分出Item和 Content,用到享元模型,将Item放到列表cache中,有需要就分发出去,分发到业务cache,根据item可以从本体cache或者db中 取出content,在content中有一个xml字段,应该就是feedview用到的xml字段.FeedConfig是分发时需要的相关配置信 息,比如分发去向等.

3.预习内容:

在Tasks文件中有两个任务:FeedDispatchTask和ReplyDispatchTask;看了代码有点混乱暂时停下来理头绪.

 

 

 

5.分析代码:FeedDispatchTask和ReplyDispatchTask

多索引容器:boost::Multi_index_container.(多个索引方式)

ReplyDispatchTask分发reply,更新最后一条reply,将reply加到db中,然后分发出去.如果是701或者709就调用photodataGatheringadapter增加照片评论.

FeedDispatchTask:新用户的权重加2处理,如果需要发给小群或者mini就存入到相应的db中.同时也要加到小群维护的 feeditem列表.如果发给news或者mini就dispatch出去.reply内容延迟分发.圈人或者照片第一次回复都要多加处理,相关计数器 处理.

 

 

feed系统分析,关于feeddispatch的接口再次分析,对于notify()的接口有了重新的认识,上次的理解有误.
notify的接口调用了私有函数AppendNewsFeed(int from,int to,[int type,]int limit):
1.设置表达式为u(to),发送到首页不发送到个人主页,更新时间
2.从数据库的表feed_mini_(from%100)中读出user=from的内容,创建feedseed,调用dispatch(seed,config)分发
3.addBuddyNotify(host,guest):将host的日志,照片,状态,分享四类的新鲜事分发给guest;用于guest为host刚刚添加的好友的情况.这里有8个调用,就是host和guest是互相,都有通知的...在功能的理解上没有错误.
4.joinPageNotify(page,fans):将page的前5条新鲜事分发给fans,用于fans刚刚加入page的情况
5.类似情况不予说明,强调内容.新产生的新鲜事比如回复,比如用户发布的状态或者照片,经过了入口步步深入,最终到达 FeedDispatcherAdapter::dispatch(),所以调用只是发生在feedAssistant处,但是对于上面的3,4的类似情 况,调用的是notify()的接口来分发新鲜事.
6.对于expr的解析:对于expr为u的就是类似3.4的情况,其他的按照列表算,最终就是决定了feed的去向..比如f(123):去向id为123的friend

7.对于score的算法:有参数rp(reply),cl(click),rc(replycount) :::(cl+rp)/(rc+2)

8.在本体cache(Memcache)中我们只cache了data和一条最新的reply,并且我们的FeedAssistantN中不断的 UpdateReply()保证了reply为最新的reply;我们利用了memclient提供的接口为set做相应的处理(取出content给其 赋值,删除的话直接将content设置为empty);对于reply网页显示出来的是2条,第一条和最新的一条,这样我们在取reply的时候是不是 从cache中取出一条,如果replycount大于1我们再从db中取出第二条???????(我X,刚刚犯了一下混,我们cache的是两条啊,, 飞哥一语点破,,,replydata中有old和new..)

posted @ 2011-12-09 19:58  tangr206  阅读(437)  评论(0)    收藏  举报