面试题|设计instagram

目录

  • 题目
    • Use Cases
  • 约束
  • High Level
  • DB Design
    • DB schema
    • 容量预估
  • 详细设计
  • 扩展
    • 可靠性
    • 高并发
    • 扩展性
  • 信息流设计

题目

用户可以上传照片,分享照片;关注其他人,亦可以看到自己的和好友的top照片;

Use Cases

功能性

  1. 支持用户上传/下载/查看 照片
  2. 根据名称搜索照片
  3. 用户关注他人
  4. 生成和展示信息流,包含所有关注的人的top照片

非功能性
5. 高可用
6. 低时延:信息流产生时延 < 200ms
7. AP系统:保可用性,特殊情况用户一段时间看不到照片也是OK的
8. 高可靠,上传的照片不能丢失

out of scope

  • 为照片添加tag,根据tag搜索,评论,查看粉丝

约束

- ***首先和面试官声明该系统的几个设计关键点
    - 用户会上传大量照片,存储系统的管理是关键
    - 查看照片需要低时延
    - 数据100%不丢失***
  • read/write 100:1 DAU:1M
  • 每天1M新照片,QPS:10
  • 500M用户,日活1M
  • 一个照片10M,10TB/Day,300TB/month,18PB/5 years
  • 元数据:一条记录 = title(1KB) + created_at(10B) + details(4KB); 一个月30M * 5KB = 150GB(不太准确,需要在schema设计后计算)

High Level

  • client upload/download/search/view service + core image service + image storage service + meta data service

DB Design

  • 数量多10B 条记录

  • 单条记录小 5KB

  • 表关联不是很强,用户表 + 图片信息表 + 用户关系表

  • 读多,前缀搜索/后缀搜索:根据名称搜索

  • 没有事务性要求,扩展性要求高,选择NOSQL

    • key=image_id value=object(name, title, size,…)
  • 照片可以存储在分布式文件存储,HDFS / S3

  • a wide-column datastore可以存储list作为value,适合保存一个user拥有的imageId,一个user拥有的followers

DB schema

  • table:image_info + user + user_relation

image_info:table
PK:image_id:varchar(32) int
name image_path :varchar(256)
title:varchar(2048)
size:int
user_id:int
created_at:datetime
update_at:datetime
is_delete:int (NOSQL延迟删除,所以不需要该字段)

user:table
PK:user_id:int
name:varchar(256 20)
created_at:datetime
last_login:datetime

user_relation:table
PK:from_id + to_id
from_id: int
to_id: int
is_follow:int
created_at:datetime
update_at: datetime

message:table
PK: message_id:int
user_id:int
image_id:int
title:varchar(2048)
created_at:datetime

top_message:table
PK:user_id:int
update_at:datetime
top_message:text

容量预估

- User:int和datetime都是4B,4 + 20 + 4 + 4 = 32 B;500M * 32 B ~= 16 G
- image:4 + 256 + 4 + 4 + 4 = 272 B;1M * 272 B = 0.27 G per day
- userFollow:500M * 500 followers * 12B = 3 TB

详细设计

读写服务分离

  • 背景:写过程较慢,web server连接数有上限,会阻塞读请求;读写分离也便于分开优化和扩容;
  • upload服务,请求量较低QPS 10,写image storage service(S3)和metadata服务
  • download服务,先读CDN,miss后再读metadata服务,再读S3服务
  • 查看服务,QPS 10000,先读浏览器cache,再读CDN,再读metadata服务,再读S3服务
  • 搜索服务,读cache,然后再从metadata服务,获取搜索结果

扩展

可靠性

  • storage服务,3副本
  • metadata 主从架构
  • download和upload service也是多个实例在跑

高并发

  • 核心服务前LB,rr策略
  • 读请求增加过期cache
    • 用户来自世界各地,需要将内容push到离用户更近的cache服务器,例如使用CDN
    • 为metadata服务增加cache服务,缓存热点的数据库rows,memcache;淘汰策略LRU
    • 问题:如何更高效地缓存;缓存20%的真实数据和元数据

扩展性

  • 存储服务数据sharing,根据image_id来哈希到不同的存储节点;讨论两种sharding的方案
    • 1.根据user_id,一个user的photo都保存在一个shard中,一个shard=1TB,假定一共10个shard,每次查找时user_id % 10找到shard;
    • 1.问题:1)热点user 2)user数据过大 3)用户数据量不同,存储分布不均匀 4)用户所有数据都不可用(某个shard down)和高时延(某个shard负载高)
    • 2.根据image id,先生成image id,然后image id % 10 ,分布会均匀;每次上传image,都索引到shard,然后写数据;读取时也是根据imag id做索引;解决了1)2)3)4)问题
      1. 问题:1)热点image 2)如何扩展?
    • 3 答案:1)加缓存??? 2)维护单独的config服务,维护logic partion和physical 数据库服务的map;如果一个数据库满时,我们可以移动一些partition到其他数据库服务。

信息流设计

  • push:每次发布,都将消息推送到所有的set,对于每一个from_id 将消息id添加到队首,如果队列消息超过10个,淘汰掉最旧的消息;
  • 问题:明星人物push有性能问题;写入数据过多;
  • pull: 获取用户信息流时,主动拉取set的消息,然后根据时间排序,选取最新的前10个照片;
  • 问题:如果关注的人过多,时延可能超过200ms;
  • 混合模式:明星人物不push,其他人物均push;

你可能感兴趣的:(系统设计)