项目总结-美食类社交app的架构设计

很早之前就想写这一篇东西,或者说是自己的总结吧。项目虽然融资失败了,作为技术者来讲,心里的失落是难免的,不过在项目的这段时间,技术架构上也积累了不少东西,有必要对自己一个交代。

先来讲讲这个项目整体上用到的一些技术和框架:

1)使用Ruby on Rails开发,rails基于3.2版本,兼容性上升级到4也是无压力,ruby使用2.0以上版本。

2)数据库使用mongodb,由于用到了aggregate,需要2.4以上版本。
因为mongodb对于地理位置的优势,这是一个不错的技术选型。

3)数据库还使用了redis,用来持久化一些计数或者关联比较弱的数据,
例如,某一道菜喜欢的人数,某一个用户follow的用户的动态,
这些数据是可以延迟更新或者允许丢失一部分也不会造成脏数据。

另外redis还用在缓存一些数据,这部分数据不能放在memcache中,因为是不允许丢失的,
例如某一道菜所有喜欢它的用户的id,已数组的形式保存在redis中。

最后redis还用在了队列系统中。

4)数据库还使用了memcache,用来做缓存一些简单的数据和页面,例如用户的个人主页,用户的积分页等等。

5)使用了sidekiq,用来处理异步处理耗时比较大的请求,例如发推送,切割图片,同步相关数据等等。

6)使用了solr,用来检索门店,
10万级别的门店数据,如果用mongodb,即使加索引,
对于一些模糊匹配还是会非常的慢,
全文检索可以解决速度的问题。(幸好solr也支持地理位置检索)

在服务器架构上,两台应用服务器负载均衡,一台服务器做nginx反向代理,三台mongodb使用replica set模式,两台redis,两台memcache,架构图如下:(比较简单)

关于follow和followers的问题

这个我想是每个做社交都不可避免的。随之而来的问题是,不一定像twitter或者微博那么的数据量大,但是核心会员有个一两万粉丝还是肯定的,这一两万粉丝的动态推送估计就够呛了。

我们知道这里无外乎两种模型,“推”和“拉”,推的问题是每次都需要推很多数据,就算用后台队列也不一定可以很快的到达,并且非常占用系统资源,如果用户不去看,推都推了,更是资源的浪费。拉的问题是每次用户访问的时候去拉数据,资源不会浪费,可是对于关注的多的用户,那会是灾难性的。

我这边的做法是“推”和“拉”结合起来,系统对于每个用户会做一次区分,当发现这个用户关注的人数在一定比较少的范围,例如100个以内,或者用户自从注册以后很长一段时间都没有访问,例如一个月都没有登录过,那么我就认为这个用户是“死用户”,对于死用户,我就采用拉的模式,因为就算他登录,因为数据量不大,也不会有太大的问题。相对于那些活跃用户,我用推模型,因为对于一个网站来讲,确实只有20%的属于活跃用户。

当然,在这个基础上,还可以更加深入下去,例如增加缓存,或者更好的来判断用户的权重,不过因为优化后没有遇到更大的问题,就先这样了,毕竟过度优化是万恶之源。