架构设计面试精讲

课程:《架构设计面试精讲》刘海丰(拉勾)

一、架构原理与技术认知

01 技术认知
  • 1 架构设计的4点理解?
    架构拆分其实是管理在技术上提效的一种手段
    –** 为什么做架构拆分?**通常最直接目的就是做系统之间解耦、子系统之间解耦,或模块之间的解耦。
    –**为什么要做系统解耦?**系统解耦后,使得原本错综复杂的调用逻辑能有序地分布到各个独立的系统中,从而使得拆封后的各个系统职责更单一,功能更为内聚。
    –**为什么要做职责单一?**因为职责单一的系统功能逻辑的迭代速度会更快,会提高研发团队响应业务需求的速度,也就是提高了团队的开发效率。
    –**为什么要关注开发效率?**研发迭代效率的提升是任何一家公司在业务发展期间都最为关注的问题,所以从某种程度上看,架构拆分是系统提效最直接的手段。

  • 2 课程案例(后续以此扩展)
    在这里插入图片描述

02 架构视角
  • 1 问题:你之前如何设计这个系统的?–注重系统设计思路
  • 2 一个优化实例
    1)场景
    在电商中,当用户发表一条商品评论,后台的逻辑是点评系统会调用一系列的远程 API 接口,如调用风控系统、广告系统、消息系统……几个甚至十几个系统的接口。
    2)初期实现
    实现:同步 RPC(Remote Procedure Call,远程过程调用)远程调用各系统接口。
    优点:在系统少、逻辑简单的阶段很符合实际情况的设计。
    缺陷:过多地依赖其他系统,导致评论发布的接口性能很低,可用性也容易受到其他系统影响。而且每当点评系统需求上线时,其他系统都需要跟着进行联调测试,导致需求迭代速度缓慢。
    在这里插入图片描述
    3)优化
    思路:问题在于系统间的耦合度太高。解决办法就是采用异步化解耦,从而通过引入 MQ 消息管道,在架构上进行系统业务逻辑拆分,将原本强依赖的系统间的同步 RPC 调用变成异步消息触发。架构如下:
    在这里插入图片描述
    不加分回答: 说“我引入了 MQ 消息队列,做了系统解耦,采用异步消息通知的方式来触发系统调用”。
    分析:网络答案,项目真实性质疑。
    4)加分回答:
    **分层表述:**四个层面的答案:
    ① 谈复杂来源;② 谈解决方案;③ 谈评估标准;④ 说技术实现。
    1> 复杂来源
    评估系统复杂度: 互联网软件通常分为功能性的复杂度和非功能性的复杂度两种。
    功能性复杂度:要解决业务发展带来的系统耦合、开发效率缓慢问题。
    非功能性复杂度:要保证系统的高可用性。
    在这里插入图片描述
    2> 解决方案
    一般出2~3个备选方案,设计要考虑可行性和优缺点。
    ① 采用开源的 MQ 消息管道。目前 MQ 消息管道有很多开源解决方案,比如 Kafka、RocketMQ、RabbitMQ 等。在实际项目中,你可以根据不同的应用场景选择合适的成熟开源消息队列方案,这是很多公司常用的做法。
    ② 采用开源的 Redis 实现消息队列。方案 1 虽然应用了开源 MQ 实现点评消息的通信,但是因为引入一个消息中间件就会带来运维成本,所以方案 2 可以基于轻量级的 Redis 实现,以降低系统的维护成本和实现复杂度。
    ③ 采用内存队列 + MySQL 来实现。方案 2 中虽然应用了较为轻量级的 Redis 来实现,但是还需要引入一个缓存系统,同样也会带来运维成本,所以方案 3 是直接基于 MySQL 实现,即基于内存队列的方式,异步持久化到数据库,然后通过定时任务读取 MySQL 中的消息并处理。
    在这里插入图片描述
    3> 评估标准
    目的:选择最合适的实现方案。
    无优劣,更适合业务。
    在这里插入图片描述
  • 3 总结
    在这里插入图片描述

