Skip to content

Latest commit

 

History

History
79 lines (52 loc) · 3.56 KB

SystemDesign.md

File metadata and controls

79 lines (52 loc) · 3.56 KB

系统设计

答题套路

第一步:描述使用场景,约束和假设

把所有需要的东西聚集在一起,审视问题。不停的提问,以至于我们可以明确使用场景和约束。讨论假设。

  • 谁会使用它?
  • 他们会怎样使用它?
  • 有多少用户?
  • 系统的作用是什么?
  • 系统的输入输出分别是什么?
  • 我们希望处理多少数据?
  • 我们希望每秒钟处理多少请求?
  • 我们希望的读写比率?

第二步:创造一个高层级的设计

使用所有重要的组件来描绘出一个高层级的设计。

  • 画出主要的组件和连接
  • 证明你的想法

第三步:设计核心组件

对每一个核心组件进行详细深入的分析。举例来说,如果你被问到设计一个 url 缩写服务,开始讨论:

  • 生成并储存一个完整 url 的 hash
    • MD5 和 Base62
    • Hash 碰撞
    • SQL 还是 NoSQL
    • 数据库模型
  • 将一个 hashed url 翻译成完整的 url
    • 数据库查找
  • API 和面向对象设计

第四步:扩展设计

确认和处理瓶颈以及一些限制。

  • 负载均衡
  • 水平扩展
  • 缓存
  • 数据库分片

题目示例:高并发抢红包

总共有10亿个红包,在某个时间一起来抢红包,如何设计。

分析

主要考察的是如何设计高并发系统,但实际上存在一定变通处理方式,不一定全在技术上。

通常在考虑系统QPS时,应当按业务上的极限QPS作为系统必须承担的QPS设计,比如10亿个红包,因为用户量巨大,极限QPS是可能是10亿。

但是一般来说几万QPS已经是比较高的并发了,就需要比较大的集群和高并发架构来处理了,所以不可能真正实现10亿的并发架构,而是通过一些变通的方法来处理,比如在业务上做一些处理规避掉部分流量。

但尽可能地需要实现高并发架构,思路是将大部分流量拦截在系统承载能力低的模块之前

回答

业务上适当规避

在相应法律法规、规章制度、活动说明、用户体验允许的情况下,可以做以下处理。

  1. 根据某些规则对部分用户直接返回没抢到。比如有些用户曾经被系统识别为恶意用户、垃圾用户、僵尸用户,直接告诉用户已经抢完。
  2. 分散不同客户端打开活动入口的时间。比如将1秒内的10亿流量分散到10秒,那么平均每秒只有1亿了。
  3. 增加客户端入口点击门槛。比如需要手机摇一摇、画一个图案才能触发抢红包的接口。

技术上硬核抗压

网关是会接触实打实10亿流量的地方,也是拦截掉最多无效流量的地方,同理,缓存也是。

  1. 限流策略。比如在压力测试中我们测到系统1亿QPS达到了极限,那么超过的部分直接返回已经抢完,通过Nginx的lua脚本可以查redis看到QPS数据从而可以动态调节。
  2. 作弊拦截。通过对UA、IP规则直接将抢红包的作弊流量拦截掉。
  3. 异步削峰。对Redis中的红包预减数量,立即返回抢红包成功请用户等待,然后把发送消息发给消息队列,进行流量的第二次削峰,让后台服务慢慢处理。
  4. 服务逻辑。比如业务逻辑是使用事务控制对数据库的创建红包记录,减红包数量的操作,那么创建操作要放到减数量操作之前,从而避免减数量update的行锁持有时间。
  5. 机器配置。当然是服务器机器配置约高越好,数据库配置越猛越好,高并发抢红包主要是CPU的负载较高,要选择偏向CPU性能的机器。