架构师之路:流量从10万到10亿,一定会遇到的80个架构问题(8000字长文)

科技   2024-11-20 21:16   北京  

想成为一个合格的架构师,经历系统流量从10万到10亿,一定会面临以下九大场景,80个架构问题。

画外音:

(1)文章较长,建议收藏;

(2)文章底部有视频版本;


【第一章:技术选型】

创业初期架构方案怎么选型?

(1)要考虑业务的需求与特点,初期往往“快速实现”更重要,此时系统的特点是请求量小,数据量小,服务器资源也非常有限;

(2)这个阶段最重要的选型依据是:合伙人熟悉什么技术栈,使用什么技术栈

(3)第一版往往采用ALL in one架构

(4)这个阶段研发主要在写CURD业务逻辑,引入DAO和ORM能极大提高工程效率;

画外音:什么是ALL in one架构?


如果硬要问我,会选择什么技术栈,我会二选一:

PHP体系(Linux,Apache,MySQL,PHP)

或者

Java体系(Linux,Tomcat,MySQL,Java)


使用开源框架组件还是自研?

我的观点是:

(1)早期不建议自研

(2)随着规模的扩大,要控制技术栈

(3)要浅浅的封装一层

(4)适当的时候,造一些契合业务的轮子;

画外音:为什么要控制技术栈?为什么要封装一层?


什么情况下要进行容量评估?

至少在三种情况下,要进行容量评估:

(1)新系统上线

(2)临时运营活动

(3)系统容量有质变性增长


系统层面,要评估哪些重要指标?

主要评估网络带宽、CPU、内存容量、磁盘容量、磁盘IO等资源指标,系统层面主要看吞吐量指标。

画外音:容量设计五大步骤是啥?


创业初期,系统层面存在瓶颈的时候,优化原则是什么?

(1)最低成本,初期最大的成本是时间成本;

(2)用“钱”和“资源”快速解决系统问题,而不是过早的系统重构;

(3)将ALL in one架构升级为伪分布式架构,是此阶段的最佳实践;


伪分布式的核心是什么?

伪分布式的本质是单机变多机,但又不是真正的高可用,其核心是垂直拆分:

(1)业务垂直拆分;

(2)代码垂直拆分;

(3)数据库垂直拆分;

(4)研发团队垂直拆分;

画外音:伪分布式的优化细节是啥?


【第二章:接入层架构】

如何解决接入层的扩展性问题?

引入反向代理。


最常见的反向代理是什么?

Nginx。


引入反向代理之后,要解决什么新的问题?

(1)集群负载均衡;

(2)反向代理高可用;

画外音:有哪些常见的负载均衡方法?如何保证反向代理高可用?


站点流量从小到大,接入层架构如何演进?

整体可以分为五个阶段

(1)有反向代理技术之前,单体架构要解决扩展性问题,可使用DNS轮询架构

(2)有反向代理技术之后,初期可以使用反向代理解决扩展性问题;

(3)然后,需要升级为高可用反向代理架构

(4)多级反向代理,引入LVS&F5进一步扩充性能;

(5)想要无限性能,必须用DNS轮询架构

画外音:每个阶段的逻辑与细节到底是怎么样的?


Session,是接入层架构非常关注的问题,如何保证Session一致性?

通常有四种方案

(1)客户端层解决;

(2)反向代理层解决;

(3)web-server层解决;

(4)后端服务层解决

画外音:每种方案细节又是怎么样的?


CDN,是接入层不得不谈的问题,CDN架构有哪些要了解?

引入CDN架构,至少要考虑这五个问题

(1)什么样的资源适合静态加速;

(2)CDN的架构是怎么样的;

(3)CDN是怎么实现“就近访问的”;

(4)如何保证源站和镜像站数据的一致性;

(5)资源更新,是推还是拉?

画外音:学CDN,千万不要去百度“斯塔尔报告”。


TCP接入,架构上要考虑哪些问题?

至少要考虑这四个架构设计点

(1)TCP如何快速实现接入;

(2)TCP如何快速实现扩展,以及高可用;

(3)TCP如何快速实现负载均衡;

(4)TCP如何保证扩展性与耦合性的平衡;

画外音:有没有综合方案,系统性解决负载均衡 + 高可用 + 可扩展 + 解耦合等一系列问题?


【第三章:急速性能优化】
在互联网公司发展早期,为了产品快速迭代,最常使用的架构是什么?
ALL in one架构。

如果此时业务发展很快,系统成了瓶颈,架构优化的方向是什么?
用最短时间,以对代码最小的冲击,极速扩充系统性能

