分布式面试

  1. 什么是分布式系统?

    1. 分布式系统就是将一个业务拆分成多个子业务,部署在不同的服务器上,然后通过一定的通信协议,让这些子业务之间相互通信。
  2. 分布式的优缺点

    1. 优点:能提供更强的计算、存储能力,避免单点故障等问题。
    2. 存在的问题:由于采用分布式部署的方式,可能经常出现网络故障等问题,并且如何在分布式系统中保证数据的一致性和可用性也是一个关键问题。
    3. 比如在集中式系统中,一些关键的配置信息可以直接保存在服务器内存中,但在分布式系统中,如何保存这些配置信息,如何保证修改一个配置能够把这次修改同步到所有机器中,又如何保证所有机器上的配置信息都保持一致呢?
    4. 再比如,在集中式系统中,进行一个同步操作要写同一个数据的时候,可以直接使用事务+锁来管理保证数据的ACID。但是,在分布式系统中如何保证多台机器不会同时写同一条数据呢?
  3. 怎么用Redis实现分布式锁?

    1. 场景由来:(上述d)多台机器请求修改同一份数据,如何保证顺序性和正确性?
    2. 本地锁和分布式锁:多个线程想修改同一份数据,可以通过synchronized等字段锁住对应的数据,但在分布式环境下synchronized就不起作用了
    3. 分布式锁应该具备什么特点
      1. 互斥性:在任何时刻,只有一个客户端持有锁。
      2. 可重入:持有锁的客户端可以再次加锁成功。
      3. 不能出现死锁:一个客户端持有了锁,但在持有期间挂了,没有释放锁,那其他客户端就永远不能获取锁。
      4. 保证上锁和解锁的是同一个客户端。
    4. 核心思想:设置一个通用的key值,如果要获得锁,就尝试对这个key进行set操作。
    5. 如何实现互斥性
      1. 使用set(之前是setnx set if not exist)命令,如果key不存在,会设置value并返回true,代表加锁成功;如果key存在,会返回false,代表加锁失败。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2VZ73I0g-1660877557345)(https://tg0wj72d15.feishu.cn/space/api/box/stream/download/asynccode/?code=MjVlOTk5Njg3NTUzNGVjMzRhOGY4NjBjODlkODA2OWVfMWJrZk92QlAwMnQ4WXBKQWFtTDhmVEdBSG13SU54WlZfVG9rZW46Ym94Y25tdzVlS1NrT0RlZTBIa2duUHV1YkliXzE2NjA4Nzc0Nzg6MTY2MDg4MTA3OF9WNA)]

  1. 如何解决死锁问题
    1. 在对key进行set操作时同时设置key的过期时间(set和设置过期时间要保证是原子的),过期时间一到就会失效,相当于释放了锁

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0uEcKYci-1660877557346)(https://tg0wj72d15.feishu.cn/space/api/box/stream/download/asynccode/?code=YzYzNTY0MzNjOTdhYTdjOWJhZTA4YTM5YjQwMGY5YzhfcFNKN3BzSlNyQlc0NWdDY0tiOGhuMldHYVc1VkppTVdfVG9rZW46Ym94Y242eWdtS3JtZEtiVFJWSk0ycGpxU2ljXzE2NjA4Nzc0Nzg6MTY2MDg4MTA3OF9WNA)]

  1. 引发了一个问题:如果A还没执行完,过期时间就到了,自动释放了锁,该怎么办?

    1. 将过期时间设置得长一些,但这个时间难以预估(可能会因为网络抖动、阻塞等问题延长执行时间)

    2. 使用

      守护线程

      每隔一段时间给锁续期,直到执行完毕主动释放锁

      1. 工作机制:当加锁成功后,同时开启守护线程,每隔一段时间给锁续期到它指定的过期时间,只要持有锁的客户端没有宕机,就能保证一直持有锁,直到业务代码执行完毕由客户端自己解锁;如果宕机了就会在有效期后自动解锁。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8rxAqSe0-1660877557346)(https://tg0wj72d15.feishu.cn/space/api/box/stream/download/asynccode/?code=MjkxMTNhNDZjNjEzMmQ2YWMyODJhZjdlMjQzMzI5NzhfRndsQW1WWkZDZ200MElwR1pXdE1FcDREV3I1c3poZnVfVG9rZW46Ym94Y25ITHNpZ2JuTTNHRnNmMjEzaVVHdTdnXzE2NjA4Nzc0Nzg6MTY2MDg4MTA3OF9WNA)]

  1. 可重入实现
    1. 从设置的value值入手,set的时候在value中添加属于当前客户端的唯一标识,再次请求加锁时,先get这个value是不是和自己的一致,如果一致,加锁成功,可重入次数+1;不一致说明其他客户端获得了锁,加锁失败。
    2. 解锁

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zscsXL59-1660877557346)(https://tg0wj72d15.feishu.cn/space/api/box/stream/download/asynccode/?code=NGU2ODc3ZTYyMWY1YzNkYzk2YzgxYzk0NWM0MTQ2NmVfcllzdzZodEVhTGpaQmtBTXpCQ3cyWmQ0RldmS1ZLbW1fVG9rZW46Ym94Y25TUWJQZ2JiN1lrbzl1alVjOVgyS0llXzE2NjA4Nzc0Nzg6MTY2MDg4MTA3OF9WNA)]

  1. 加锁失败的客户端是怎么等待再次获得锁的
    1. 采用发布订阅机制
    2. 加锁失败后,订阅锁释放的消息,自身进入阻塞状态;
    3. 当持有锁的客户端释放锁时,发布锁释放的消息;
    4. 在阻塞等待的客户端收到锁释放的消息后,解除阻塞等待状态,再次尝试加锁。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ErkDBEEG-1660877557347)(https://tg0wj72d15.feishu.cn/space/api/box/stream/download/asynccode/?code=Y2NkMzg4NjIxNTZiYTFkYzczZWNmYTQwM2IyMDQwNjRfSWRaOEU2ckZBdElYMlhnYlN6OFBwSWlzUmpkZXp2Q0pfVG9rZW46Ym94Y25XOXVmclBuYnU1UUoxcW1sOWIwYjNiXzE2NjA4Nzc0Nzg6MTY2MDg4MTA3OF9WNA)]

  1. 集群模式下,主服务器宕机了,但现在从服务器还没有同步锁的状态,故障转移又将从服务器升级为主服务器,锁状态丢失了怎么办?—使用redlock

    1. 部署至少5个主服务器(不需要部署从服务器和哨兵)
    2. 工作机制
      1. 客户端依次请求这5个主服务器,申请加锁;(每个请求会设置一个超时时间(远小于要设置的锁的过期时间),如果超时就立即向下一个redis主服务器申请加锁)
      2. 如果大多数(>3个)服务器都加锁成功了,而且请求获取锁消耗的总时间小于锁过期的时间(保证加锁成功的服务器上的锁都是有效的),则认为加锁成功
      3. 如果加锁失败,就向所有节点发起释放锁的请求(因为可能存在因为网络延时等问题超时了,其实已经加锁成功了,这时也要释放锁)
  2. https://www.zhihu.com/question/300767410/answer/1749442787

  3. MySQL实现分布式锁

    1. 原理:使用唯一索引来实现,获得锁时向表中插入一条数据,释放锁时删除这条数据。唯一索引可以保证这条数据只被插入一次,可以根据这个数据是否存在来判断是否处于锁定状态。
    2. 存在问题
      1. 锁没有失效时间,解锁失败的话其他进程无法再获得这个锁;
      2. 不可重入;
      3. 只能是非阻塞锁,插入失败就直接报错了,无法重试。
  4. Zookeeper分布式协调组件

    1. zookeeper=文件系统+监听通知机制
  5. zookeeper数据结构

    1. zookeeper维护一个类似文件系统的数据结构,将所有数据存储在内存中。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rywpIjgS-1660877557347)(https://tg0wj72d15.feishu.cn/space/api/box/stream/download/asynccode/?code=OWRjNDNiNGE0MjY1YmI0MjdhMDYyZGE5MmZkMDQ3NDBfQklrMUNteUVPeG51UE9hakVKcTlhOWh6YTR1WFk4dVlfVG9rZW46Ym94Y25RT0pNSUdvZDc0Q2dpeUphUHBjZUdHXzE2NjA4Nzc0Nzg6MTY2MDg4MTA3OF9WNA)]

  1. 节点

    1. 概念:每个子目录如NameService都被称为znode(目录节点),每个znode都会保存自己的数据内容和一系列属性信息。和文件系统一样,我们能够自由的增加、删除znode,在一个znode下增加、删除子znode。
    2. 类型:
      1. 持久节点:一旦这个znode被创建了,除非主动删除,否则这个znode将一直保存在zookeeper上。
      2. 临时节点:它的生命周期和客户端会话绑定,一旦客户端会话结束,那这个客户端创建的所有临时节点都会被删除。
    3. 有序节点:在节点名后面加一个数字后缀,这个数字是由父节点维护的自增数字。例如生成的有序节点为 /lock/node-0000000000,它的下一个有序节点则为 /lock/node-0000000001,以此类推。
  2. zookeeper重要概念

    1. 会话session
      1. zookeeper服务器与客户端会话(TCP长连接)。
      2. 通过这个连接,客户端能够通过心跳检测与服务器保持有效的会话,也能够向zookeeper服务器发送请求并接受响应,同时还能够通过该连接接收来自服务器的watch事件通知。
      3. 可以通过sessionTimeOut值来设置一个客户端会话的超时时间。当由于服务器压力太大、网络故障或客户端主动断开连接等各种原因导致客户端连接断开时,只要在sessionTimeOut规定的时间内能够重新连接上集群中任意一台服务器,那么之前创建的会话仍然有效。
      4. zookeeper会为每个客户端都分配一个sessionID,而且要保证全局唯一。
    2. 版本
      1. 每个 ZNode,Zookeeper 都会为其维护一个叫作 Stat 的数据结构。
      2. Stat 中记录了这个 ZNode 的三个数据版本,分别是:
        1. version(当前 ZNode 的版本)
        2. cversion(当前 ZNode 子节点的版本)
        3. aversion(当前 ZNode 的 ACL 版本)
    3. watcher(事件监听器)
      1. zookeeper允许用户在指定节点上注册一个监听器,在节点状态发生改变时,zookeeper服务端将事件通知到感兴趣的客户端上。
    4. ACL(AccessControlLists)

zookeeper采用ACL策略来进行权限控制。

  1. zookeeper特点

    1. 顺序一致性:从客户端发起的事务请求,最终将会严格地按照顺序被应用到zookeeper中。
      1. 是怎么保障顺序一致性的?—顺序访问
        1. 对于来自客户端的每个更新请求,zookeeper都会分配一个全局唯一的递增编号。这个编号反应了所有事务操作的先后顺序,应用程序可以使用zookeeper这个特性来实现更高层次的同步原语。这个编号也叫做时间戳。
    2. 原子性:所有事务请求的处理结果在整个集群中所有机器上的应用情况是一致的,也就是说,要么整个集群中所有的机器都成功应用了某一个事务,要么都没有应用。
    3. 单一系统映像:无论客户端连到哪一个zookeeper服务器上,其看到的服务端数据模型都是一致的。
    4. 可靠性(持久性):一旦一次更改请求被应用,更改的结果就会被持久化,直到被下一次更改覆盖。
  2. zookeeper集群

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EQzyVgzS-1660877557347)(https://tg0wj72d15.feishu.cn/space/api/box/stream/download/asynccode/?code=ZWFhMDI2Nzk3NWNiYmM2ZWZmZTFmMzRjZmYzN2MzMjdfR1V4b1FiNjFPcUVwRDNXamNSUktIOXViem5TdEdtTnRfVG9rZW46Ym94Y24xenFVWXVNMnprQllhbWNJR2h2OEliXzE2NjA4Nzc0Nzg6MTY2MDg4MTA3OF9WNA)]

  1. 每一个 Server 代表一个安装 ZooKeeper 服务的服务器。组成 ZooKeeper 服务的服务器都会在内存中维护当前的服务器状态,并且每台服务器之间都互相保持着通信。
  2. leader领导者:zookeeper集群中的所有机器通过leader选举过程来选定leader服务器。负责进行投票的发起和决议,更新系统状态。(读+写)
  3. follower和observer都只能提供读服务。但observer不参与leader的选举过程,也不参与写操作的“过半写成功”策略。因此observer机器可以在不影响写性能的情况下提升集群的读性能。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-W8bxRL3O-1660877557347)(https://tg0wj72d15.feishu.cn/space/api/box/stream/download/asynccode/?code=ZDYxZWE5OGZjN2RlYzljM2MxOTY2YWQ2NGM4MWNhNDlfd1ZSZERkaWZya09wYzNXREpCNEJuaXlwVkZGcEd5blJfVG9rZW46Ym94Y250aDhKMGd3WHRLdE84QU05N21lSnA1XzE2NjA4Nzc0Nzg6MTY2MDg4MTA3OF9WNA)]

  1. zookeeper应用

    1. zookeeper底层其实只提供了两个功能:管理(存储)用户程序提交的数据;为用户程序提供数据节点监听服务—客户端注册它关心的节点,当节点发生变化,比如数据改变、被删除、子节点增加或删除时,zookeeper会通知客户端进行之后的处理。
    2. 应用:分布式应用配置管理、统一命名服务、状态同步服务、集群管理等功能。(后来开发人员基于zookeeper的特点,实现了各种功能)
    3. 分布式应用配置管理
      1. 解决的问题:假设我们的程序部署在多台机器上,如果我们要改变程序的配置文件,需要逐台机器进行修改,非常麻烦。
      2. 如何实现:把这些配置保存在zookeeper的某个节点中,所有相关的应用程序都监听这个节点。一旦配置发生改变,所有的应用程序都会收到zookeeper的通知,从zookeeper获取新的配置信息。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-B3zl8fMS-1660877557348)(https://tg0wj72d15.feishu.cn/space/api/box/stream/download/asynccode/?code=MzYwNTY2ZjhhNGIzNjRjY2MyNmFkYzE1YmFiMzgyNmJfc1lPS004TEdzYnpNT1NEa3dLUzhJNEY2bUt0UkQyT0lfVG9rZW46Ym94Y25GdmdHMXRPUjBUVlRhT1R4dUs1MlNlXzE2NjA4Nzc0Nzg6MTY2MDg4MTA3OF9WNA)]

  1. 服务提供者和服务消费者的注册中心(dubbo)

    1. 服务提供者将自己提供的服务注册到zookeeper中,包括自己的实例名、ip、端口、方法名等,服务的消费者在进行服务调用时先到zookeeper中查找服务,获取到服务提供者的详细信息之后,再去调用服务提供者的内容和数据。一旦服务提供者宕机了,它所建立的临时节点也会消失,因此也不会有它的注册信息。
  2. 命名管理

    1. 类似域名管理:如果应用中需要服务和IP的映射关系的配置,也可以统一集中管理。
  3. 分布式锁(临时节点+有序节点)

    1. 创建一个锁目录/lock;
    2. 当一个客户端需要获取锁时,在/lock下创建临时且有序的子节点;
    3. 然后判断自己创建的子节点是否是当前子节点中序号最小的,如果是则获得锁;如果不是,说明已有其他客户端获取了锁,因此监听自己的前一个子节点,前一个子节点变更后再次尝试获取锁。
    4. 获得锁后执行业务代码,完成后删除对应的子节点。
    5. 如果会话超时,因为创建的是临时节点,所以该会话对应的临时节点会被删除,相当于释放了锁。
    6. 把 ZooKeeper 上的一个 Znode 看作是一把锁,通过 create znode的方式来实现。所有客户端都去创建 /distribute_lock 节点,最终成功创建的那个客户端就拥有了这把锁。
    7. 如果/distribute_lock 节点已经存在,所有试图获取这个锁的客户端,会注册监听器监听这个节点,一旦这个节点被删除就会通知相关的客户端。
  4. 分布式事务

    1. 什么是分布式事务?
      1. 多个节点同时参与一个事务的执行中,需要保证事务的ACID特性。
    2. 方法一:两阶段提交
      1. 核心思想:增加一个协调者来管理各个参与者的行为,根据各参与者执行的状态来决定这些参与者的下一步动作。
      2. 过程
        1. 准备阶段1:协调者询问参与者事务是否执行成功,参与者返回事务执行结果。询问可以看做是一种投票,需要所有参与者都同意。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xebtxIm5-1660877557348)(https://tg0wj72d15.feishu.cn/space/api/box/stream/download/asynccode/?code=M2JjYzgyNDU1ZjJjNzJiYTI0Y2U4NDZmMmNjM2FhODhfSEQ0bzN1SVEzVlBHcXU2RGFUaXdPU2ExSHE0MW9CeUFfVG9rZW46Ym94Y25kcjk4REVkRWFlamRpVUg3RFNZM3NmXzE2NjA4Nzc0Nzg6MTY2MDg4MTA3OF9WNA)]

  1. 提交阶段2:如果每个参与者都执行成功,事务协调者发送通知让所有参与者提交事务;否则,协调者让参与者回滚事务。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-q7OiWj88-1660877557348)(https://tg0wj72d15.feishu.cn/space/api/box/stream/download/asynccode/?code=NTYwZDU2ZTcxODE1OTJlNTkwZTY0ODU0ZDE0ZTM0NmNfSjEzbjdqbjhIelg5VVY4R1hucmJtbE9mQXFtNmtiOG9fVG9rZW46Ym94Y25GNnM0Q2FuNVE1NW9Xd0FucHZadTIyXzE2NjA4Nzc0Nzg6MTY2MDg4MTA3OF9WNA)]

  1. 存在的问题

    1. 同步阻塞:事务的参与者都需要等其他参与者的响应,处于同步阻塞状态,无法进行其他操作。
    2. 单点问题–协调者太重要了:协调者一旦发生故障会造成很大的影响,尤其是在提交阶段故障,所有参与者会一直处于同步阻塞状态,无法完成其他操作。
    3. 数据不一致:如果协调者只发送了部分commit消息,此时网络发生异常,那么只要部分参与者提交了事务,使得系统数据不一致。
    4. 任意一个节点失败就会导致整个事务的失败,容错低。
  2. 方法二:3PC(只做了解,效果很小)

    1. 核心思想:和2PC相比,多了第一步预留资源
    2. 过程:
      1. 准备阶段:协调者先询问所有参与者是否有条件执行当前的事务,这样不会直接锁定资源,使得因为某些参与者需要的资源不可用造成其他参与者阻塞。
      2. 预提交阶段:
      3. 提交阶段:
  3. 方法三:TCC

    1. 核心思想:在业务层面进行控制,所有参与者事先写好回滚接口,如果有参与者提交事务失败,则直接调用参与者的cancel接口进行回滚,实现了自动化。
    2. 过程
      1. try:预留,资源预留和锁定
      2. confirm:事务执行和提交
      3. cancel:如果2中有事务没有提交成功,则调这个接口回滚。
    3. 业务层面的管理,和业务强耦合,开发量大,还不如手动修改。
  4. 本地消息表

    1. 核心思想:使用本地消息表和消息队列来维护事务每一步骤之间的通信。
    2. 过程
      1. 假设事务分为1 2 3步,分别需要A B C系统来执行;
      2. 首先A系统开一个事务,执行步骤1,并将执行成功的消息插入到本地消息表中,状态为“发送中”。之后再把这条消息发送到mq中;
      3. B系统从mq中监听到这条消息后,执行步骤2,如果执行成功了就反向向mq投递一条执行成功的消息,此时A发现这条消息后将本地消息表中消息的状态改成“已发送”。
      4. 如果B执行失败,会有后台任务定时去读本地消息表,筛选出还没有成功的消息,再次调用相关服务。
      5. 如果重试超过了最大次数,就报警让人工处理。
  5. 一致性协议

    1. Paxos
      1. 大致思想:有三种角色,proposer,acceptor和learner,proposer向acceptor发送自己的序号和提议值,如果acceptor还没有接收过提议值,会接收,并保证之后只接收比当前序号大的值,最后acceptor将接收到的值发送给learner,learner选出大多数acceptor都接收的值。
    2. Raft
      1. 主要用来竞选主节点。有三种角色:Follower、Candidate和Leader。Leader会周期性地发送心跳包给Follower。每个Follower都设置一个随机的竞选超时时间,一般为150-300ms,如果在这个时间内没有收到Leader的心跳包,就会变成Candidate,进入竞选阶段。
      2. 单个Candidate竞选
        1. candidate给其他所有节点发送投票请求,如果超过一半的节点回复了,这个candidate变成Leader。
        2. 之后这个Leader周期性地发送心跳包给Follower,Follower接收到心跳包,会重新开始计时。
      3. 多个Candidate竞选
        1. 如果多个candidate参与竞选,并且获得的票数相同,就会重新投票。因为每个节点设置的随机竞选超时时间不同,所以下次再获得相同票数的概率很低。
      4. 数据同步
        1. 客户端的修改都会传给Leader。这个修改还没有提交,只是写入日志中。
        2. Leader会把修改复制给所有Follower,等大多数Follower都进行了修改,才执行提交,并通知所有Follower也提交修改。
  6. CAP理论

    1. Consistency一致性:所有节点在同一时间的数据完全一致。每次访问得到的数据都是最新的。
      1. 强一致性:对于关系型数据库,要求更新过的数据能被后续的访问都看到。
      2. 弱一致性:能够容忍后续的部分或全部访问的数据不是最新的。
      3. 最终一致性:如果经过一段时间后能访问到最新的数据,则是最终一致性。
    2. Availability可用性:指服务一直可用,而且是正常响应时间。(99.99%)好的可用性是指系统能够很好地为用户提供服务,不出现用户操作失败或访问超时等用户体验不好的情况。
    3. Partition tolerance分区容忍性:分布式系统在遇到某节点故障或节点间通信失败时,仍然能够对外提供服务。(分布式系统的各节点部署在不同的子网,就是网络分区)
    4. CAP理论是一个分布式系统最多能同时满足CAP中的两项,但一般P总是成立的。因为在分布式环境下,网络分区是一个自然的事实,分区是必然的,如果舍弃P,那意味着要舍弃分布式系统,也就没必要讨论CAP了。如果要提升P,需要提升基础设施的稳定性。
  7. CAP证明

    1. 假设在N1和N2网络断开时,有用户向N1发送数据更新请求,那N1中的数据V0将被更新为V1,由于网络是断开的,所以分布式系统无法执行同步操作M,所以N2中的数据依旧是V0;在这个时候,用户向N2发送数据读取请求,由于数据还没进行同步,应用程序没办法立即给用户返回最新的数据V1,怎么办呢?
    2. 有两种选择:
    3. 第一,牺牲数据一致性,响应旧的数据V0给用户;
    4. 第二,牺牲可用性,阻塞等待,直到网络连接恢复,数据更新操作M完成之后,再给用户响应最新的数据V1。
  8. PC without A(舍弃可用性)

    1. 适用场景:如果一个分布式系统不要求强的可用性,即容许系统停机或长时间无响应的话,就可以选择保障PC而舍弃A。
    2. 实战:很多分布式数据库。它们在发生极端情况时,优先保证数据的强一致性,代价就是舍弃系统的可用性。如Redis这样的分布式存储系统,或Zookeeper这样的分布式协调组件(任何时刻对Zookeeper的访问请求都得到一致的数据结果,但不能保证每次服务请求的可用性,也就是在极端环境下,zookeeper可能会丢弃一些请求,消费者需要重新请求才能获得结果。Zookeeper的职责是保证数据在其管辖下的所有服务之间保持同步、一致)。
  9. PA without C

    1. 适用场景:一旦网络问题发生,节点之间可能会失去联系,为了保证高可用,需要在用户访问时马上响应,则每个节点只能用本地数据提供服务,而这样会导致全局数据的不一致性。
    2. 实战:(保证全年达到N个9)淘宝购物,12306买票。比如12306买票时提示有票,并下单,但之后系统提示下单失败,余票不足。这是先在可用性方面保证系统可以正常服务,在数据一致性方面做出了牺牲,这会影响一些用户体验,但不至于造成用户流程的严重阻塞。并且,舍弃的只是强一致性,但保证了最终一致性。
  10. BASE理论

对CAP理论的延伸,核心思想是即使无法做到强一致性,但应该可以采用适合的方式达到最终一致性。

  1. BASE:基本可用(Basically Available)、软状态(Soft State)、最终一致性(Eventual Consistency)

  2. 基本可用:分布式系统出现故障时,允许损失部分可用性,保证核心可用。(降级)

  3. 软状态:软状态是指允许系统存在中间状态,而该中间状态不会影响系统整体可用性。分布式存储中一般一份数据至少会有三个副本,允许不同节点间副本同步的延时就是软状态的体现。

  4. 最终一致性:系统中的所有数据副本经过一定时间后,最终能够达到一致的状态。

  5. RPC(Remote Procedure Call)

    1. 远程过程调用,也就是说两台服务器A,B,一个应用部署在A服务器上,想要调用B服务器上应用提供的函数/方法,由于不在一个内存空间,不能直接调用,需要通过网络来表达调用的语义和传达调用的数据。
    2. 首先要解决通讯问题,主要是通过在客户端和服务器之间建立TCP连接,远程过程调用的所有交换数据都在这个连接里传输。连接可以是按需连接,调用结束后就断掉,也可以是长连接,多个远程过程调用共享同一个连接。
    3. 第二,要解决寻址的问题,也就是说,A服务器上的应用怎么告诉底层RPC框架,如何连接到B服务器以及特定的端口,方法名是什么,这样才能完成调用。比如基于web服务协议栈的RPC,就要提供一个endpoint URI,或者从UDDI服务上查找。如果是RMI调用的话,还需要一个RMI Registry来注册服务的地址。
    4. 第三,当A服务器上的应用发起远程过程调用时,方法的参数需要通过底层的网络协议如TCP传递到B服务器,由于网络协议是基于二进制的,方法、参数要序列化成二进制形式,也就是序列化或编组,通过寻址和传输将序列化的二进制发送给B服务器。
    5. 第四,B服务器收到请求后,需要对参数进行反序列化,恢复为内存中的表达方式,然后找到对应的方法(寻址的一部分)进行本地调用,然后得到返回值。
    6. 第五,返回值还要发送回服务器A上的应用,也要经过序列化的方式发送,服务器A接收到后,再反序列化,恢复为内存中的表达方式,交给A服务器上的应用。

过程调用时,方法的参数需要通过底层的网络协议如TCP传递到B服务器,由于网络协议是基于二进制的,方法、参数要序列化成二进制形式,也就是序列化或编组,通过寻址和传输将序列化的二进制发送给B服务器。
5. 第四,B服务器收到请求后,需要对参数进行反序列化,恢复为内存中的表达方式,然后找到对应的方法(寻址的一部分)进行本地调用,然后得到返回值。
6. 第五,返回值还要发送回服务器A上的应用,也要经过序列化的方式发送,服务器A接收到后,再反序列化,恢复为内存中的表达方式,交给A服务器上的应用。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-J6uIxIYL-1660877557348)(https://tg0wj72d15.feishu.cn/space/api/box/stream/download/asynccode/?code=NWZlZDQ5NzZhMzViMDU4NDk2YTIyNDgzZTRiYWE1ZTJfWWNqNmVCdlo5YUhTUTBYMlJxOVFlSEVYRHhaSjB0cnhfVG9rZW46Ym94Y25iTWFTUnlXQ3BjaDBQUkRXQXpzdXpnXzE2NjA4Nzc0Nzg6MTY2MDg4MTA3OF9WNA)]

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值