我的2012-分享我的四个项目经验

前言

    一看标题就俗套,一时也想不到各种华丽的名字了,直接copy去年的标题,只是将2011改成了2012。还好今年也没有末日,活着就是幸福。在12年最后一天的工作日,刚好可以花点时间回顾下今年的工作情况以及稍微规划下明年吧,希望慢慢的按着自己的规划往前走。
    如果有看过去年的朋友,可能会发现与去年的巧合就是都是在最后一天来写。。尴尬。。
    本文大致会分两部分,一个是今年回顾,一个是明年的设想,与规划相比我更喜欢设想这词。
    另外就是描述方便就直白叙述,不会太书面语,希望本文有些知识可以给大家一点帮助,下面是正文!

回顾

    既然是回顾,那么这部分就会从年初说到年尾。主要叙说工作上的事情,以及今年学到了哪些知识之类,还是和去年一样会按照项目来叙述。

    推荐系统:

    这个是和去年的最后一个项目是同一个,去年没有做完,在那边有描述是关于hadoop这一套的。整套推荐做到了4月份其实完成了demo,在7,8月份上线的,后面还做了很多更改。这里接去年的继续往下说。
    关于从hadoop出数据方面:目前也就是生成影片id-用户id,应该来说大部分的视频网站有很多用户可能没有注册的,那么要出推荐,并定位到用户,那么就需要取用户的mac地址来标识出用户的身份,这点客户端是可以做到的(我们就是客户端),而宽屏网站想youku,tudou怎么取的这我不太清楚,前端东西不了解。当根据历史观看记录来生成了movie_id->user_id的,用mahout就可以跑出来个性化推荐(根据用户推)和相似度推荐(根据影片推)这两部分数据。做出来的分别是user_id-》movie_id和movie_id-》movie_id。
    根据hadoop出来的数据,那么就要在hadoop,hbase中查询各种记录,并根据业务需求生成相关的数据,如影片名,描述,图片,导演,评分,还有一些其他方面的数据(不好透漏)。既然详细的数据出来了,就要考虑如果提供服务给用户,为了快速访问我们先期也考虑过很多nosql,最后选型为redis,不过单台的redis根本容不能将我们全部的数据load进去,又使用了一致性hash做成伪分布式redis,将底层redis访问做成异步库,这样抛弃master-slave模式,数据分别存在多台redis中,并且有些由于个性化推荐数据太多,还有一些其他要求,因此,我们不能贪图简单而所有的数据全部都通过简单的set key value存储进去,这样会浪费相当多的内存。查过文章,将符合hash存储的数据进行处理,一是减少key长度但保证key唯一,二是保证sub key 列表不要太大,一般都在几十到一两百,这样处理后,总共使用了48G的内存,比原先节省了一倍多,还是很ok的。结合封装hiredis做成异步库及做个入库程序,对于1.2亿条数据,可以在1个小时内全部倒入到redis。因此底层数据存储就是这样了。
    再说服务提供,毋庸置疑,我们选择了nginx,apache没有选是不需要用到这种多进程多线程的work模式,当然了如果高并发下nginx会资源占用少很多,由于底层访问redis是已经封装成异步的,因此nginx每次操作也不会阻塞,只要写个nginx模块,将http接口做好,该过滤的过滤,并且做份热点数据,作为如果针对该用户没有的推荐则从热点数据中取。这样保证任何人都有数据,这对于个性化推荐时这样的,对于相似度推荐则还要保证如果没有推荐数据,则要在热点数据中找到同类型的影片数据作为默认相似度推荐结果来返回。现在说到了nginx对于前端http请过过来,来返回推荐数据,还要再做一步,就是前端请求,肯定是需要你返回有某种格式的数据,那么nginx这边做成可配置,方便变更,我们采用了google ctemplate做几个模板,来针对不同的接口的需要。
    到这,就算基本差不多了,然后就是上压力测试,做配置进行自动部署,以及之后的需求变更,稍微小改改。

    搜索系统:

    这就是个基于clucene的全文检索,不过在我们这是做成了搜索影片的一套系统,关于clucene,可以参看apache的lucene。clucene是c++写的,算apache lucence的其他语言的一个实现。不好的就是,作者挺久没有更新了,我觉得,没接触过的,还是直接玩apache的比较好。或者其他的活跃的开源实现。
    搜索这套我们之前是有一套的,不过架构不好,代码混乱,维护起来不好维护,且无法动态更新,每次索引更新都要重启apache,也就对用户是用影响(虽然很短暂)。旧的架构模式就不说了,就说下新的架构,其实也简单,后端clucene的检索做成库实现所有搜索处理(后面简称库,也可以理解成含有搜索实例的一个pool),apache做个模块(后面简称模块)。模块会在apache进程初始化的初始化库。当前端有请求到来时,初步解析,并调用库的接口,传递请求,获取搜索实例,等待搜索结果的响应。这样就是写个模块,编译成so扔到apache/modules就可以了。库内部都有几个搜索实例,搜索实例是有针对不同虚拟主机的且每类实例个数都比较少(多的话,clucene占cpu太高),搜索实例用来完成搜索,当一个线程接受到请求,并去尝试获取符合这个请求类别的搜索实例,如果没有请求到则按照FIFO的原则push到请求队列中,避免请求时间不均。搜索到后会填充模版(还是ctemplate)返回给模块,模块会告知apache将结果响应给前端。为了支持多域名也就是虚拟主机使用不同的索引,还在模块中做了处理,使得能正确告知每个虚拟主机的索引位置,模版列表等参数给库,这样在库在初始化的时候可以生产对应类别的搜索实例。另外就是索引部分了,因为原始数据时每天变化的,有增加也有减少的,那么就不能使用增量索引,而是使用重建索引,还在量不是很大。建索引的程序每天会执行几次重建索引,那么我们会安装日期变化将索引生成到指定目录下的一个有着规则名称的目录名下,如所有索引在index中,动态索引目录就是2012.12.29.14.1356762061。当重建索引成功后,会将这个新的索引目录的绝对路径填充到共享内存中,而库则会由间隔一段时间读取共享内存,判断是否有新的索引需要使用。有的话,则搜索实例内部重新生成下。这里共享内存的话,使用boost::interprocess就可以了。这样就完成了动态索引更新,而无需重启apache也不会影响用户搜索体验。
    索引既然是每天都会重建,那么就需要定期清理旧索引,否则磁盘占用会越来越多。而这只需要用一个脚本每天定时跑一下就可以,只要将前一天的索引都删掉掉在这之前先查看共享内存中记录的当前使用的索引是哪个,防止误删。
    至于到代码层面,就不细说了。

    分布式flash系统:

    好吧,名字挺牛叉的,是什么东西么,举个例子;我们在优酷上看视频,从技术角度看,首先是走HTTP请求,然后定向到后端调度服务器集群,告知该片实际所在的存储服务器,然后重定向到实际影片所在的存储服务器去请求数据。我们也是做的这一套东西,有点遗憾的是,没有全面上。
    下面说说这东西我们是怎么实现的。从功能划分,有调度服务器和存储服务器,以及一个全局的注册服务器,用来监控其他两种服务的状态。
    在说每部分大致实现的之前,先说下zeromq,因为在这几个服务里面用了很多。zeromq封装了底层通信,提供了几种概念,如req-rep,pub-sub等。req-rep就是请求-响应,是一应一答这种模式,也客户端发起请求,然后服务端做响应,这种模式都是按照这个顺序来,不会没有接受到req而直接rep。pub-sub就是客户端是接受者,服务端是发送者,如服务端有1000个连接,需要发送消息广播给所有连接,就用pub-sub模式。至于详细的可以去google zeromq guide 。另外关于zeromq使用之前也写过一篇文章,也算是对细节方面的一个总结。
    存储服务器,分后台扫描计算服务和前端apache两个服务。后台在启动的时候向注册服务器注册。启动时,会启动tcp pub和ipc pub,tcp pub广播到所有调度服务器,ipc pub是广播到本机apache的每个进程,同时后台还启动tcp rep和ipc rep,tcp rep是用来监听所有调度服务器启动后的第一次请求获取当前存储服务器上的所有影片列表,ipc rep是用来监听本机apache启动后第一次请求本机所有影片文件列表信息。在之后定时扫面磁盘更新影片列表信息后会向所有调度服务器以及向apache进程广播列表对照信息。apache启动时,每个apache进程都会向后台发起一个req,后台如果已经有数据则rep列表回来。并且apache模块和后台还有一个sub-pub连接,也就是每个apache进程都可以接收后台的publish影片列表变更信息,这些都是使用zeromq。那么真正的提供数据服务就是前面提到的重定向到存储服务器上,也就是apache模块来接受这个请求,并从当前进程中所保存的列表信息中查找该请求所请求的文件是否在本机中,有则返回数据,否则返回NOT FOUND。另外还有一个就是状态监控,后台服务会定时向apache模块发起请求,并判断apache是否正常服务,并将状态通过req定时向注册服务器汇报,这样,注册服务器就可以监控到存储服务器上的apache运行状态,以及如果超时还没有接受到存储服务器的状态汇报还可以判断存储服务器已经失效。
    调度服务器,分后台tracker和前端apache两个服务,就如前面说的,存储服务器启动会向注册服务器注册,同时注册服务器会返回当前所有已经注册的存储服务器节点。然后存储服务会分别向所有存储服务器发起一次req请求每台存储服务器上的所有文件列表,之后还会启动sub模式向所有存储服务器发起连接,用来接受存储服务器的列表更新。也就是说,任何一台调度服务器都维护了文件映射到实际存储服务器的列表。并且tracker会启动ipc的pub和rep模式用来向调度服务器上的apache的每个进程广播或响应当前trackre所维护的文件到存储节点的映射。而apache用户在启动的时候也会做存储服务器的apache模块类似的启动req,sub,用来获取本机的后台所发送的列表(这两者apache模块仅仅就这部分功能是相同)。这样在apache的每个进程中就都维护了一份文件-》存储节点的列表
