分布式理论知识点全梳理(纯干货、新手向)

备战秋招面试,微信搜索公众号【TechGuide】关注更多新鲜好文和互联网大厂的笔经面经。
作者@TechGuide【全网同名】
点赞再看,养成习惯,您动动手指对原创作者意义非凡🤝

当你的才华还撑不起你的野心时,你应该静下心去学习 。🤝点赞再看,养成习惯🤝

前言

分布式理论涵盖分布式系统设计模块、算法和微服务相关的理论知识。文章结尾推荐了一篇近期看到的一篇关于淘宝架构演进的文章,学习到一定程度再从全局看一下分布式架构的整体,有一种豁然开朗的感觉(当然肯定还有很多不足之处哈哈),分享给大家。

正文

1.负载均衡如何实现,有哪几种方式

负载均衡方式:

  1. 重定向(redirect)

这种方式,是通过将请求全部发送到前置机,由前置机通过算法得出要分配给哪台应用服务器,然后响应给客户端,由客户端重定向到应用服务器的一种方式。由于每一个请求,都要重定向一下,所以效率不是很高。

  1. 反向代理(转发forward)

这种方式,是通过在前置机,使用反向代理的方式,将请求分发到应用服务器,客户端无需再请求一次,实现方式通常有两种,一种是用交换机实现,还有一种是用nginx这一类的软件实现。由于不需要再次重定向,所以较第一种,效率较高,但是由于请求和响应都是通过前置机来的,所以对前置机的考验很大

  1. 数据链路返回

这种方式,通过给应用服务器设置虚拟IP,然后通过修改mac地址的方式,将请求分发出去,而应用服务器收到请求后,可以直接响应给客户端,而不需要经过前置机。由于前置机只需要接受请求,不需要响应数据,所以,效率较第二种较高。

负载均衡算法:

  1. 轮询法

将请求按顺序轮流地分配到后端服务器上,它均衡地对待后端的每一台服务器,而不关心服务器实际的连接数和当前的系统负载。

  1. 随机法

通过系统的随机算法,根据后端服务器的列表大小值来随机选取其中的一台服务器进行访问。由概率统计理论可以得知,随着客户端调用服务端的次数增多,其实际效果越来越接近于平均分配调用量到后端的每一台服务器,也就是轮询的结果。

  1. 源地址哈希法

源地址哈希的思想是根据获取客户端的IP地址,通过哈希函数计算得到的一个数值,用该数值对服务器列表的大小进行取模运算,得到的结果便是客户端要访问服务器的序号。采用源地址哈希法进行负载均衡,同一IP地址的客户端,当后端服务器列表不变时,它每次都会映射到同一台后端服务器进行访问。

  1. 加权轮询法

不同的后端服务器可能机器的配置和当前系统的负载并不相同,因此它们的抗压能力也不相同。给配置高、负载低的机器配置更高的权重,让其处理更多的请;而配置低、负载高的机器,给其分配较低的权重,降低其系统负载,加权轮询能很好地处理这一问题,并将请求顺序且按照权重分配到后端。

  1. 加权随机法

与加权轮询法一样,加权随机法也根据后端机器的配置,系统的负载分配不同的权重。不同的是,它是按照权重随机请求后端服务器,而非顺序。

  1. 最小连接数法

最小连接数算法比较灵活和智能,由于后端服务器的配置不尽相同,对于请求的处理有快有慢,它是根据后端服务器当前的连接情况,动态地选取其中当前积压连接数最少的一台服务器来处理当前的请求,尽可能地提高后端服务的利用效率,将负责合理地分流到每一台服务器。

2.谈谈你对微服务的理解

引用微服务之父,马丁.福勒的话,此为译文:

