设计流程总结
-
定义系统需求
- 解决什么问题?
- 要实现的功能需求
- 要实现的非功能需求
- 可靠性 reliable
- 数据不会丢失
- 可用性 available
- 不会因某个硬件故障而停止服务
- 可扩展性 scalable
- 随着用户规模增长,可以轻松扩展集群
- 低延时 latency
- 高峰期也能快速处理并返回请求
- 高吞吐 Throughput
- 能承受较高流量请求而不会变慢或崩溃
- 一致性 consistency
- 是否需要严格一致性(会丧失可用性),还是仅需要最终一致性
- 安全 security
- 是否需要权限校验
- 可靠性 reliable
- 给什么人用?
- 大概数据
- 日活量?
- 读写比?
- 数据量?
- 用来计算所需要的
- QPS(读和写)
- 高峰期要用平均值乘以3倍
- 磁盘容量
- 带宽
- QPS(读和写)
- 大概数据
- 解决什么问题?
-
开始设计
- 接口函数
- 给各个功能对应的函数命名、以及所需参数
- 存储结构
- 用户表
- userId(主键)、name、avatar、createTime、lastLogin
- 资源表
- resourceId(主键)、title、description、ctime、mtime
- 用户表
- 总体架构
- 用户侧 client
- 负载均衡 load balance
- 服务侧 server
- 队列 queue
- 服务中心 configuration center
- 缓存 cache
- 数据库 database
- 接口函数
-
实现可靠性、可用性和可扩展性
- 主从复制结构
- 半同步复制
- 故障切换
- 读写分离
- 哈希分区
- 按资源Id进行一致性哈希,分配到不同的节点分片中
- 不建议按用户Id进行,因为会存在热点现象,难以平衡负载
- 唯一主键生成服务
- 自增键生成服务
- 按资源Id进行一致性哈希,分配到不同的节点分片中
- 主从复制结构
-
实现低延时和高吞吐
- 引入缓存
- 参考28法则,把20%的高频数据放到缓存
- redis、memcached
- 满容量后的过期策略用LRU
- 考虑分布式
- 考虑刷新策略
- 参考28法则,把20%的高频数据放到缓存
- 引入队列
- 异步处理,提高吞吐
- 缓冲作用,充分利用服务器资源
- 引入任务
- 进行解耦
- 引入频率限制
- 检测单个用户的单位时间请求量,不得超过某个值,防止占用过多资源
- 引入缓存
-
实现一致性
- 是否需要事务级的ACID支持及多表联查
- 需要,就用传统数据库 postgreSQL
- 不需要,就用宽列式数据库 Cassandra
- 是否需要线性化
- 需要,采用加锁处理,或者选择可串行化的隔离级别
- 不需要,只需要实现最终一致性即可
- 是否需要事务级的ACID支持及多表联查
-
分析系统瓶颈
- 单点故障
- 缓存丢失与击穿
- 并发操作
-
考虑监控
- 入口处负载的高峰期流量
- 集群内各节点运行情况、各自处理的请求数、成功率
- 缓存的命中率