早期如何快速的扩充系统性能?
使用三大分离的性能优化方法。

早期系统容易“白屏”,如何快速的提升用户体验,消除白屏?
动静分离

什么是动静分离?
动静分离,是“静态页面与动态页面,分开不同的系统访问”的架构设计方法。
画外音:如何来实施?分别对应怎样的技术点?

如果静态页面访问这么快,动态页面访问这么慢,能否将“原本需要动态生成的页面,提前生成静态页面”?
可以,这是“页面静态化”技术,能够100倍提升访问速度。
画外音:这个技术适用怎么样的业务场景?

早期系统的主要瓶颈,最容易出现在哪里?
数据库读性能扛不住。

如何快速提升数据库读性能?
读写分离,使用数据库分组架构,一主多从,主从同步,读写分离。
画外音:读写分离,水平切分都是使用数据库集群,有什么异同?

后台运营系统,复杂的SQL语句对数据库性能影响较大,怎么办?
前台与后台分离
画外音:前后端分离,前台后台分离,是一回事么?如何快速实施前台与后台分离?

【第四章:微服务架构】
系统初期,哪类技术栈最为流行?
(1)PHP语言的LAMP栈;;
(2)Java语言的LiToMyJa栈;

业务快速发展,三层架构可能存在哪些问题?
(1)代码频繁拷贝;
(2)底层复杂性扩散;
(3)公共库耦合;
(4)SQL质量不可控,数据库性能急剧下降;
(5)数据库耦合,无法实现增加实例扩容;

可以通过什么架构方案解决上述1-5问题?
微服务架构

如果要落地微服务架构,服务粒度可以如何选择?
常见的有以下四种粒度:
(1)统一服务层;
(2)按业务划分服务;
(3)按库划分服务;
(4)按接口划分服务(需要轻量级进程等语言层面支持);

微服务架构,可能带来什么问题?
可能带来的潜在问题有:
(1)系统复杂性上升;
(2)层次间依赖关系变得复杂;
(3)运维,部署更麻烦;
(4)监控变得更复杂;
(5)定位问题更麻烦;
不要以为,引入一个RPC框架就是“微服务架构”了,微服务架构要解决很多问题。

微服务架构要解决哪些问题?
至少要解决高可用无限性能扩展负载均衡等众多架构基础问题。

如何解决高可用的问题?
每一层解决高可用问题的方案不一样,涉及虚IP,反向代理,集群,连接池,数据库分组,缓存冗余,故障转移等诸多技术。
画外音:高可用的方法论是什么?

如何解决无限性能扩展的问题?
每一层解决高可用问题的方案不一样,涉Scale upScale out,DNS轮询,反向代理,连接池,水平切分等诸多技术。
画外音:无限性能的方法论是什么?

如何解决负载均衡的问题?
负载均衡分为两类:
(1)同构均匀分摊;
(2)异构按能力分摊;

异构服务器负载均衡,常见的这么几种方案:
(1)静态权重法;
(2)动态权重法,涉及“保险丝”算法;
同时,动态权重法还可以实现服务器的过载保护
画外音:什么是“保险丝”算法?什么是过载保护?

哪一个组件,和高可用,无限性能扩展,负载均衡相关?
连接池。

连接池的核心是什么?
两个核心数据结构:连接数组,锁数据;
三个核心接口:初始化,拿出连接,放回连接;
画外音:如何快速掌握连接池内核?

【第五章:数据库架构】
工程上,数据库要设计一些什么?
(1)根据“业务模式”设计表结构
(2)根据“访问模式”设计索引结构

架构上,数据库还必须考虑什么?
(1)读性能提升;
(2)高可用;
(3)一致性保障;
(4)扩展性;
(5)垂直拆分;
画外音:我C,我居然从来没考虑过这些问题。

提升系统读取速度,有哪几种常见方法?
(1)建立索引;
(2)增加从库;
(3)增加缓存;

一个数据库分组集群,主从同步,读写分离,能不能在主库和从库建立不同的索引?
可以,例如:
(1)主库只响应写请求,不建立索引;
(2)线上从库,建立线上访问索引;
(3)后台从库,建立后台访问索引;

如何保证数据库的高可用?
核心思想是:冗余+故障自动转移
(1)写库高可用,冗余写库;
(2)读库高可用,冗余读库;

数据冗余会带来什么副作用?
会引发一致性问题:
(1)两个写库数据可能不一致;
(2)主库和从库数据可能不一致;