就目前而言,对于微服务业界并没有一个统一的、标准的定义(While there is no precise definition of this architectural style ) 。
但通常来说,微服务架构是一种架构模式或者说是一种架构风格,它提倡将单一应用程序划分成一组小的服务,每个服务运行独立的自己的进程中,服务之间互相协调、互相配合,为用户提供最终价值。
服务之间采用轻量级的通信机制互相沟通(通常是基于 HTTP 的 RESTful API ) 。每个服务都围绕着具体业务进行构建,并且能够被独立地部署到生产环境、类生产环境等。
另外,应尽量避免统一的、集中式的服务管理机制,对具体的一个服务而言,应根据业务上下文,选择合适的语言、工具对其进行构建,可以有一个非常轻量级的集中式管理来协调这些服务。可以使用不同的语言来编写服务,也可以使用不同的数据存储。

3.SOA和微服务的区别

SOA(Service Oriented Architecture)与微服务的区别在于如下几个方面:

  1. 微服务相比于SOA更加精细,微服务更多的以独立的进程的方式存在,互相之间并无影响;

  2. 微服务提供的接口方式更加通用化,例如HTTP RESTful方式,各种终端都可以调用,无关语言、平台限制;

  3. 微服务更倾向于分布式去中心化的部署方式,在互联网业务场景下更适合。

4.CAP理论和BASE定理

CAP:要满足分区容错性的分布式系统,只能在一致性和可用性两者中,选择其中一个。

在这里插入图片描述

BASE(basically available, soft state, eventually consistent)是对CAP定理的延伸,是对CAP中一致性和可用性权衡的结果,其来源于对大规模互联网系统分布式实践的结论,是基于CAP定理逐步演化而来的。其核心思想是即使无法做到强一致性(Strong consistency),但每个应用都可以根据自身的业务特点,采用适当的方式来使系统达到最终一致性(Eventual consistency)。【拓展

(1)基本可用:出现故障的时候,允许损失部分可用性,即,保证核心可用。如电商大促时,为了应对访问量激增,部分用户可能会被引导到降级页面,服务层也可能只提供降级服务

(2)软状态:允许系统存在中间状态,而该中间状态不会影响系统整体可用性。
软状态本质上是一种弱一致性,允许的软状态不能违背“基本可用”的要求。如,分布式存储中一般一份数据至少会有三个副本,允许不同节点间副本同步的延时(某些时刻副本数低于3)。

(3)最终一致性:系统中的所有数据副本经过一定时间后,最终能够达到一致的状态。软状态的终极目标是最终一致性。如,分布式存储的副本数最终会达到稳定状态。

5.分布式系统需要考虑哪些问题

  1. 如何将系统拆分成多个子系统
  2. 如何规划子系统的通信问题
  3. 如何实现通信过程中的安全
  4. 如何才能实现子系统的可扩展性
  5. 如何保证子系统的可靠性
  6. 如何实现数据的一致性

6.分布式系统如何实现数据一致性

幂等性
对于同一个系统,在同样条件下,一次请求和重复多次请求对资源的影响是一致的,就称该操作为幂等的。
就是用户对于同一操作发起的一次请求或者多次请求的结果是一致的,不会因为多次点击而产生了副作用。举个最简单的例子,那就是支付,用户购买商品使用支付,支付扣款成功,但是返回结果的时候网络异常,此时钱已经扣了,用户再次点击按钮,此时会进行第二次扣款,返回结果成功,用户查询余额发现多扣钱了,流水记录也变成了两条,这种情况就是不幂等的。

  1. 强一致性

当更新操作完成之后,任何多个后续进程或者线程的访问都会返回最新的更新过的值。这种是对用户最友好的,就是用户上一次写什么,下一次就保证能读到什么。根据 CAP 理论,这种实现需要牺牲可用性。

  1. 弱一致性

系统并不保证后续进程或者线程的访问都会返回最新的更新过的值。系统在数据写入成功之后,不承诺立即可以读到最新写入的值,也不会具体的承诺多久之后可以读到。

  1. 最终一致性

弱一致性的特定形式。系统保证在没有后续更新的前提下,系统最终返回上一次更新操作的值。在没有故障发生的前提下,不一致窗口的时间主要受通信延迟,系统负载和复制副本的个数影响。DNS 是一个典型的最终一致性系统。