在调度服务器上的apache用来接收前端请求(前端总是先向这请求),并确认所请求的文件位置,然后返回一个302重定向,设置重定向的地址前端就会自动跳转到存储服务器,如果没有找到,则返回NOT FOUND。另外监控方面也是和前面差不多。同时,tracker还有一部分是做负载计算的,这里就不想说了。最后一点就是,当存储服务器失效的时候(如当机,掉线,服务崩了),那么要保证把将失效节点对应的所有影片列表从当前保存的列表中踢除,并广播的apache模块,因此,tracker还需要定时向注册服务器查询所有的存储服务器列表,如果对比之前保存的存储服务器列表少了,并且超时,则执行所说的踢除操作。
    关于失效,如果用优酷用的多的,就会发现,优酷有些时候也会存在文件找不到的情况,只要刷新下,就有可能可以正常播放,这就是由于某些存储节点没有及时踢除,当请求过去的时候定到了一个失效的节点,就会请求不到数据,刷新下,那么调度服务器一般会从一个文件所在的所有存储节点列表中按某种策略选择一个返回,这时就有可能返回的那个节点是好的。
    最后注册服务器,相当简单,一个是rep,分别接受前两者服务器的注册消息,状态汇报,以及调度服务器的查询消息。注册服务器可以分别配置全局配置,在响应消息的时候,可将对应类别的全局配置广播出去。这样就可以一个个修改所有的配置文件,当然,这些在前两者服务器也会做响应的处理,使得能正确重新应用全局配置。

    夭折的IM系统:

    由于前端没人做,搞了一个月应该有的,然后被宣判推迟了,这个在我看来是已经夭折了,不过还是有些东西可以拿来分享的。
    这个关键还是选型,可以在xmpp.org上看到有很多的lib,client,server都现成的,当然,为了匹配业务需要,要选一个容易的,还是比较麻烦的。我们选的是tigase,这个以前csdn上也有报道国外哪个社交网站用这用的挺不错,然后作者也是很活跃,有问题都会及时帮助解答。我这里所说的tigase是指tigase-server以及muc component。因为我们业务要搞群,以及点对点聊天,以及其他的一些功能,那么有些需要在开源代码上面修改。tigase是java写的,看代码不太容易,各种多继承,有点绕来绕去的,初次阅读,建议从eclipse倒入,因为目录下会有一个pox.xml,都懂得。然后debug跟踪下,会对流程熟悉点,否则真的不好看懂。
    点对点的话,基本的用用是可以的,不过还有各种权限状态之类的,如果要搞,也要改,不过这个可以写plugin。
    群,xmpp协议的muc(聊天室)是不支持持久化的,这个需要在muc component中改代码,这部分已经实现可以支持用户离线,且权限及相关数据正确保存
