《从零开始学架构》笔记——第二部分:高性能和高可用架构模式
第四章 存储高性能
关系数据库
-
读写分离(减轻访问压力)
基本原理:将数据库读写操作分散到不同节点上,减小单个数据库的访问压力,提高访问效率。
基本实现:
- 数据库服务器搭建主从集群,一主一从或者一主多从。
- 数据库主机负责读写操作,从机负责读操作。
- 数据库主机通过复制将数据同步到从机。
- 业务服务器将读写发送到主机,将读发送到从机。
事务问题:一致性。
【问题】
如何保证主机和从机的数据一致???主从复制的延迟性问题。
- 二次读取,读完从机再读一次主机
- 关键业务指向主机,非关键业务指向从机
-
分库分表(减轻存储压力)
分库
将业务模块分到不同数据库服务器里。比如电商项目中用户,商品,订单就可以防在三台不同的服务器上。
【问题】
-
join操作问题
无法实现关联查询
-
事务问题
数据需要保持一致。比如订单加1商品数量就会减1。(延迟性问题)
-
成本
分表
单表数据拆分有水平拆分和垂直拆分两种。
拆分后可以放在同一数据库中,也可以放在不同数据库中。
-
垂直分表
将表中不常用的列拆分出去。会带来表数量增加的复杂性。但能显著提高查询效率。
-
水平分表
水平分表适合表行数特别大的表。
-
水平分表的问题
-
路由:根据什么条件拆分表
-
范围路由:根据有序的数据列作为路由拆分条件,比如1-999999,1000000-1999999.
建议段大小在100万到2000万之间
优缺点:分段大小选取具有复杂性;但可以随着数据增加平滑扩展新的表
-
Hash路由
-
配置路由
-
-
join操作需要合并结果
-
order by 操作无法在数据库中进行,只能通过业务代码或者数据库中间件分别查询,然后汇总排序
-
-
-
NoSQL
NoSQL分类:
- K-V存储:Redis
- 文档数据库:MongoDB
- 列式数据库:HBase
- 全文搜索引擎:ElasticSearch
缓存
基本原理:将可能会重用的数据放在内存中,一次生成,多次使用。
【一个明星发一条微博,执行一个insert,然后n多个select】
-
缓存穿透
缓存没有发挥作用,业务系统向缓存中读取,但并没有数据。
问题:
- 存储数据不存在
- 缓存需要时间较长
-
缓存雪崩
当缓存失效后系统性能急剧下降。很多请求访问数据库,同时生成缓存。
解决方案:
- 更新锁,只能有一个线程生成缓存。(分布式锁)
- 后台更新。不用业务线程更新,而是用后台线程专门更新。
-
缓存热点
复制多份缓存,创建缓存服务器集群,将请求分发到不同服务器上。
【比如新浪微博上粉丝超过100w的明星发的微博,生成100份缓存(当然需要100台服务器)】
第五章 计算高性能
从物理层面上来说:
- 尽量提升单服务器的性能,将资源发挥到极致
- 单服务器达到性能瓶颈,设计服务器集群方案
单服务器高性能
集群高性能
负载均衡代替前面的任务分配。
负载均衡分类
- DNS负载均衡(实现地理级别的负载均衡)
- 硬件负载均衡(类似路由交换机)100w以上的并发,就是贵,好一点的就是一台宝马了。
- 软件负载均衡(Nginx&&LVS)
负载均衡算法
- 轮询
- 加权轮询
- 负载最低优先
- Hash类(根据关键信息进行Hash运算,将相同Hash值的请求分发到同一台服务器山)
第六章 分布式系统设计理论CAP
对于分布式计算系统,只能满足一致性,可用性,分区容错性三个中的两个。
三进二
-
一致性
所有节点在同一时刻都能看到相同的数据。(比如MySQL集群主从数据一致性)
-
可用性
非故障节点在合理时间返回合理响应。(不能是错误或者超时的响应)
-
分区容错性
当出现网络分区后(网络故障,丢包网络中断),系统可以继续运行。
CAP细节
CAP粒度是数据,而不是系统
比如用户账号数据选择CP,而其他信息选择AP
正常情况下,可以同时满足CA
当发生了分区情况,也就是网络故障,才会存在CA的选择,在网络正常的情况下,CA可以同时满足。
ACID:关于数据库事务完整性的理论
- 原子性:单个事务要么都完成,要么都失败(比如银行转账,一个减,一个加,必须同步)
- 一致性:并发请求下数据保持一致
- 隔离性:防止多个事务并发交叉执行导致的数据不一致问题。(悲观锁和乐观锁实现)
- 持久性:事务结束后,对数据的修改就是永久的,即使系统故障也不会丢失。
BASE:如果无法达到强一致性,那就最终一致性
-
Basically Availible 基本可用
分布式系统故障时,保证核心功能可用(保持登录可用,损失注册)
-
Soft Status 软状态
数据不一致
-
Eventually Consistency 最终一致性
BASE理论是AP方案的延申。
第七章 存储高可用
主备复制
- 主机存储数据,将数据复制给备机
- 备机不提供读写服务
- 主机发生故障需要人工干预将备机升为主机
主从复制
- 主机存储数据,将数据复制给备机
- 备机提供读服务
- 主机故障可以进行读业务,发挥了备机的性能
- 主从复制比主备复制复杂,主要体现在客户端需要识别主从关系
- 适用写少读多的系统(论坛,新闻网站)
主备倒换和主从倒换
主备复制和主从复制的共性问题是主机故障,无法进行写操作。
主备倒换和主从倒换在原有基础上增加角色倒换的功能。
-
互连式:主备机间建立状态传递的通道。
通道可以是网络连接,也可以是串口连接。
-
中介式
主备机不进行直接连接,而是通过中介传递信息。(需要中介高可用)
Zookeeper仲裁节点设置节点级别。
-
模拟式
将备机模拟成客户端,模拟读写操作。
主主复制
- 两台主机都有数据,通过复制通道同步
- 一致性问题很大
- 适合临时性,可丢失,可覆盖的场景
数据分散集群
数据分散集群指多个服务器组成一个集群,每台服务器都会存储一部分数据,同时,每台服务器会备份一部分数据。(分库分表)
分布式事务算法:保持一致性
2PC 二阶段提交
- 第一阶段:协调者向所有参与者发送请求(投票阶段)(任一参与者否定都可终止提交)
- 第二阶段:参与者全部通过请求,协调者提交请求。
问题:
- 同步阻塞:协调者和参与者互相等待
- 协调者单点故障
3PC 三阶段提交
- 第一阶段:协调者向所有参与者发送请求(投票阶段),参与者有否定则事务中止,在超时时间内收到所有yes则进入第二阶段。
- 第二阶段:协调者发送预提交给参与者,参与者收到信息执行事务操作,返回ACK消息。
- 第三阶段:协调者收到所有的ACK消息后发送执行提交。参与者执行提交后返回已提交消息给协调者。
分布式一致性算法
-
Paxos(纯理论)
特别复杂
- 多数一致性
- 读操作也会将算法完全执行一遍
-
Raft
- Leader选举
- 日志复制
- 安全保证
-
ZAB
Zookeeper采用的分布式一致性算法
第八章 计算高可用
当部分硬件损坏时,计算任务可以正常运行。
基本思想:通过增加更多的服务器达到计算高可用。
主备
- 主机执行所有的计算任务
-
当主机损坏且无法恢复时,需要人工将备机升至主机,并且增加新的备机
-
冷备:程序包和配置文件准备好,启动服务器,但业务不启动;温备:业务已启动,但不对外提供服务
-
适用内部管理系统,后台管理系统的等使用人数不多的情况
主从
- 主机执行部分任务,备机执行部分任务
- 主机故障,任务分发不变,即使主机无法正常运作
- 需要人工将备机升为主机,并添加新的备机
对称集群(负载均衡集群)
- 正常情况下,任务分配器将任务分配给不同的主机
- 当某台服务器故障后,任务分配器将跳过该台服务器
- 当故障服务器恢复后,重新分配任务
非对称集群
Master-Slave
- 集群通过某种方式区分服务器角色,选出Master服务器
-
当Master服务器故障后,推选出新的Master服务器
-
Zookeeper通过ZAB协议选取Master
第九章 业务高可用
异地多活
机房断电,机房火灾,城市地震…(但是鸡蛋也不是那么容易碎的)(不要把鸡蛋放在一个篮子里)
- 同城异区
- 跨城异地
- 跨国异地
异地多活设计技巧
- 保证核心业务的异地多活
- 核心数据最终一致(异地多活不可能很快)
- 采用多种手段同步数据
- 消息队列
- 二次读取
- 回源读取等等
- 保证大部分地区的异地多活(无法达到100%)
异地多活设计步骤
- 业务分级(挑选核心业务)
- 数据分类(数据量,唯一性,实时性,可恢复性)
- 数据同步(存储系统同步,消息队列同步等等)
- 异常处理(多通道同步,同步和访问结合,日志记录,用户补偿)
接口级故障应对方案
相对与概率小的机房火灾,断电等故障,接口故障发生的情况更多。
接口级故障:
- 内部:程序问题,计算机性能到达极限,导致数据库慢查询
- 外部:黑客攻击,促销抢购导致用户访问量突增,第三方响应缓慢等
降级
降级是着眼与整个系统的高可用,丢车保帅的一种行为。
比如论坛的系统接近负载,暂停发帖子功能,只能看帖子。
(如果系统持续负载,服务器崩溃,看帖子的功能也废了)
熔断:
是降级的一种情况。换句话说,熔断会导致降级。
熔断是指请求达到一个阈值,暂停该服务的调用,防止系统负载过大,导致崩溃。
限流
只让一部分访问通过。保证一部分响应优于全部不能响应。
- 基于请求限流(控制阈值)
- 基于资源限流(对关键资源限流,比如线程池最大并发量)