解决一致性问题的经典思路:

此方案的核心是将需要分布式处理的任务通过消息日志的方式来异步执行。消息日志可以存储到本地文本、数据库或消息队列,再通过业务规则自动或人工发起重试。人工重试更多的是应用于支付场景,通过对账系统对事后问题的处理。

消息日志方案的核心是保证服务接口的幂等性。

BASE 的可用性是通过支持局部故障而不是系统全局故障来实现的。

如果产生了一笔交易,需要在交易表增加记录,同时还要修改用户表的金额。这两个表属于不同的远程服务,所以就涉及到分布式事务一致性的问题。

eBay提出了一个经典的解决方法,将主要修改操作以及更新用户表金额的消息放在一个本地事务来完成。同时为了避免重复消费用户表消息带来的问题,达到多次重试的幂等性,增加一个更新记录表 updates_applied 来记录已经处理过的消息。

第一阶段,通过本地的数据库的事务保障,增加了 transaction 表及消息队列 。
第二阶段,分别读出消息队列(但不删除),通过判断更新记录表 updates_applied 来检测相关记录是否被执行,未被执行的记录会修改 user 表,然后增加一条操作记录到 updates_applied,事务执行成功之后再删除队列。

通过以上方法,达到了分布式系统的最终一致性。【拓展

7.如何实现分布式锁

  1. MySql
  2. Zk
  3. Redis

基于数据库的分布式锁, 常用的一种方式是使用表的唯一约束特性。当往数据库中成功插入一条数据时, 代表获取到锁。将这条数据从数据库中删除,则释放锁。

在这里插入图片描述
拓展

8.手写限流算法(后续)

9.你的系统你会从哪些方面考虑去优化(查19问)

10.你的服务挂了怎么处理

思考:什么原因造成的?比如请求量过大造成的:
可用方法:缓存、服务降级、限流。

缓存,就是用内存来顶替一部分DB的查询+数据的处理。这应该是所有业务开发人员的必修课。业务上大致可以把缓存分为三类:浏览器缓存(HTTP Cache-Control Header),CDN服务器业务缓存。而业务缓存根据实现的结构可以分多个层级,可以用in-memory cache (如Guava Cache),或者是分布式共享Cache(如Redis)。在设计缓存一致性更新模式时,无非就是Cache Aside、Read/Write Through和Write Behind这三大种模式。有些超级NB的缓存系统自带Cluster加持(比如Ehcache即可单机用,也可以组集群)。

留意下这里说的缓存仅仅是利用了内存访问比磁盘访问快得多的特性(大概可以理解为2~3个数量级),并不会让用户感知到数据一致性哪里不对劲(与下面的降级不同)。

服务降级,是指通过降低服务质量的方法,达到节省资源的目的。简单来说就是弃车保帅。比如你的服务有ABC,平时消耗差不多的资源。突发事件时,A的请求量极大的增高了,B和C没有变化。那么可以比如减少或者暂停B和C的服务,省出资源给A用。

再比如,一个热点新闻的业务,有新闻内容,有评论,有点赞数等等。一旦新闻热点了,就可以把所有这些内容静态化,不必再查DB。这时虽然评论,点赞的数暂时就不准了,但是主要的服务——内容,还是让用户可以看到。这就足够了。

可以看到,降级的具体的方案,要结合业务和系统实现来综合设计,并没有定法。

降级很多时候也会用到缓存。只不过这时候使用缓存的方法就可能会以牺牲数据一致性为代价——内存里的数据和DB不一样,就不一样吧,业务上可接受,并且这段热点时间段过去了,能够恢复为一致就可以。

限流,即限制用户的请求流量。具体的做法有计数器、滑动窗口、滴漏、服务token、请求队列化等办法。这些方法的详细解释,在这里都说得比较清楚,所以我就不重复了。只是值得注意的是,现在很多生产级别的服务都是多节点分布式架构。很多单机上容易做的算法和控制逻辑到了分布式下就会带来一些实现上的麻烦。这又涉及到了分布式一致性、CAP的权衡等等问题。【拓展