二、分布式原理与设计

03 CAP分布式理论
  • 1 CAP 理论
    –概念:C(Consistency)是数据一致性、A(Availability)是服务可用性、P(Partition tolerance)是分区容错性。C、A、P 只能同时满足两个目标,而由于在分布式系统中,P 是必须要保留的,所以要在 C 和 A 间进行取舍。假如要保证服务的可用性,就选择 AP 模型,而要保证一致性的话,就选择 CP 模型。
    –必要性:在绝大多数时间里并不存在网络分区(网络不会经常出现问题)。为什么还要进行三选二吗(CP 或者 AP)?原因:不同的分布式系统要根据业务场景和业务需求在 CAP 三者中进行权衡。CAP 理论用于指导在系统设计时需要衡量的因素,而非进行绝对地选择。

  • 2 CAP原理
    –现在有一个分布式系统 A,它有一个副本 A1,在正常情况下,客户端 Client 写数据到系统 A,然后数据从 A 节点同步到 A1 节点,再返回给 Client 成功状态。
    –这时,客户端 Client 从任何节点 A 或 A1 读取数据,都能读取到最新写入的数据,说明 A 和 A1 的数据是一致的,并且 A 和 A1 也都是可用的。
    –网络是不可靠的,节点 A 和 A1 的网络随时会因为中断而出现分区。所谓网络分区就是由于网络不通导致节点 A 和 A1 被隔离在不同的网络子集中,此时节点 A 的数据就不能及时同步到节点 A1 中了。
    –出现网络分区时,根据 CAP 理论,需要在 A 和 C 中进行取舍,即要么保证系统的可用性,要么保证数据一致性。
    在这里插入图片描述在这里插入图片描述

  • 3 实践经验
    1)BASE 理论
    –引入:分布式的设计方案是数据一致性和系统可用性的权衡,并不是非此即彼。所以即使无法做到强一致性(简单来讲强一致性就是在任何时刻所有的用户查询到的数据都是最新的),也可以根据自身的业务特点,采用适当的方式来使系统达到最终一致性。由此引出 BASE 理论。
    –概念:是CAP 理论的延伸。BASE 是 Basically Available(基本可用)、Soft State(软状态)和 Eventually Consistent(最终一致性)三个单词的简写;
    –作用:是保证系统的可用性,然后通过最终一致性来代替强一致性,它是目前分布式系统设计中最具指导意义的经验总结。
    2)实际项目中,你如何通过 BASE 理论来指导设计实践呢?
    1> 基本可用性
    在这里插入图片描述
    2> 软状态和最终一致性
    指的是允许系统中的数据存在中间状态,这同样是为了系统可用性而牺牲一段时间窗内的数据一致性,从而保证最终的数据一致性的做法。
    注:目前这种处理数据的方式几乎成了互联网的标配设计模式,最经典的例子是在用户下单的时候不需要真正地扣减库存,而是仅在前台计个数,然后通过异步任务在后台批量处理。

  • 4 CAP理论面试回答
    1)回答逻辑
    1> 先充分理解理论原理,不能仅浮在概念上(这一点需要你课下下功夫);
    2> 其次需要有自己的思考,表现出你思考能力的不同;
    3> 然后将理论结合于实践,讨论实际中处理问题时的思考逻辑。
    2)扩展
    知识体系、技术判断
    1> 分布式系统的理解
    分布式系统看起来就像一个计算机。计算机包括五大体系结构(即冯诺依曼结构),它有五大部件:分别是控制器、运算器、存储器、输入及输出。你可以这么理解:一个分布式系统也包含这五大部件,其中最重要的是计算与存储。计算与存储由一系列网络节点组成,每个节点之间的通信就是输入与输出,各节点之间的调度管理就是控制器。
    在这里插入图片描述

  • 5 例子:Redis 是否可以作为分布式锁
    解题思路:
    1)说明现实存在的问题
    一般使用 setnx 方法,通过 Redis 实现锁和超时时间来控制锁的失效时间。但是在极端的情况下,当 Reids 主节点挂掉,但锁还没有同步到从节点时,根据哨兵机制,从就变成了主,继续提供服务。这时,另外的线程可以再来请求锁,此时就会出现两个线程拿到了锁的情况。
    2)回归理论的指导
    根据对 CAP 理论的理解,Redis 的设计模型是 AP 模型,而分布式锁是一个 CP 场景,那么很明显,将 Redis 这种 AP 模型的架构应用于 CP 的场景,在底层的技术选型上就是错误的。
    3)扩展到知识体系
    Redis 属于分布式存储系统,你的头脑里就要有对分布式存储系统领域的知识体系。思考它的数据存储、数据分布、数据复制,以及数据一致性都是怎么做的,用了哪些技术来实现,为什么要做这样的技术或算法选型。你要学会从多维度、多角度去对比、分析同一分布式问题的不同方法,然后综合权衡各种方法的优缺点,最终形成自己的技术认知和技术判断力。
    4)有技术的判断力
    比如通过 Redis,你能想到目前分布式缓存系统的发展现状以及技术实现,如果让你造一个“Redis”出来,你会考虑哪些问题等。虽然在实际工作中不推荐重复“造轮子”,但在面试中要表现出自己具备“造轮子”的能力。
    在这里插入图片描述
    在这里插入图片描述