写库高可用,两个写库相互同步数据,自增ID可能冲突导致数据不一致,有什么优化方案?
(1)为每个写库指定不同的初始值,相同的增长步长;
(2)生成不同的ID;
(3)一个写库提供服务,一个写库作为高可用影子主;

主从延时,有什么优化方案?
(1)业务容忍;
(2)强制读主;
(3)在从库有可能读到旧数据时,选择性读主(非常帅气的方案);

底层表结构变更,水平扩展分库个数发生变化,底层存储引擎升级,数据库如何平滑过度?
如果业务能够接受,可以停服扩展。

否则,可以使用以下三种方法:
(1)追日志平滑扩容法,平滑过度;
(2)双写平滑扩容法,平滑过度;
(3)秒级平滑扩容法(非常帅气的方案);
画外音:如何在秒级,实现读写实例加倍?容量加倍?

数据库垂直拆分的最佳实践是什么?
数据库垂直拆分,尽量把:
(1)长度短;
(2)访问频率高;
(3)经常一起访问;
的数据放在主表里。

【第六章:缓存架构】
工程上,缓存一般有几种使用方式?
(1)进程内缓存
(2)进程外缓存,也就是缓存服务

如果有多个服务使用进程内缓存,如何保证一致性?
常见的有三种方法:
(1)服务节点同步通知;
(2)MQ异步通知;
(3)牺牲少量一致性,定期后端更新;

绝大部分情况,还是应该使用缓存服务,缓存的使用,有什么注意点?
以下几点,应该要注意:
(1)服务与服务之间不要通过缓存传递数据;
(2)如果缓存挂掉,可能导致雪崩,此时要做高可用缓存,或者水平切分;
(3)调用方不宜再单独使用缓存存储服务底层的数据,容易出现数据不一致,以及反向依赖;
(4)不同服务,缓存实例要做垂直拆分,不宜共用缓存;

互联网缓存操作细节,最佳实践是什么?
Cache Aside Pattern

Cache Aside Pattern的细节是什么?
它分为读缓存最佳实践,以及写缓存最佳实践。

读缓存最佳实践是:先读缓存,命中则返回;未命中则读数据库,然后设置缓存。

写缓存最佳实践是:
(1)淘汰缓存,而不是修改缓存;
(2)先操作数据库,再操作缓存;
画外音:为什么呢?

缓存的本质是“冗余了数据库中的数据”,可能存在什么问题?
缓存与数据库数据不一致

什么场景下容易出现不一致?
写后立即读业务场景。
画外音:为什么呢?

出现不一致时,优化思路是什么?
及时把缓存中的脏数据淘汰掉。

具体要怎么淘汰,保证缓存与数据库中数据的一致性呢?
(1)服务同步二次淘汰法;
(2)服务异步二次淘汰法;
(3)线下异步二次淘汰法;
画外音:二次淘汰法,是很常见的一种实践。

目前缓存服务最常用的是什么?
Redis和memcache。

什么时候选择使用Redis?
以下场景优先使用Redis:
(1)需要支持复杂数据结构;
(2)需要支持持久化;
(3)需要天然高可用;
(4)value存储内容比较大;
如果只是纯KV,可以使用memcache。
画外音:纯KV场景,为什么memcache会更快呢?

【第七章:架构解耦】
配置文件,是互联网架构中不可缺少的一环。依赖(调用)某个下游服务集群,将下游集群信息放在自身配置文件里是一种惯用做法,该做法可能导致什么问题?
可能导致上下游严重耦合:
(1)上游痛:扩容的是下游,改配置重启的是上游;
画外音:架构设计中典型的反向依赖。
(2)下游痛:不知道谁依赖于自己,难以实施服务治理,按调用方限流;

为了解决上述问题,常见的配置架构演进是怎么样的?
(1)“配置私藏”架构;
(2)“全局配置文件”架构;
(3)“配置中心”架构;

除了配置中心,消息总线MQ也是互联网架构中的常见解耦利器。

一般来说,什么时候不使用MQ?
上游实时关注执行结果时,通常不使用MQ,而使用RPC调用。

什么情况下,可以使用MQ来解耦?
以下四种情况,可以使用MQ来解耦:
(1)数据驱动的任务依赖;
(2)上游不关心执行结果;
(3)上游关注结果,但执行时间很长,例如跨公网调用第三方服务;
(4)削峰填谷,流量控制,保护下游;

上下游IP耦合,可以如何解耦?
使用内网域名来代替内网IP。

