架构师学习心得
前言
古时江湖中人有两种讲究:“里”与“尖”,也称为“术”与“道。里指的是手段,类似生意经,揣摩人的心理运用何种方法才能达到目的;尖指的是真本领、真正的功夫与追求的大道。比如疲门讲行医,“里”指的就是怎么故弄玄虚能忽悠人,而“尖”指的是真正的医道修为。
在世间行事,这“里”与“尖”二者不可偏废,否则就算你有真本事也未必有人肯买帐,古往今来天底下怀才不遇人多的是。俗话说“尖中里,了不起,里中尖,赛神仙”,讲的就是这个道理。但是近代以来走江湖的术士艺人,更多的是研究坑蒙拐骗的手段,大多沦为下九流了。其实江湖术本身是一门大学问,如果善用此中之道,足以行走天下。
--摘自 徐公子胜治
之所以开头引用这么一段是既是因为这段话刚好与华仔说过的“道”与“术”理论有异曲同工之妙,也是因为这个思想也是我学习架构师训练营最大的收获与感想;
对于技术工种,绝大部分人认为衡量能力的方法就是技术好不好,但现实工作中一个项目能不能做,应该怎么做需要得到多个方面的认可,如何能够多方人员认可是非常有方法可循的。
--个人感言
道
一、架构师整体职责
核心职责:一、解读痛点;二、理解要求
核心能力:判定、拆解、取舍
一、判断(确定性思维,排除模糊、不确定的说法、信息)
1、业务理解力
2、技术能力
3、沟通能力
二、拆解(创造性思维,通过排列组合得到更多方案)
1、技术深度
2、技术宽度
3、技术广度
三、取舍(系统性思维,有逻辑和推导过程)
1、设计理念
2、说服能力
3、决断能力
需求详细处理流程:
判断维度-> 三原则(合适/简单/演进)->架构设计环->4R 架构(分层+角色+角色关系+运作规则)
二、架构复杂度
来源:业务复杂度、质量复杂度;
两者正交产生产生四个象限,通过对需求项目的象限判定,达到一个初步的项目复杂度定位判定(架构需求分析处理第一步就应该做的事情);
分析和设计复杂度常用的方法:
一、拆分(鸡蛋篮子第一法则:如果一个篮子数不清,拆分到多个篮子再数!)
拆分粒度:内部复杂度、外部复杂度
拆分第一原则 - - 内外平衡原则
拆分第二原则 - - 先粗后细原则
二、封装
预测第一原则 - - 2 年原则
预测第二原则 - - 3 次法则 没有把握不要封装,1 写 2 抄 3 封装(同样问题遇到三次再封装)
三、叠加(鸡蛋篮子第二原则:如果一个篮子装不下你的鸡蛋,用多个篮子!)
四、冗余(鸡蛋篮子理论第三法则:不要把所有鸡蛋装在一个篮子,放到多个篮子!)
注:高性能任务分配考虑的是正常处理,高可用任务分配考虑的是异常处理
鸡蛋篮子三原则分别对应架构设计中的:可扩展、高性能、高可用
业务容忍度优先级:生命>安全>金钱>付费>免费>内部
三、架构文档
前期
任务
1、澄清不确定性
2、识别复杂度
关键输出
1、总体业务架构图
2、核心场景流程
中期
任务
1、设计备选方案
2、选择备选方案
关键输出
1、备选方案
2、方案评估结论
3、方案结论汇报
后期
任务
1、细化架构(按照 4R 完善细节)
2、完善架构(可维护性、可测试性、成本、安全)
关键输出
完整的架构设计文档
架构文档内容
业务背景(解决什么问题,带来什么价值)
约束限制(明确的,无需设计的相关条件)
总体架构设计(Rank、Role、Relation)
详细架构设计(Rule 具体的架构规范)
架构质量设计(可测试性、可维护性、安全、规范等)
架构演进规划(一期、二期....)
术
一、数据库存储架构
每种存储系统都有自己的有别于其它系统的典型特征,其技术本质决定了其核心应用场景和以及优缺点。
1、读写分离
如何判断需要读写分离
a、业务量持续增长
b、先优化(优化索引、加入缓存)再重构
2、分库分表
3、分布式事务算法
1、2PC
2、3PC
3、mysql 事务 XA
数据库复制架构
主备/主从架构
双机切换-主备切换
双机切换 - - 主从切换
集群选举架构
分片架构和分区架构
分片架构设计核心
1.分片规则:数据按照什么规则分片
2.路由规则:业务服务器如何找到数据
分片架构高可用方案
独立备份(MongoDB\Redis\MySQL)
互相备份(es\hdfs)
分区架构
全局路由(DNS/GSLB)
备份策略(集中/互备/集中)
如何设计存储架构
1、估算性能需求
用户量预估->用户行为建模->存储性能需求计算
2、选择存储系统
从单机存储、读写性能支持是否需要自动切换、分区部署进行判定
技术本质:挑选应用场景和系统本质契合的系统
技术储备:挑选熟悉的
综合考虑:可维护性、成本、成熟度
设计存储方案
1、设计数据结构
2、验证读写场景
3、评估读写性能
4、迭代返回 1
二、计算架构(缓存、负载均衡、高可用)
缓存
缓存的技术本质:空间换时间
作用:加速数据的读写能力
缓存设计-3W1H
业务场景
what 存什么
when 存多久
技术抉择
where 存哪里(技术选择)
how 如何存(更新、过期策略)
多级缓存
app/浏览器缓存-
CDN
WEB 容器缓存
应用缓存(进程内、进程外、SSD)
分布式缓存
缓存三类问题
缓存穿透
应对方法:
1、空值缓存(防止攻击或业务逻辑漏洞)
2、缓存当前数据(应对爬虫、分页)
3、数据预热(模拟请求/按规则批量生成/灰度发布、预发布)
4、随机失效(缓存有效期设定为一个时间范围内的随机值,例如 3~5 分钟内随机失效
缓存雪崩
原因
1. 生成缓存较慢(复杂的数据查询,大量的计算等);
2. 缓存失效后并发请求量较大,例如 50 个以上。
应对方法
一、更新锁
二、后台更新
缓存热点
应对方法:多副本缓存
难点:不好预测那些是热点,需要动态决策和人工干预
负载均衡
DNS(最泛用)
HTTP-DNS(业界常规增强)
GSLB(全球部署)
基于 DNS 的 GSLB
基于 HTTP redirect 的 GSLB
基于 IP 欺骗的 GSLB
F5(性能 100W~1000W)
LVS(性能 10W~100W)
LVS-NAT
LVS-DR
LVS-TUN
Nginx(性能 5W ~10W)
F5/LVS/Nginx 对比
通用负载算法
轮询/随机
加权轮询
负载优先
性能优先
Hash
接口高可用
雪崩效应:请求量超过系统处理能力后导致系统性能螺旋快速下降。
方法:1、限流;2、排队
链式效应:某个故障引起后续一连串的连锁故障
方法:1、熔断;2、降级
总结:本质上是丢车保帅,业务或者用户体验是部分有损的
三、微服务
分层架构与微服务架构区别
分层架构:端到端的架构或者单个系统的内部架构,按照某种规则划分为不同层级
微服务是端到端分层架构中的业务层的架构
微服务陷阱
粒度太细
服务关系复杂,内部复杂度低,外部复杂度高,整体复杂度高
团队效率下降,需求分析、方案设计、测试、部署工作量都会增加
问题定位困难,单个微服务故障导致多个微服务异常,监控到处告警,不知道根本原因
系统性能下降,调用链长,单次请求耗时更长
基础设置缺乏
无法快速交付
服务管理混乱
陷阱应对
业务级分布式事务
本地事务消息
消息队列事务
全局幂等
接口兼容
1. 接口多版本,直接拷贝一份旧接口代码,在旧接口代码上修改,接口 URL 加上 v1/v2 这种标识;
2. 接口逻辑兼容,同一份接口代码,兼容新旧逻辑,容易互相影响,且旧接口下线时又要修改代码(不推荐)
接口循环调用(没有好办法)
四、灾备/异地多活
FMEA 方法排除架构隐患
一套分析和思考的方法,而不是某个领域的技能或者工具。
Failure:假设系统某些组件或者模块出现故障。
Mode: 故障发生的方式、可能性。
Effect :故障的影响。
Analysis:分析系统的可能反应,以及如何改进。
应用场景:总体架构优化迭代时候
分析维度
业务功能:FMEA 分析设计的功能点,从用户角度而不是系统角度。
故障模式:系统中可能出现什么样的故障,尽量精确,多使用量化描述,避免使用泛化的描述。例如,推荐使用“MySQL 响应时间达到 3 秒”,而不是“MySQL 响应慢”
故障影响:发生故障是,业务功能具体收到什么影响,尽量准确描述。例如,推荐使用“20%的用户无
法登录”,而不是“大部分用户无法登录”;
严重程度:故障对业务的影响程度
故障原因:导致故障发生的原因,不同原因可能导致相同的现象,发生概率、检测手段、处理措施
故障概率:某个具体故障原因发生的概率,1、硬件;2、开源系统;3、自研系统
风险程度:综合艳照程度和故障概率一期判断等级;风险程度 = 严重程度×故障概率
已有措施:针对具体故障,系统是否提供了某些措施应对,常用:1、检测告警;2、容错;3、自恢复
规避措施:为了降低故障发生的概率或者故障影响采取的一些措施。可以是技术手段,也可以是管理
手段。
例如:
1. 技术手段:为了避免新引入的 MongoDB 丢失数据,在 MySQL
中冗余一份。
2. 管理手段:为了降低磁盘坏道的概率,强制统一更换服务时间超过 2 年的磁盘。
解决措施:能够解决问题而坐的一些事情;
一般都是技术手段。例如:
1. 为了解决密码暴力破解,增加密码重试次数限制。
2. 为了解决拖库导致数据泄露,将数据库中的敏感数据加密保存。
3. 为了解决非法访问,增加白名单控制。
如果某个故障既可以采取规避措施,又可以采取解决措施,优先选择解决措施。
灾备设计
同城双中心
跨城双中心
OceanBase 官方推荐, 2 近(10ms)1 远(30m)
异地多活
三种模式
业务定制型异地多活(设计核心 - - RoleID)
业务通用型异地多活
存储通用型异地多活
核心原理
粒度:CAP 关注的粒度是数据,而不是系统,需要根据不同业务的数据特点来设计异地多活
延迟:CAP 是忽略网络延迟的 ,但工程落地不可能做到零延迟。
分区容忍:C 和 A 只能取 1 个是在发生分区的时候,正常运行情况下,可以同时满足 CA。
三大原则
原则 1-只保证核心业务
原则 2-只能做到最终一致性
原则 3-只能保证绝大部分用户( 不要为了 0.01%的用户,而影响了 99.9%的用户)
设计步骤
1、业务分级(a、访问量;b、核心场景;c、收入来源)
2、数据分类(修改量、一致性、唯一性、可丢失性、可恢复性)
3、数据同步(数据库同步、消息队列、二次读取、回源读取, 根据需求进行取舍或叠加)
4、异常处理(业务兼容/事后补偿/人工修正)
设计技巧
1、全局唯一数据(消息队列辅助同步)
2、库存拆分
3、事务合并
4、实时改异步
5、适当容忍
五、高性能、高可用设计技巧
网络模型:多 Reactor 多线程” 是目前已有技术中接近完美的技术方案!
常见集群算法:
Bully 选举算法、Raft 选举算法、ZAB、Paxos
消息队列通讯协议
gRPC
1. 成熟框架,通过 IDL 支持多语言;
2. 性能好,底层使用 HTTP/2;
3. 基于 Protocol Buffer,性能好,可扩展;
4. 实现要复杂一些。
TLV
1. 实现简单;
2. 可扩展;
3. 性能不如 gRPC。
HTTP
1. 实现简单;
2. 可扩展;
3. 支持异构系统,无需嵌入 SDK;
4. 性能不如 gRPC 和 TLV
六、架构的重构与演进
架构重构
【定义】
通过调整系统结构(4R)来修复系统质量问题而不影响整体系统能力。
【目的】
修复质量问题(性能、可用性、可扩展……)。
【关键点】
1. 修复质量问题,提升架构质量;
2. 不影响整体系统功能;
3. 架构本质没有发生变化。
重构技巧
先局部优化后架构重构
局部优化常见手段
数据库添加索引,优化索引;
某个数据缓存更新策略采用后台更新;
增加负载均衡服务数量;
优化代码里面并发的逻辑;
修改 InnoDB buffer pool 配置,分配更多内存;
服务间的某个接口增加 1 个参数。
架构重构常见手段
引入消息队列(增加 Role);
去掉 ZooKeeper,改为内置 Raft 算法实现(删除 Role);
将 Memcached 改为 Redis(改变 Role);
按照稳定性拆分微服务(拆分 Role);
将粒度太细的微服务合并(合并 Role);
将服务间的通信方式由 HTTP 改为 gRPC(修改 Relation);
SDK 从读本地配置文件改为从管理系统读取配置(修改 Rule)。
有的方式
1、明确目标:不要试图解决所有的问题,抓住关键问题。
2、明确时间:要有明确的时间点和里程碑,不要说“慢慢优化”
3、明确结果:需要有量化的指标来衡量,不能说“提升 xxx 质量”。
合纵连横
合纵:说服老板
1、数据说话
2、案例说话
连横:说服其他团队
1、换位思考
2、合作双赢
运筹帷幄
问题分类:将问题分类,一段时间集中处理一类问题。
问题排序:分类后排序,按照优先级顺序来落地。
逐一攻破:每一类问题里面先易后难。
架构演进
1 个原则
架构演进是为了促进业务发展。
目的:降低成本、提升效率、提升质量
价值:新技术要带来典型的价值才考虑演进。产出要远远大于投入!
2 个驱动力
1. 业务发展带来新的复杂度,ToC 业务主要体现在用户规模增长和业务多样性;
2. 技术发展带来新的复杂度应对方法,例如国产化,大数据、云计算等。
2 种模式
1. 主动演进:架构师主动识别和规划架构演进;
2. 被动演进:架构师被迫进行架构演进。
版权声明: 本文为 InfoQ 作者【ifc177】的原创文章。
原文链接:【http://xie.infoq.cn/article/eaebfe33fede6cf312c29cef8】。未经作者许可,禁止转载。
评论