设计一个在 AWS 上管理千万级别的用户系统
设计一个在 AWS 上管理千万级别的用户系统
1. 概述用例和约束,计算
假设这题有以下用例:
用户发出读取或写入请求
- 服务进行处理,存储用户数据,然后返回结果
服务需要从负载少量用户发展到千万用户
- 思考处理大量用户和请求时,架构设计和一般的扩展模式
服务高可用
状态假设:
用户流量分布不均匀
需要关系型数据
从1个用户扩展到1千万用户
每月 10 亿次写请求
每月 1000 亿次读请求
读写比例 100 : 1
每次写请求存储 1kb 内容
计算:
每月 1T 内容存储:每次写 1kb * 10亿次写 = 1T,3 年就是 36 T
平均每秒 400 次写请求
平均每秒 40000 次读请求
1 | 1G ≈ 1000M ≈ 1000000K(100万k) ≈ 1000000000b(10亿byte) |
2. 抽象设计
3. 核心组件设计
对于 1 - 2 个用户,只需要简单得设计即可:
一台 Web Server
必要时垂直扩容
监控以确定瓶颈
在单个机器里,部署服务,部署 MySQL 数据库存放用户数据。
当性能不足时 (cpu, memory等) ,垂直扩容,换更好的机器。
将服务器分配一个公共静态 IP。
添加 DNS 域名服务,指向服务器的 IP。
安全方面,服务器仅打开必要的端口,比如 http 请求的 80 端口,https 请求的 443 端口,以及 ssh 白名单用户的 22 端口。
4. 扩展服务设计
User+
用户增多,单机的负载增加。用户静态资源占用过多磁盘,MySQL 也占用越来越多的内存和CPU资源。
因为垂直扩展已到极限,换再好的硬件机器也无法对 MySQL 数据库和 Web 服务器进行独立扩展。
目标与对策:
减轻单机负载,并允许独立扩容。
考虑 S3 对象存储,单独保存 JS, CSS, Html, Images, Videos 等静态资源
将 Mysql 单独部署,使用 RDS 服务来管理 Mysql 实例
User++
用户再次增多,高峰时段的单个Web服务器瓶颈,导致响应缓慢,在某些情况下还会导致停机。希望朝着更高的可用性和更低的延时性发展。
目标与对策:
使用水平扩容应对不断增加的负载,解决单点故障
添加 Load Balancer 负载均衡器,例如亚马逊的 ELB 或 HAProxy
Web Server 多服务多地域部署
Mysql 采用多实例部署,主从模式。
将 Web Server 与 Application Server 分开
两层分别配置
Web Server 可以作为一个反向代理
比如可以增加 Application Server 专门负责读请求,其他的负责写请求
将静态(和一些动态)内容移动到 CDN 上,减少加载和延时
User+++
用户仍在增多,而且的读取量很大(读写比例100:1),我们的数据库性能不佳。需要提高读请求的性能。
目标与对策:
减少负载和延迟
将热门数据缓存到 Elasticache 之内的内存中 (首先可尝试先开始 MySQL 缓存,观察是否足以缓解瓶颈),session 数据的缓存
Web Server 设成无状态,允许自动缩放。
从内存顺序读取 1MB大约需要 250 微秒,而从 SSD 读取则需要 4 倍,而从磁盘读取则需要 80 倍的时间
添加 MySQL 读库,减少写主库上的负载
添加更多Web服务器和应用服务器以提高响应速度
User++++
用户在一天的某段时间比如工作时间会达到峰值,而其他时间流量会大幅下降,希望尽可能多的 DevOps 自动化以实现自动缩放和常规操作。
目标与对策:
根据流量自动扩展机器
跟上流量高峰
通过关闭未使用的实例来降低成本
自动化DevOps
继续监控指标以解决瓶颈
主机级别-查看单个EC2实例
聚合级别-查看负载均衡器统计信息
日志分析-CloudWatch,CloudTrail,Loggly,Splunk,Sumo
外部站点性能-Pingdom或New Relic
错误报告-sentry
User+++++
用户进一步增长,持续监测并做一些优化
如果 MySQL 数据库开始变得太大,考虑仅在数据库中存储有限时间段的数据,其余存储在 Redshift 等数据仓库中
每秒平均 40000 个读取请求,通过扩展内存缓存来解决热门数据的读取流量,这对于分布不均的流量和流量峰值也很有用
每秒 400 次平均写入,对于单个主从模式写请求而言,可能很难,需要其他扩展技术,比如queue
为了进一步解决高读写请求,我们还应该考虑将适当的数据移动到 NoSQL 数据库(例如 DynamoDB)
5. 进一步讨论
取决于问题领域和剩余时间。
SQL扩展模式 (读写分离,分库分表,分片,sql 调优)
NoSql (kv 存储,document 存储,宽表存储,图形数据库)
缓存 (client,cdn,web server,database)
消息队列,微服务,服务发现
其他方面的权衡取舍
6. 其他
持续对系统进行基准测试和监控,发现瓶颈,并解决它,服务扩展时一个持续的过程。
以上。
Title: 设计一个在 AWS 上管理千万级别的用户系统
Author: mjd507
Date: 2019-12-29
Last Update: 2024-01-27
Blog Link: https://mjd507.github.io/2019/12/29/system-design-3/
Copyright Declaration: This station is mainly used to sort out incomprehensible knowledge. I have not fully mastered most of the content. Please refer carefully.