不过这只是最基本的一部分功能,还有些协议要扩展,没人搞前端,现在也没法测。
    关于tigase资料的话,可以在tigase.org找到。最后只能对这个项目说遗憾,不然搞起来还是有点意思的,虽然是java做的~
    其他:
    在年底的时候,自己也稍微总结了下,稍微写写写,挂在github上。如果想学apache/nginx的模块编写的话,或者了解下libevent demo怎么用,再或者像看看apache apr的使用的话,可以在这个地址github.com/iamwljiang里找到。
    另外的,年底前,各种事情缠身,年中的时候函数式编程clojure看了一个头,希望以后能好好学学,以后可能会有大发展。关于逻辑方面,看云风开源的skynet,向学习学习别人如果设计框架的,其核心虽然是c写的,但逻辑全部是lua做的,也就使得我对lua有兴趣了,看差不多了,还挺好玩的,希望能自己琢磨到如果合适的嵌入。今年大致就这样了,做了几个东西,自己独立完成能力有提高,接口设计还要学习~

设想

    过两天就是跨年了,乘着总结,也设想下在工作方面的话,如果有可能的话,希望接触游戏行业或者还是继续在当前行业,继续做一些有挑战的项目,继续提升自己能力,另外要开始专注于大并发,高性能网络服务器方面的开发,然后跟随技术脚步多了解开源事物,别掉队了。工作之外的话,自己希望做几个正规点的开源项目,目前已经有大致方向了,有空就一步步来。关于读书,手头还有几本书,可要看看完。能全部做完,我觉得在明年回过头来总结的时候,会没有遗憾

杂项

    吐槽下,一是这么长的篇幅,一年真没几次,早上写到晚上才写完。。
    二是希望身体真的健康,饮食注意,不然真就坑进去了,也不知道几时能康复,认识基督教的朋友,也许要请教下,是否信教有用,有用的话,我也去入门下。
    最后祝大家节日快乐
    
                                                                                                                                                                                        2012-12-29 于 杭州
            

  • 11
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 11
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值