04 分布式系统原理问题-数据存储
  • 0 综述
    在这里插入图片描述

  • 1 常见问题
    –常见问题:
    如何设计一个支持海量商品存储的高扩展性架构?
    在做分库分表时,基于 Hash 取模和一致性 Hash 的数据分片是如何实现的?
    在电商大促时期,如何对热点商品数据做存储策略 ?
    强一致性和最终一致性的数据共识算法是如何实现的 ?
    –问题核心:在分布式系统中,核心的考察点包括了分布式系统中数据的存储、分布、复制,以及相关协议和算法。
    如“如何设计海量商品数据的存储?”

  • 2 分布式数据存储的问题
    分布式数据存储的问题可以分成:数据分片、数据复制,以及数据一致性带来的相关问题
    1)数据分片
    –背景:为了解决单台存储设备的局限性,会把数据分布到多台存储节点上,以此实现数据的水平扩展。
    –概念:数据分片即按照一定的规则将数据路由到相应的存储节点中,从而降低单存储节点带来的读写压力。
    –常见方案:Hash(哈希分片)与 Range(范围分片)。
    2)数据复制
    –数据复制:数据复制会产生副本,而副本是分布式存储系统解决高可用的唯一手段,这也是我们熟知的主从模式,又叫 master-slave。
    –作用:在分布式存储系统中,通常会设置数据副本的主从节点,当主节点出现故障时,从节点可以替代主节点提供服务,从而保证业务正常运行。
    3)数据一致性
    –解决:节点故障,完成从节点替代主节点。
    –数据一致性,通常要考虑一致性强弱(即强一致性和最终一致性的问题)。而要解决一致性的问题,则要进行一系列的一致性协议:如两阶段提交协议(Two-Phrase Commit,2PC)、Paxos 协议选举、Raft 协议、Gossip 协议。
    在这里插入图片描述

  • 3 存储策略-分片
    1)问题引入
    –问题:假设你是一家电商网站的架构师,现在要将原有单点上百 G 的商品做数据重构,存储到多个节点上,你会如何设计存储策略?
    –分析:因为是**商品存储扩容的设计问题,**很容易想到做数据的分库分表,也就是重新设计数据的分片规则,常用的分片策略有两种,即 Hash(哈希)分片和 Range(范围)分片。从这一点出发会考察你Hash(哈希)分片的具体实现原理。
    2)Hash分片
    –分片:商品表包括主键、商品 ID、商品名称、所属品类和上架时间等字段。如果以商品 ID 作为关键字进行分片,系统会通过一个 Hash 函数计算商品 ID 的 Hash 值,然后取模,就能得到对应的分片。模为 4 就表示系统一共有四个节点,每个节点作为一个分片。
    –例子:假设Hash 函数为 “商品 ID % 节点个数 4”,通过计算可以得到每个数据应该存入的节点:计算结果为 0 的数据存入节点 A;结果为 1 的数据存入节点 B;结果为 2 的数据存入节点 C;计算为 3 的数据存储节点 D。
    –优缺点:
    优点在于可以保证数据非常均匀地分布到多个分片上,并且实现起来简单,但扩展性很差,因为分片的计算方式就是直接用节点取模,节点数量变动,就需要重新计算 Hash,就会导致大规模数据迁移的工作。
    在这里插入图片描述
    3)一致性Hash
    –问题:如何解决 Hash 分片的缺点,既保证数据均匀分布,又保证扩展性?
    –一致性Hash:它是指将存储节点和数据都映射到一个首尾相连的哈希环上。存储节点一般可以根据 IP 地址进行 Hash 计算,数据的存储位置是从数据映射在环上的位置开始,依照顺时针方向所找到的第一个存储节点。
    –例子:在具体操作过程中,通常会选择带有虚拟节点的一致性 Hash。
    存储节点–假设在这个案例中将虚拟节点的数量设定为 10 个,就形成 10 个分片,而这 10 个分片构成了整个 Hash 空间。现在让 A 节点对应虚拟节点 0 ~ 3,B 节点对应虚拟节点 4 ~ 6,C 节点对应虚拟节点 7 ~ 8,D 节点对应虚拟节点 9。
    数据–同样根据哈希函数为 “商品 ID % 节点个数 10”得到每一个商品在 Hash 环上的位置,然后根据顺时针查找最近的存储节点,即数据实际映射的位置。计算结果为:0 ~ 3 的数据存入节点 A;结果为 4 ~ 6 的数据存入节点 B;结果为 7 ~ 8 的数据存入节点 C;计算为 9 的数据存储节点 D。
    在这里插入图片描述
    –新增:当我们新增一台服务器,即节点 E 时,受影响的数据仅仅是新服务器到所处环空间中前一台服务器(即沿着逆时针方向的第一台服务器)之间的数据。结合我们的示例,只有商品 100 和商品 101 从节点 A 被移动到节点 E,其他节点的数据保持不变。此后,节点 A 只存储 Hash 值为 2 和 3 的商品,节点 E 存储 Hash 值为 0 和 1 的商品。
    在这里插入图片描述
    –优缺点:一致性 Hash 分片的优点是数据可以较为均匀地分配到各节点,其并发写入性能表现也不错。
    (初级到此步不会追问)
    在这里插入图片描述
    –缺点:
    虽然一致性 Hash 提升了稳定性,使节点的加入和退出不会造成大规模的数据迁移,但本质上 Hash 分片是一种静态的分片方式,必须要提前设定分片的最大规模,而且无法避免单一热点问题, 某一数据被海量并发请求后,不论如何进行 Hash,数据也只能存在一个节点上,这势必会带来热点请求问题。比如案例中的电商商品,如果某些商品卖得非常火爆,通过 Hash 分片的方式很难针对热点商品做单独的架构设计。
    4)范围(Range)分片-分布式数据存储的理解
    –问题:解决单一热点问题?
    –Range(范围)分片:与 Hash 分片不同的是,Range 分片能结合业务逻辑规则。
    –例子:例如,我们用 “Category(商品类目)” 作为关键字进行分片时,不是以统一的商品一级类目为标准,而是可以按照一、二、三级类目进行灵活分片。例如,按业务品类分片,对于京东强势的 3C 品类,可以按照 3C 的三级品类设置分片;对于弱势品类,可以先按照一级品类进行分片,这样会让分片间的数据更加平衡。
    在这里插入图片描述
    要达到这种灵活性,前提是要有能力控制数据流向哪个分区,一个简单的实现方式是:预先设定主键的生成规则,根据规则进行数据的分片路由,但这种方式会侵入商品各条线主数据的业务规则,更好的方式是基于分片元数据(不过架构设计没有好坏,只有适合与否,所以在面试场景中,我建议你用擅长的解决方案来回答问题)。
    基于分片元数据的方式,就是调用端在操作数据的时候,先问一下分片元数据系统数据在哪,然后在根据得到的地址操作数据。元数据中存储的是数据分片信息,分片信息就是数据分布情况。在一个分布式存储系统中,承担数据调度功能的节点是分片元数据,当客户端收到请求后,会请求分片元数据服务,获取分片对应的实际节点地址,才能访问真正的数据。而请求分片元数据获取的信息也不仅仅只有数据分片信息,还包括数据量、读写 QPS 和分片副本的健康状态等。
    这种方式的灵活性在于分片规则不固定,易扩展,但是高灵活性就会带来高复杂性,从存储的角度看,元数据也是数据,特殊之处在于它类似一个路由表,每一次请求都要访问它,所以分片元数据本身就要做到高可用。如果系统支持动态分片,那么分片信息的变更数据还要在节点之间进行同步,这又带来
    多副本之间的一致性问题,以此延伸出如何保证分片元数据服务的可用性和数据一致性?

    在这里插入图片描述
    最直接的方式是专门给元数据做一个服务集群,并通过一致性算法复制数据。在实现方式上,就是将元数据服务的高可用和数据一致性问题转嫁给外围协调组件,如 ETCD 集群,这样既保证了系统的可靠,数据同步的成本又比较低。知道了设计思路,那具体的架构实现上怎么做 ?
    1 给分片元数据做集群服务,并通过 ETCD 存储数据分片信息。
    2 每个数据存储实例节点定时向元数据服务集群同步心跳和分片信息。
    3 当调用端的请求过来时,元数据服务节点只需要做好高可用和缓存即可。
    在这里插入图片描述
    给元数据分片:
    在这里插入图片描述

  • 4 共识算法
    如果面试官想挖掘你的能力,还会深入聊到共识算法,在一致性共识算法和最终一致性共识算法方面提出类似的问题,比如, ETCD 是如何解决数据共识问题的?为什么要选择这种数据复制方式呢?
    1)分布式系统中的一致性共识算法
    对于这类问题,你要从一致性算法原理层面解答,思路是:清楚 ETCD 的共识算法是什么,还有哪些常用的共识算法,以及为什么 ETCD 会做这样的选型。
    –问题:ETCD 的共识算法是基于 Raft 协议实现的强一致性算法,同类的强一致性算法还有 Paxos,在面试过程中,面试官很可能让你从自己的角度理解一下这两个算法,当然也会直接问:为什么没有选择 Paxos 而选择了 Raft ?这个问题对应聘高级研发的同学来讲很常见,主要考核你对以下内容的理解:
    Paxos 算法解决了什么问题?
    Basic Paxos 算法的工作流程是什么?
    Paxos 算法和 Raft 算法的区别又是什么?
    1> Paxos
    在分布式系统中,造成系统不可用的场景很多,比如服务器硬件损坏、网络数据丢包等问题,解决这些问题的根本思路是多副本,副本是分布式系统解决高可用的唯一手段,也就是主从模式,那么如何在保证一致性的前提下,提高系统的可用性,Paxos 就被用来解决这样的问题,而 Paxos 又分为 Basic Paxos 和 Multi Paxos,然而因为它们的实现复杂,工业界很少直接采用 Paxos 算法,所以 ETCD 选择了 Raft 算法 (在面试过程中,面试官容易在这里设置障碍,来对候选者做技术分层)。
    2> Raft
    Raft 是 Multi Paxos 的一种实现,是通过一切以领导者为准的方式,实现一系列值的共识,然而不是所有节点都能当选 Leader 领导者,Raft 算法对于 Leader 领导者的选举是有限制的,只有最全的日志节点才可以当选。正因为 ETCD 选择了 Raft,为工业界提供了可靠的工程参考,就有更多的工程实现选择基于 Raft,如 TiDB 就是基于 Raft 算法的优化。
    2)最终一致性算法
    如果把问题设计的极端一些,考察你对最终一致性算法的掌握,还可以有一种思路:分片元数据服务毕竟是一个中心化的设计思路,而且基于强一致性的共识机制还是可能存在性能的问题,有没有更好的架构思路呢?
    –可用性:既然要解决可用性的问题,根据 Base 理论,需要实现最终一致性,那么 Raft 算法就不适用了,因为 Raft 需要保证大多数节点正常运行后才能运行。这个时候,可以选择基于 Gossip 协议的实现方式。
    在这里插入图片描述
    –Gossip 的协议原理有一种传播机制叫谣言传播,指的是当一个节点有了新数据后,这个节点就变成了活跃状态,并周期性地向其他节点发送新数据,直到所有的节点都存储了该条数据。这种方式达成的数据一致性是 “最终一致性”,即执行数据更新操作后,经过一定的时间,集群内各个节点所存储的数据最终会达成一致,很适合动态变化的分布式系统。
    –从图中你可以看到,节点 A 向节点 B、C 发送新数据,节点 B 收到新数据后,变成了活跃节点,然后节点 B 向节点 C、D 发送新数据。
    在这里插入图片描述
    3)一致性共识算法做个总结
    到此,我们对一致性共识算法做个总结,共识算法的选择和数据副本数量的多少息息相关,如果副本少、参与共识的节点少,推荐采用广播方式,如 Paxos、Raft 等协议。如果副本多、参与共识的节点多,那就更适合采用 Gossip 这种最终一致性协议。
    在这里插入图片描述

  • 思考题
    在这里插入图片描述

  • 总结:
    本章:分布式技术下的数据分片、存储、复制与一致性的原理性问题
    在这里插入图片描述

