坛子里有朋友问,关于在线用户动态信息的管理,应该如何设计数据库以及优化,正好本人碰到过类似的问题,谈了一点看法,这里保存下来,供大家参考。
这个问题我看了很久,也很想看看大家的分析,一直在思考。
这实际上是一个比较普遍的问题,几乎所有论坛、IM软件、社区、博客之类的,需要用户验证和状态查询的软件系统,都会碰到这个问题。
我在工作中也有碰到。
经过思考,我认为这是一个业务优化问题,而不是一个功能优化问题。
这里面有一个惯性思维,我们把用户信息放到数据库中,已经有了这个框架了,因此,以后我们处理问题,第一直觉就是如何想办法优化数据库,包括重新组织表,加事务,加查询之类的机制,来提升某个瓶颈业务的性能。
但大家有想过没有,这实际上变成了一种毫无规划,头疼医头,脚疼医脚的打补丁行为。数据库已经成型,很难更动,如果要加针对性的查询表,加太多了,实际上数据库恶性膨胀,整体看来,平均能力更为降低,得不偿失。
数据库提供的,仅仅是数据存储功能,如果依赖数据库来做查询,这本来就不是它擅长的业务,因此这个时候,我觉得我们有必要跳出框框来看问题了。
仔细分析一下,其实问题很简单,我们有一个数据库,里面存了用户所有的信息,包括在线状态等动态信息,现在我们有一个需求,即查询一个人的n个好友的在线状态,因此,引发一次数据库的select,然后发现性能很低,我们需要优化。
ok,我们的关键需求仅仅是查询一个人n个好友的动态信息。
那我们可不可以考虑,如果这件事不让数据库来办,而是我们在网上单设一个服务,这个服务就是为大家快速提供每个人的动态信息的,只要client端丢过来一个查询的用户id列表,server端即回送这个列表中所有用户id的状态,至于怎么存储,怎么查询来得快,我们先不考虑,我们关心的是,如果有这个service存在于网络上,我们的问题就解决了?
答案是肯定的。如果有这个service,我们还要数据库干什么?
ok,我的解决方案就出来了。
一个用户的动态信息部分,最多几十个bytes就解决了,我们预设64bytes,我们预设一个server专门存储用户的动态信息,100w吧,服务100w用户。
64*100w=64M
现在的计算机内存多少?家用机普遍1G。
这个表,放到内存里面绰绰有余。
ok,我现在写一个服务进程,叫ActiveUserInfoService,在,比如说60000端口监听,专门提供这个服务,在原有Server上做个转向,即查询动态信息的所有信令报文,我全部转到这个服务进程ActiveUserInfoService上处理,自己不再负责查询。
客户端上线,丢一个Add信令,下线,丢一个Del,查询,丢一个RequestActiveInfo(List* pUserList)信令过去。
这个Service就处理这三个信令就好了。
然后我们来讨论,大家发现,当所有信息都在内存的时候,我们的方法就太多了,什么平衡二叉树,哈希map==,有太多的方法来优化这个查询速度。
而且,甚至我们可以把Add和Del信令做成异步的,就是收到后,打入队列,立即返回,避免MasterServer发生阻塞。
我们只需要建立这样一个小小的Service,前文所述的所有的数据库优化,其实全都不必要了。
这就是我想说的重点:当一个优化走到极致,我们应该跳出思维框框,开始从架构上、系统上想办法,而更进一步,我们每次面临一个优化需求的时候,我们甚至都要想,能不能不碰数据库,有没有其他办法解决。可不可以通过服务器集群的方式,自然解决。
数据库是功能层,提供数据存储和提取的功能,在其中做优化,很难做到针对性优化,只能做普适性优化,效果很差,如果我们到业务层来,针对单笔业务,做特定优化,其实路子会宽很多。
呵呵,一家之言哈,欢迎拍砖。
本文转自 tonyxiaohome 51CTO博客,原文链接:http://blog.51cto.com/tonyxiaohome/198492 ,如需转载请自行联系原作者