11.分布式ID生成策略

数据库分库分表后需要有一个唯一ID来标识一条数据,数据库的自增ID显然不能满足需求;特别一点的如订单、优惠券也都需要有唯一ID做标识。此时一个能够生成全局唯一ID的系统是非常必要的。那么这个全局唯一ID就叫分布式ID

序号ID生成器描述优缺点
1UUIDUUID.randomUUID().toString()字符串没有意义;用作业务主键ID太长,存储性能差、查询耗时
2数据库自增ID单点单点故障;不适合高并发
3数据库多主模式集群设置步长、不利于后续扩容
4号段模式从数据库批量的获取自增ID,每次从数据库取出一个号段范围,对数据库的压力小改进单点
5Redisincr命令实现ID的原子性自增高并发
6雪花算法(SnowFlake)指定机器 & 同一时刻 & 某一并发序列,是唯一的。-
7百度 (Uidgenerator支持自定义时间戳、工作机器ID和 序列号等各部分的位数-
8美团(Leaf)同时支持号段模式和snowflake算法模式,可以切换使用。-

雪花算法
在这里插入图片描述
Snowflake生成的是Long类型的ID,一个Long类型占8个字节,每个字节占8比特,也就是说一个Long类型占64个比特。

比特位描述
第一个bit位(1bit)Java中long的最高位是符号位代表正负,正数是0,负数是1,一般生成ID都为正数,所以默认为0。
时间戳部分(41bit)毫秒级的时间,不建议存当前时间戳,而是用(当前时间戳 - 固定开始时间戳)的差值,可以使产生的ID从更小的值开始;41位的时间戳可以使用69年,(1L << 41) / (1000L * 60 * 60 * 24 * 365) = 69年
工作机器id(10bit)也被叫做workId,这个可以灵活配置,机房或者机器号组合都可以。
序列号部分(12bit)自增值支持同一毫秒内同一个节点可以生成4096个ID

如何解决时钟回拨问题?

时钟倒回或者闪跳造成重复ID,可以有两种解决方法:

  1. 等待curTime-lastTime的时间,之后重启后看是否同步上。
  2. 机器ID分片,利用冗余机器为故障机器备份。

详解

12. 一致性算法(2/3pc, paxos, Raft, ZAB)

在这里插入图片描述

补充
在 DNS 协议中,域名每个解析记录都有 TTL(Time to live) 属性,当我们用浏览器访问网站时,首先查看这个域名在本地的缓存,若最后更新的时间距离现在没有超过 TTL,则直接使用,否则去 DNS server上获取该域名的IP。所以我们在 Name Server 上修改某条记录后,不会立刻扩散(同步)到所有的缓存服务器上,而是由各个层级的服务器根据自己的缓存判断是否过期,若过期才去同步数据。最终 的含义就在于此,由此可见如果修改一条 DNS 解析记录,最长可能要等待一个 TTL 周期才能获取最新数据,同样如果你用的 DNS 服务器如果已经有人尝试更新,服务器就不需要再次去 Name Server 更新数据了。这种分布式方式通过层层缓存大大降低了 Name Server 的负载。当然代价是一定时间更新延迟,但达到了最终一致性。

在这里插入图片描述

state machine replication: 通过记录log来保存操作的路径流程。

零、2PC (两阶段提交)协议:

两阶段:propose 》 commit
两阶段:propose 》barrier 》 commit

参考

一、主从复制

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
二、Basic Paxos

关键词:proposer、acceptor、编号、多数

在这里插入图片描述
在这里插入图片描述

这里的Quorum一般是指多数派,但是你也可以设置成其他比例。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
(以上问题可以由多个Proposer保证可用性)-----》multi Paxos

在这里插入图片描述
活锁:proposer不断提交议案,并且编号不断增加,则acceptor就一直不能成功决议,谓之活锁。解决办法是设置timeout再重新提交。

在这里插入图片描述
三、Multi Paxos (选老大)

只有唯一一个proposer选leader。

在这里插入图片描述
N号老大提出第I号内容为Vm的提案,则议员必须接受。(只有一次RPC,除了第一次选老大两次RPC)

在这里插入图片描述
简化角色(servers中选一个老大(上图中proposer和acceptor合并))

四、Raft算法(paxos简化版)

关键词:leader、follower、heartbeat、log replication、 timeout、 term(第几任leader)

在这里插入图片描述
以下讲解log replication:同步log到其他节点上。【详解】【动画演示
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
以上演示了写请求的全部过程,大致可以分成两个步骤:

  1. 开始时,大家都是follower,直到其中一个要选leader,请求其他followers选自己。
  2. 之后所有的(写)请求会由leader接收,leader节点会将日志同步复制到其他follower节点,但并不提交。
  3. 如果quorum都写入了这条log,则leader先自己commit这条log,之后通知followers我已提交,则followers也会提交日志。

以上过程即为选举和日志拷贝的过程。

如何保证leader election呢?

election timeout
在这里插入图片描述
来自leader的心跳周期发送给follower,follower超过随机事件timeout未收到心跳则认为无leader。第一个timeout到期的节点会先投票给自己,之后发送投票请求给其他follower,如果接收到请求的follower还未投票就会投票给他,之后超过半数票即成为leader。注意,数据也包含在心跳包中。

总结一下,timeout分两种,一种是follower变candidate的时间,比如两个candidates同时选leader时,随机事件后在变candidate重新选;另一种是如上描述的心跳周期。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
指的是两个节点同时到期,并选举自己,咋办?他们再等待随机事件后再发请求。
在这里插入图片描述
如下脑裂情况如何保证一致性呢?
在这里插入图片描述
一般来说,节点总数一般为奇数个,这样任意分割总有一个集群超半数,比如上图中的上半部分和下半部分,下集群小于半数,所以任何改动都不会提交。patition恢复时,term更低的leader会自动退出(感觉这个部分还是会有点问题,如果分出去的是少数部分且leader任期更高的话?)

以上截图来源:Raft

五、ZAB算法
在这里插入图片描述
六、Gossip算法

Gossip算法每个节点都是对等的,即没有角色之分。Gossip算法中的每个节点都会将数据改动告诉其他节点,节点收到数据改动,又会再次将改动传播给其他4个节点。

补充:文章推荐

淘宝架构演进

《服务端高并发分布式架构演进之路》

关键词:分布式 负载均衡 缓存 数据库 集群 CDN

在这里插入图片描述

在这里插入图片描述

拓展:CDN加速 - 高并发神器

内容分发网络(Content Delivery Network,简称CDN)是建立并覆盖在承载网之上,由分布在不同区域的边缘节点服务器群(缓存节点)组成的分布式网络。
在这里插入图片描述

假设通过CDN加速的域名为www.a.com,接入CDN网络,开始使用加速服务后,当终端用户(北京)发起HTTP请求时,处理流程如下:

  1. 当终端用户(北京)向www.a.com下的指定资源发起请求时,首先向LDNS(本地DNS)发起域名解析请求。
  2. LDNS检查缓存中是否有www.a.com的IP地址记录。如果有,则直接返回给终端用户;如果没有,则向授权DNS查询。
  3. 当授权DNS解析www.a.com时,返回域名CNAME www.a.tbcdn.com对应IP地址。
  4. 域名解析请求发送至阿里云DNS调度系统,并为请求分配最佳节点IP地址。
  5. LDNS获取DNS返回的解析IP地址。用户获取解析IP地址。
  6. 用户向获取的IP地址发起对该资源的访问请求。如果该IP地址对应的节点已缓存该资源,则会将数据直接返回给用户,例如,图中步骤7和8,请求结束。
  7. 如果该IP地址对应的节点未缓存该资源,则节点向源站发起对该资源的请求。获取资源后,结合用户自定义配置的缓存策略,将资源缓存至节点,例如,图中的北京节点,并返回给用户,请求结束。【关于淘宝商品图片加载过程
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

TechGuide

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值