05 分布式事务一致性
  • 1 分布式事务
    –背景:在互联网分布式场景中,原本一个系统被拆分成多个子系统,要想完成一次写入操作,你需要同时协调多个系统,这就带来了分布式事务的问题。
    –概念:分布式事务是指:一次大的操作由多个小操作组成,这些小的操作分布在不同的服务器上,分布式事务需要保证这些小操作要么全部成功,要么全部失败
    在这里插入图片描述
  • 2 系统简例
    –案例:以京东旅行系统为例,早期的交易系统是通过 .NET 实现的,所有的交易下单逻辑都写在一个独立的系统中。随着技术改造,我们用 Java 重写了核心系统,原本的系统也被拆分成多个子系统,如商品系统、促销系统、订单系统(为了方便理解,我只拿这三个系统举例)。当用户下单时,订单系统生成订单,商品系统扣减库存,促销系统扣减优惠券,只有当三个系统的事务都提交之后,才认为此次下单成功,否则失败。
    –解决:这是一个很典型的分布式事务问题,解决方案也很多,有两阶段提交协议(Two-Phase Commit,2PC)、3PC 、TCC 和基于消息队列的实现方式。在这里插入图片描述
  • 2 如何实现系统之间的分布式事务一致性?
    1)错误回答
    所以当很多候选者听到“怎么实现系统之间的分布式一致性?”的问题之后,会信心满满地选择一个方案,回答说:方案很多,可以选择 2PC ,2PC 实现的流程是……
    这种答题思路犯了一个很明显的错误,因为在实际工作中,很少采用前几种方案,**基本都是基于 MQ 的可靠消息投递的方式来实现。**所以一上来就说 2PC、3PC 或者 TCC 会让我觉得你并没有实际做过。
  • 5
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值