多个模块,因为公共库而耦合在一起,可以如何解耦?
粗暴方案:代码各自拷贝一份(不太推荐)。
优化方案:
(1)垂直拆分,个性业务代码“上浮”;
(2)服务化,共性业务代码“下沉”;

多个模块,因为数据库而耦合在一起,可以如何解耦?
数据库耦合,需要对架构进行调整:
(1)第一步,公共数据访问服务化,数据私藏;
(2)第二步,个性数据访问,自己家的数据自己管理;
画外音:数据库耦合,当数据库成为瓶颈时,增加数据库实例也难以拆分扩容,非常头疼。

微服务拆分不完全,导致耦合,可以如何解耦?
(1)底层微服务功能要尽量通用;
(2)杜绝底层switch case不同业务类型的业务逻辑代码;
(3)个性化代码上浮,公共代码下沉,是更古不变的架构解耦准则;
画外音:架构复杂时,微服务是好事,但拆分不彻底反而会有坑。

【第八章:架构分层】
为什么互联网系统架构分层会越来越多?
当系统越来越复杂的时候,为了:
(1)让上游更高效的获取与处理数据,必须复用
(2)让下游能屏蔽数据的获取细节,必须封装
上述复用和封装,在系统架构上的呈现,就是“分层”

每次都要连接数据库获取数据,编码非常低效,有什么痛点?
每次数据库访问,都需要:
(1)创建连接,创建资源;
(2)拼装SQL;
(3)执行SQL并获取结果集;
(4)通过游标遍历结果集,拿到每一行,分析行数据,拿到每一列;
(5)关闭连接,回收资源;
很多重复的代码要编写,效率很低。

怎么优化?
分层抽象,分离DAO层。

单体架构,编码非常低效,有什么痛点?
每次数据获取,都需要:
(1)关注缓存细节(Redis?MC?);
(2)关注存储引擎细节(MySQL?);
(3)关注分库分表;
(4)关注数据路由规则;
很多重复的代码要编写,效率很低。

怎么优化?
分层抽象,分离基础服务层(微服务)。

微服务架构,编码非常低效,有什么痛点?
每次数据获取,都需要:
(1)要访问很多RPC接口,获取很多公共的数据;
(2)站点层与基础服务层之间的连接关系非常复杂;
(3)不同垂直业务之间有需要共性业务,代码要冗余很多次;
很多重复的代码要编写,效率很低。

怎么优化?
分层抽象,分离共性业务服务层。
画外音:可以先简单理解为“中台业务服务”。

PC/H5/APP多端业务,编码非常低效,有什么痛点?
每次数据获取,都需要:
(1)大部分业务逻辑相同,只有少量展现/交互不一样;
(2)一旦一个服务RPC接口升级,多端都要升级;
(3)一旦一个服务bug出现,多端都要升级;
(4)PC/H5/APP多端相同的逻辑存在大量代码拷贝;
很多重复的代码要编写,效率很低。

怎么优化?
分层抽象,前后端分离。

大数据量,高并发量的微服务架构,编码非常低效,有什么痛点?
数据库侧数据获取,往往:
(1)根据业务进行数据路由,水平切分;
(2)不确定路由的接口,要遍历全库;
(3)有时候要多个库拿数据,然后到内存排序,例如跨库分页需求;
(4)…
很多微服务有很多重复的代码要编写,效率很低。

怎么优化?
分层抽象,数据库中间件。

可以看到,架构分层,对研发效率的提升,与复杂性的屏蔽,至关重要。

【第九章:架构进阶】
负载均衡、数据收集、服务发现、调用链跟踪。这些非业务的功能,一般是谁实现的呢?
(1)互联网公司一般会有一个“架构部”,研发框架、组件、工具与技术平台;
(2)业务研发部门直接使用相关框架、组件、工具与技术平台,享受各种“黑科技”带来的便利;

对于上述“黑科技”的使用与推广,存在什么问题?
框架、组件、工具与技术平台的使用与推广,往往会遇到以下一些问题:
(1)业务研发团队,需要花大量时间去学习、使用基础框架与各类工具;
(2)架构部,对于“黑科技”不同语言客户端的支持,往往要开发C-client,Python-client,go-client,Java-client多语言版本;
(3)架构部,“黑科技” client要维护m个版本, server要维护n个版本,兼容性要测试m*n个版本;
(4)每次“黑科技”的升级,都需要推动上下游进行升级,这个周期往往是以季度、半年、又甚至更久,整体效率极低;
画外音:每次fastjson漏洞升级,要1个月。

