一、数据库扩展
使用django ORM+postgresql,因为PostGIS,选择了postgresql。(PostGIS在对象关系型数据库PostgreSQL上增加了存储管理空间数据的能力,相当于Oracle的spatial部分)并且数据库部署在独立服务器上。
因为EC2机器的最大内存为68G,随着照片存储量的增加,进行垂直分区(vertical partitioning);使用django db routers,做垂直分区变得很容易;如下:照片则映射到photodb
def db_for_read(self, model): if app_label == 'photos': return 'photodb'
当照片存储量大于60G的时候,采用水平分区(也就是所谓的“分片”sharding)
sharding带来的问题:
- 数据的检索,hard to know what your primary access patterns will be w/out any usage in most cases, user ID
- 当有分片变得太大的时候怎么办?
基于范围的分片策略(就像MongoDB那样)
3、性能有下降趋势,尤其在EC2上,原因:disk IO,解决方法:预先切分(pre-split),即预先切分上千个逻辑切片,将它们映射到较少的物理分区节点中去。
关于相关内容,更详细的可以参看这里。
二、选择合适工具
进行缓存/反规范化数据设计
用户上传图片时:
- 用户上传带有标题信息和地理位置信息(可选)的照片
- 同步写到这个用户对应的数据库(分片)中
进行队列化处理
- 如果带有地理位置信息,通过异步的POST请求,将这个图片的信息送到Solr(Instagram 用于geo-search API的全文检索服务器)。
- 跟随者的信息分发(follower delivery),即告诉我的follower ,我发布了新的照片。如何来实现的呢?每个用户都有一个follower 列表,新照片上传时会把照片ID发送给列表中的每一个用户,用Redis 来处理这一业务简直太棒了,快速插入,快速子集化(rapid subsets)
- when time to render a feed,we take small # of IDs, go look up info in memcached(当需要生成feed的时候,我们通过ID+#的格式,直接在memcached中查找信息)
Redis适合什么样的场景?
- 数据结构相对有限
- 对频繁GET的地方,对复杂对象进行缓存