您当前的位置: 首页 >  分布式

TechGuide

暂无认证

  • 3浏览

    0关注

    176博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

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

TechGuide 发布时间:2020-11-12 01:55:57 ,浏览量:3

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

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

文章目录
  • 前言
  • 正文
    • 1.负载均衡如何实现,有哪几种方式
    • 2.谈谈你对微服务的理解
    • 3.SOA和微服务的区别
    • 4.CAP理论和BASE定理
    • 5.分布式系统需要考虑哪些问题
    • 6.分布式系统如何实现数据一致性
    • 7.如何实现分布式锁
    • 8.手写限流算法(后续)
    • 9.你的系统你会从哪些方面考虑去优化(查19问)
    • 10.你的服务挂了怎么处理
    • 11.分布式ID生成策略
    • 12. 一致性算法(2/3pc, paxos, Raft, ZAB)
  • 补充:文章推荐
    • 淘宝架构演进
    • 拓展:CDN加速 - 高并发神器

前言

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

正文 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
关注
打赏
1665329535
查看更多评论
0.0377s