高性能
读写分离
将访问压力分散到集群中的多个节点
解决复制延迟
- 写操作侯的读操作指定发给主库
- 读从库失败后再读一次主库
- 关键业务全部读主库
分配机制
- 程序侧代码封装
- 中间件封装
分库分表
既分散访问压力,也分散存储压力
业务分库
按业务模块将数据分散到不同的数据库服务器
问题
- 关联查询问题
- 事物问题
- 成本问题
纬度分表
- 垂直分表
- 大字段拆分
- 水平分表
- 行数特别大的表
问题
- 路由问题
- 确定数据在哪个子表
- 范围路由
- Hash路由
- 关联查询
- 求和查询
- 排序查询
NoSQL
关系数据库缺点
- 存储的都是行记录,无法存储数据结构
- schema扩展不方便
- 全文搜索功能比较弱
NoSQL数据库类型
- K-V存储
- 文档数据库
- 列式数据库
- 全文搜索引擎
缓存
设计要点
- 缓存穿透
- 数据不存在,缓存中没有每次都要去数据库查询。解决办法缓存默认值
- 缓存数据生成耗费大量时间,解决办法提前缓存
- 缓存雪崩
- 缓存失效(过期)引起系统性能急剧下降,多个请求同时生成新的缓存
- 解决办法
- 更新锁,使用分布式锁,获取锁的则更新,其他请求等待锁释放后重新读取缓存,或者返回空值、默认值
- 后台更新,由后台线程更新缓存,而不是业务线程,缓存设置永久有效
- 缓存热点
- 热点数据集中访问一个缓存节点,解决办法复制多份缓存副本
单服务器高性能
高性能架构设计
- 尽量提示单服务器性能,发挥到极致
- 单服务器无法支撑时设计集群方案
架构设计决定了系统性能的上限,实现细节决定了系统性能的下限
并发模型设计点
- 服务器如何管理连接
- 服务器如何处理请求
PPC
Process Per Connection
每次有新的连接就新建一个进程专门处理,其中有可通过prefork提前创建进程
TPC
Thread Per Connection
使用线程处理每一个请求
连接数量、请求数量
- 海量连接,海量请求:抢购、双十一
- 海量连接,常量请求:门户网站
- 常量连接,海量请求:中间件
- 常量连接,常量请求:内部系统、管理系统
Reactor
I/O多路复用+线程池;非阻塞同步网络模型,read、send需要用户线程同步操作
- 当多条连接共用一个阻塞对象,进程只需在一个阻塞对象上等待
- 当某条连接有新的数据可以处理时,操作系统通知进程,进程从阻塞返回
实现方案
- 单Reactor单线程
- 单Reactor多线程
- 多Reactor多线程
Proactor
Reactor中同步I/O操作改为异步实现
高性能负载均衡
任务分配器==负载均衡器
分类
- DNS负载均衡
- 同一域名返回不同的IP地址
- 硬件负载均衡
- 软件10万级并发、硬件100万以上
- 软件负载均衡
- Nginx
- 7层负载均衡,支持HTTP,E-mail协议
- LVS
- 4层负载均衡,和协议无关,几乎所以应用都可以做
- Nginx
典型案例
- DNS负载机房IP
- 硬件负载本地集群
- 软件负载具体服务器
算法
分类
- 任务平分类
- 负载均衡类
- 性能最优类
- Hash类
具体算法
- 轮询
- 加权轮询
- 负载最低优先
- 性能最优类
- 源地址Hash
- ID Hash
CAP理论
- 一致性(Consistence)
- 可用性(Availability)
- 分区容错性(Partition Tolerance)
- 根据系统内数据不同场景,选择CP、AP
- 单个用户余额、单个商品库存强一致的数据在技术上无法做到分布式场景下的完美一致,只能单点写入,其他节点做备份,无法做到分布式场景下多点写入,系统整体可以应用分布式架构
- 既要考虑分区发生时选择CP还是AP,也要考虑分区没有发生时如何保证CA
- BASE理论是对CAP中AP的延伸补充
- 完美的CP场景是不存在的(几毫秒延迟),CP实际也是实现最终一致性
分布式系统设计初衷
- 横向扩展
- 解决单点瓶颈问题,保证高并发下的可用性
- 高可用性
- 解决单点故障问题,保证部分节点故障时的可用性尽量降低系统复杂度
FMEA故障模式与影响分析
FMEA分析方法
- 给出初始的架构设计图
- 假设架构中某个部件发生故障
- 分析此故障对系统功能造成的影响
- 根据分析结果,判断架构是否需要进件优化
分析表格
- 功能点
- 故障模式
- 故障影响
- 严重程度
- 故障原因
- 故障概率
- 风险程度
- 已有措施
- 规避措施
- 解决措施
- 后续规划