千寻的架构设计(一)

发布于2012年3月8日 -

千寻(https://github.com/dangfan/Chihiro)是本学期软件工程课大作业的项目名称,这是一个Kik类的通讯工具,此外,还加入了基于地理位置信息的元素。

对于一个这样的应用,性能是必须考虑的,一方面,我们希望并发数足够高(例如10,000 req/s),另一方面,我们也希望在传输的过程中,数据量尽可能的小,以节省用户的流量,并加快消息收发的速度。

考虑到这两个因素,服务器端的架构和通讯方式就显得非常重要。经过一些初步的调研和测试,我们在这个项目中使用如下的通讯解决方案:

  • 使用HTTP协议作为通讯的基础。虽然相比直接使用TCP协议,HTTP协议稍显臃肿,但考虑到开发、调试等因素,HTTP协议还是很有优势的。事实上,微信也是使用HTTP协议通信的。
  • 使用WebSocket作为实际的通讯协议。与轮询相比,WebSocket极大的降低了数据量和延迟,此外全双工的连接也给开发带来了巨大的便利。

千寻需要存储的数据可以分两类:

  1. 需要长期保存的数据,包括用户的信息、兴趣爱好、好友列表、地理位置等。
  2. 不需要长期保存的数据,主要是聊天的数据(包括群聊和点对点聊天消息)、好友请求等。

这两类数据最重要的区别就是是否需要长期保存。对于第二类数据,我们只需要保存到用户成功接收到消息即可,不需要在服务器做备份。此外,第二类数据如果存在磁盘中,然后再读取广播或单播,这在IO性能上是不可接受的。因此,针对这两类不同的数据,我们需要选择恰当的方法进行存储。

对于需要长期保存的数据,我们使用MongoDB来存储。使用MongoDB的理由如下:

  • 可以对地理位置信息建立索引,提供API查找最近的若干点。
  • MongoDB是schema-less的文档型数据库,可以很容易、很高效的获取记录相关的信息。例如,我们可以在用户下面直接保存他的好友列表、兴趣爱好列表等。
  • MongoDB的IO性能相对较高。

而对于不需要长期保存的数据,我们则使用Redis来存储。使用Redis的理由如下:

  • Redis是基于内存的Key-Value存储,性能不亚于Memcached。
  • Redis支持高效的有序列表、无序集合等数据结构,比Memcached更灵活方便。
  • Redis还提供pub/sub的功能,在某些功能上,这是非常方便的。

关于数据库的具体设计和其他内容,请见后续文章。