如何来进行优化?
一个思路是,解耦将业务服务拆分成两个进程
(1)一个进程实现业务逻辑(不管是调用方,还是服务提供方),biz,即上图白色方块;
(2)一个进程实现底层技术体系proxy,即上图蓝色方块;
画外音:负载均衡、监控告警、服务发现与治理、调用链…等诸多基础设施,都放到这一层实现。

他们之间有这样一些特点:
(1)biz和proxy共同诞生,共同消亡,互为本地部署,即上图虚线方框;
(2)biz和proxy之间,为本地通讯,即上图黑色箭头;
(3)所有biz之间的通讯,都通过proxy之间完成,proxy之间才存在远端连接,即上图红色箭头;

这样就实现了“业务的归业务,技术的归技术”,实现了充分解耦,如果所有节点都实现了解耦,整个架构会演变为:
(1)绿色为biz;
(2)蓝色为proxy;
整个服务集群变成了网格状,这就是Service Mesh服务网格的由来。

Service Mesh的行业开源最佳实践是什么?
Istio。

Istio的架构核心是什么?
Istio架构分为两层:
(1)数据平面(data plane)
(2)控制平面(control plane)

其架构核心方法论是:控制与实施分离
画外音:具体envoy,mixer,citadel,pilot和galley的职责与细节,见《大专栏》。

前面所有章节讲的都是单机房架构,单机房架构的特点是什么?
架构分层之间,是全连接

理想化的多机房架构,特点是什么?
架构分层之间,是同连接,即:站点,服务,数据全部单元化,仅连接同机房。

理想化的多机房架构,存在什么问题?
(1)并非所有的业务都能“单元化”;
(2)如果不能“单元化”,跨机房的数据同步存在较大延时;

有什么折衷方案?
可以实施“折衷多机房架构”。

什么是“折衷多机房架构”?
站点,服务,数据做不到全量单元化,做不到“只”连接同机房,但可以“最小化”跨机房连接,整个架构,可以只有两个地方跨机房:
(1)数据库写库(相比读,写的比例较小);
(2)数据库一处主从同步(本来就有延时);

折衷多机房架构,有什么优点?
机房区分主次,落地性强,对原有架构冲击较小,业务几乎不需要进行单元化改造
画外音:更多多机房架构细节,详见《大专栏》。

18次直播回看,以及《架构师训练营》,系统性的详聊了上面这80个问题,感兴趣的同学可以扫码看细节。

18次直播精华回看,有哪些内容?
(1)每秒100w请求,秒杀架构
(2)千万粉丝,feed架构
(3)千万同时在线,IM架构
(4)每秒100w检索,搜索引擎内核架构
(5)MQ内核细节
(6)RPC内核细节
(7)数据库架构
(8)多机房多活架构与细节
(9)分布式调用链追踪架构与细节
(10)3周自研自动化上线平台
(11)区块链中的架构理念
(12)数据库性能瓶颈定位
(13)反范式数据库设计
(14)微服务抽离与解耦
(15)经典架构10问
(16)微服务与数据库架构10问
(17)技术人职业发展规划
(18)InnoDB内核架构与细节
每次1-2小时不等,全部已放出

50节架构师训练营干货重放,有哪些内容?
第一阶:技术选型(5节,已放出)
第二阶:接入层架构(5节,已放出)
第三阶:极速性能优化(3节,已放出)
第四阶:微服务架构(7节,已放出)
第五阶:数据库架构(6节,已放出)
第六阶:缓存架构(7节,已放出)
第七阶:架构解耦(6节,已放出)
第八阶:架构分层(5节,已放出)
第九阶:架构进阶(6节,已放出)
把控住这些,应该能成为一名P8的架构师吧?

《大专栏》是什么?
20年口罩期间,我录制的一个架构实践课,讲述流量从10万到10亿增长过程中,架构师将要面临的典型场景,会遇到什么架构问题,如何思考这些问题,如何解决这些问题。

《大专栏》以怎样的节奏学习最合适?
建议平均每天花1-2小时(可倍速)。

《大专栏》大概多久能学完?
快的话,能坚持的话,1个月之内

《大专栏》有没有福利?
福利1:不用购买,邀返立得179.8
详情页右上角分享,不买专栏也能邀返

福利2:原价1699(20年找团队录的),现价巨折只需XXX,扫码你就知道了;

重点提醒:学习过程中一定要“加群”,任何问题,随时群内沟通交流。

如何学习《大专栏》?
扫码,学习架构师之路《大专栏

阅读原文,学习《大专栏》,希望大家有收获。

架构师之路
架构师之路,坚持撰写接地气的架构文章
 最新文章