java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Java面试题

Java面试题冲刺第二十三天--分布式

作者:_陈哈哈

这篇文章主要为大家分享了最有价值的三道关于分布式的面试题,涵盖内容全面,包括数据结构和算法相关的题目、经典面试编程题等,感兴趣的小伙伴们可以参考一下

面试题1:说说什么分布式事务?解释一下什么是CAP?

现在互联网开发多使用微服务架构,一个简单的操作,在服务端可能就是由多个服务和数据库实例协同完成的。但在一致性要求较高且高QPS的场景下,多个独立操作之间的一致性问题和服务高可用问题就显得格外棘手。

基于对水平扩容能力和成本考虑,针对除非敏感业务(如支付、转账等)外的大量其他业务,传统的强一致的解决方案逐渐被淘汰。

其理论依据就是CAP原理。在分布式系统中,同时满足CAP定律中的一致性 Consistency、可用性 Availability和分区容错性 Partition Tolerance三者是不可能的。在绝大多数的场景,为了可用性和分区容错性,都需要牺牲强一致性来换取系统的高可用性,系统往往只需要保证最终一致性。

在这里插入图片描述

CAP理解:

Consistency:一致性就是在客户端任何时候看到各节点的数据都是一致的。

Availability:可用性就是在任何时刻都可以提供读写。

Partition Tolerance:分区容错性是在网络故障、某些节点不能通信的时候系统仍能继续工作。

具体地讲在分布式系统中,在任何数据库设计中,一个Web应用最多只能同时支持上面的两个属性。显然,任何横向扩展策略都要依赖于数据分区。因此,设计人员必须在一致性与可用性之间做出选择。

AP(高可用&&分区容错):

允许至少一个节点更新状态会导致数据不一致,即丧失了C性质(一致性)。会导致全局的数据不一致。

CP(一致&&分区容错):

为了保证数据一致性,将分区一侧的节点设置为不可用,那么又丧失了A性质(可用性)。分区同步会导致同步时间无限延长(也就是等数据同步完成之后才能正常访问)

CA(一致&&高可用):

两个节点可以互相通信,才能既保证C(一致性)又保证A(可用性),这又会导致丧失P性质(分区容错性)。这样的话就分布式节点受阻,无法部署子节点,放弃了分布式系统的可扩展性。因为分布式系统与单机系统不同,它涉及到多节点间的通讯和交互,节点间的分区故障是必然发生的,所以在分布式系统中分区容错性是必须要考虑的。

分布式事务服务

分布式事务服务(Distributed Transaction Service,DTS)是一个分布式事务框架,用来保障在大规模分布式环境下事务的最终一致性。

CAP理论告诉我们在分布式存储系统中,最多只能实现上面的两点。而由于当前的网络硬件肯定会出现延迟丢包等问题,所以分区容忍性是我们必须需要实现的,所以我们只能在一致性和可用性之间进行权衡。

为了保障系统的可用性,互联网系统大多将强一致性需求转换成最终一致性的需求,并通过系统执行幂等性的保证,保证数据的最终一致性。

追问1:怎么理解强一致性、弱一致性和最终一致性?

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

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

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

  最终一致性是指系统中所有的副本经过一段时间的异步同步之后,最终能够达到一个一致性的状态,也就是说在数据的一致性上存在一个短暂的延迟。

  几乎所有的互联网系统采用的都是终一致性,只有在实在无法使用终一致性,才使用强一致性或事务,比如,对于决定系统运行的敏感数据,需要考虑采用强一致性,对于与钱有关的支付系统或金融系统的数据,需要考虑采用事务。

  也就是说能够使用最终一致性的业务就尽量使用最终一致性,因为强一致性会降低系统的可用性。

面试题2:了解BASE理论么?

在分布式系统中,我们往往追求的是可用性,它的重要程序比一致性要高,那么如何实现高可用性呢?前人已经给我们提出来了另外一个理论,就是BASE理论,它是用来对CAP定理进行进一步扩充的。BASE理论指的是:

BASE理论是对CAP中的一致性和可用性进行一个权衡的结果,是对互联网大规模分布式系统的实践总结,强调可用性。

理论的核心思想就是:基本可用(Basically Available)和最终一致性(Eventually consistent)。虽然无法做到强一致,但每个应用都可以根据自身的业务特点,采用适当的方式来使系统达到最终一致性(Eventual consistency)。

追问1:基于BASE理论,举几个实际的例子

我们以12306订票系统为例

1.流量削峰

  可以在不同的时间,出售不同区域的票,将访问请求错开,削弱请求峰值。比如,在春运期间,深圳出发的火车票在 8 点开售,北京出发的火车票在 9 点开售。

2.延迟响应

  在春运期间,自己提交的购票请求,往往会在队列中排队等待处理,可能几分钟或十几分钟后,系统才开始处理,然后响应处理结果。

3.体验降级

  比如用小图片来替代原始图片,通过降低图片的清晰度和 大小,提升系统的处理能力。

4.过载保护

  比如把接收到的请求放在指定的队列中排队处理,如果请求等 待时间超时了(假设是 100ms),这个时候直接拒绝超时请求;再比如队列满了之后,就 清除队列中一定数量的排队请求,保护系统不过载,实现系统的基本可用。

 面试题3:实现分布式事务一致性(Consistency)的方法有哪些?

为了解决分布式系统的一致性问题,在长期的探索研究过程中,涌现出了一大批经典的一致性协议和算法,其中最著名的就是二阶段提交协议、三阶段提交协议和Paxos算法。

追问1:说一下二阶段提交(2PC)的原理吧

二阶段提交(two-phase commit)增加了事务处理器和事务执行者的角色。由事务处理器来进行整个事务的处理。主要流程如下面的图

在这里插入图片描述

两阶段提交协议

prepare(准备阶段)

当开始事务调用的时候,事务处理器向事务执行者(有可能是数据库本身支持)发出命令,事务执行者进行prepare操作。

当所有事务执行者都完成了prepare操作,就进行下一步行为。

如果有一个事务执行者在执行prepare的时候失败了,那么通知事务处理器,事务处理器再通知所有的事务执行者执行回滚操作。

commit(提交阶段)

当所有事务执行者都prepare成功以后,事务处理器会再次发送commit请求给事务执行者,所有事务执行者进行commit处理。

当所有commit处理都成功了,那么事务执行结束。

如果有一个事务执行者的commit处理不成功,这个时候就要通知事务处理器,事务处理器通知所有的事务执行者执行回滚(abort)操作。

但是两阶段提交的诟病就是在于性能问题。比如由于执行链比较长,锁定资源的时间也变长了。所以在高性能的系统中都会避免使用二阶段提交。

总结

本篇文章就到这里了,希望能给你带来帮助,也希望您能够多多关注脚本之家的更多内容!

您可能感兴趣的文章:
阅读全文