之前有在文章中介绍过云原生的十二要素,今天来介绍下云原生架构以及其架构设计中需要考虑的关键因素(后续逐步完善)。
概要
还是先通过一张图简单介绍云原生架构的组成,具体见下图:
- 敏捷基础设施
- 公共基础服务
- 微服务架构
- DevOps
- 团队文化
- 架构设计
接下来重点讲解其架构设计中的四个要素。
架构设计
主要包括:高可用、可扩展性、性能、一致性这四个方面。
可用性设计
可能影响系统可用性的因素主要有三方面:发布、故障和压力。下面就分析基于这三方面的应对方案。
发布
- 影子测试
除了使用log或者tcpcopy来复制影子环境以外,如果系统使用了MQ,可以直接为MQ添加消费者,将流量复制到影子系统;
- 蓝绿发布
蓝绿部署的问题是: 需要一套独立的闲置资源;
- 灰度发布
过程: 内部员工
> 1%的外部友好用户
> 5%的友好用户
> 10%的友好用户
> 全网发布
故障(容错设计)
- 消除单点
飞行员总是要将飞机上升到执行两次失误的高度才开始做动作,也启发我们为什么负载均衡后的节点都推荐是 n+2
而不是 n+1
;
- 特征开关
代码分支管理,如果是基于master开发,需要提供特征开关,从而避免相互影响的时候能够快速切换;
- 服务分级
在高流量期,可以考虑牺牲部分功能,通过降级服务来达到整体系统的高可用;
- 超时重试策略
- 熔断器
- 故障隔离
压力(流控设计)
- 限流算法
窗口、漏桶、令牌桶
- 限流策略
GW入口、微服务入口、中间件
- 容量预估
全链路压测
- 故障演练
各种monkey
扩展性设计
- AFK扩展立方
X
: 横向扩展(数据库、磁盘压力)
Y
: 微服务拆分(数据库压力)
Z
: 分库分表
- 数据库扩展
- 数据库的三坐标
X
: master+slave,扩展多个slave用于读;
Y
: 分库(微服务拆分);
Z
: SATA盘,单表十个字段,数据量达到1千万会出现瓶颈,需要分片
- 数据库分片方法
- 区间法(按照ID范围), 容易导致数据热点;
- 轮转法(hash(key)mod node_number ),不容易排序,拓扑变化需要重新分配
- 扩容
- 停服扩容;
- 0中断扩容(先将新加节点设为slave,然后提升为master,再修改数据库中间件配置,注意:需要支持去重)
- 应该让单次请求在一个数据中心处理完
- 两地三中心、同城多活、异地多活
性能设计
性能指标
- 响应时间
- 吞吐量
单位时间的响应次数
- 负载敏感度
用户增加、系统响应时间的衰减度(系统数据量、数据增长速度)
- 可伸缩性
使吞吐量增加一倍,需要扩展的节点数(资源限制)
优化方法
- 通信优化
序列化消息(grpc protobuf 等)
- 通过中间件提高吞吐量
- MQ解决写的性能瓶颈
- 缓存解决读的性能瓶颈(cache aside, cache as sor)
一致性设计
由于微服务拆分后,各个微服务使用独立数据库,可能导致数据不一致。
CAP
- 一致性(Consistence)
分布式系统中的所有数据备份,在同一时刻是否同样的值。(等同于所有节点访问同一份最新的数据副本)
- 可用性(Availability)
集群出现故障节点后,是否还能响应客户端的读写请求。(对数据更新具备高可用性)
- 分区容忍性(Partition tolerance)
实际中通信产生延时。系统如果不能在时限内达成数据一致性,就意味着发生了分区的情况,必须就当前操作在C点和A点之间做出选择。
BASE
- 基本可用(Basically Available)
基本可用是指分布式系统在出现故障的时候,允许损失部分可用性,即保证核心可用。
- 软状态( Soft State)
软状态是指允许系统存在中间状态,而该中间状态不会影响系统整体可用性。分布式存储中一般一份数据至少会有三个副本,允许不同节点间副本同步的延时就是软状态的体现。mysql replication的异步复制也是一种体现。
- 最终一致性( Eventual Consistency)
最终一致性是指系统中的所有数据副本经过一定时间后,最终能够达到一致的状态。弱一致性和强一致性相反,最终一致性是弱一致性的一种特殊情况。
Quorum机制(NWR原理)
思想
:一致性不取决于写时进行全同步,只要保障读的时候能够读到最新的数据就解决问题了。
只需要满足 R + W > N
, 其中N为副本数, R和W分别为读写的节点数。
实现强一致性
-
两阶段提交的问题
- 可能第二阶段出异常(某个参与者网断了),无法处理;
- 协调者的可用性无法保障,可能导致第一阶段后资源被锁死;
- 两个阶段之间需要锁定资源,可能导致阻塞
-
三阶段提交
- 流程和思想
- 将两阶段的第一阶段分为两个阶段,先请求,得到同意字后再锁定资源;
- 另外引入超时机制;
- 问题
- 可能第三阶段出异常(某个参与者网断了),无法处理;
如何实现最终一致性
悲观锁与乐观锁
分布式锁
- zookeeper
- Redis
基于setnx
问题在于Redis是异步复制的,如何保障主节点挂了之后,不影响分布式锁?
原文
http://ljchen.net/2019/03/30/Cloud-Native架构设计/