千尋的架構設計(一)

Posted on March 8, 2012 -

千尋(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的功能,在某些功能上,這是非常方便的。

關於數據庫的具體設計和其他內容,請見後續文章。