分布式
1、分布式服务接口的幂等性如何设计?
所谓幂等性,就是说一个接口,多次发起同一个请求,你这个接口得保证结果是准确得。比如不能多扣款。不能多插入一条数据,不能将统计值多加了1,这就是幂等性。
其实保证幂等性主要是三点:
⚫ 对于每个请求必须有一个唯一的标识,举个例子:订单支付请求,肯定得包含订单ID,一 个订单ID最多支付一次。
⚫ 每次处理完请求之后,必须有一个记录标识这个请求处理过了,比如说常见得方案是再 mysql中记录个状态啥得,比如支付之前记录一条这个订单得支付流水,而且支付流水采 用order id作为唯一键(unique key)。只有成功插入这个支付流水,才可以执行实际 得支付扣款
⚫ 每次接收请求需要进行判断之前是否处理过得逻辑处理,比如说,如果有一个订单已经支 付了,就已经有了一条支付流水,那么如果重复发送这个请求,则此时先插入支付流水, order id已经存在了,唯一键约束生效,报错插入不进去得。然后你就不用再扣款了。
2、分布式系统中的接口调用如何保证顺序性?
可以接入MQ,如果是系统A使用多线程处理的话,可以使用内存队列,来保证顺序性,如果你要100%的顺序性,当然可以使用分布式锁来搞,会影响系统的并发性。
3、说说 ZooKeeper 一般都有哪些使用场景?
⚫ 分布式协调:这个其实就是zk很经典的一个用法,简单来说,就好比,你系统A发送个 请求到mq,然后B消费了之后处理。那A系统如何指导B系统的处理结果?用zk就可 以实现分布式系统之间的协调工作。A系统发送请求之后可以在zk上对某个节点的值注 册个监听器,一旦B系统处理完了就修改zk那个节点的值,A立马就可以收到通知,完 美解决。
⚫ 分布所锁:对某一个数据联系发出两个修改操作,两台机器同时收到请求,但是只能一台 机器先执行另外一个机器再执行,那么此时就可以使用zk分布式锁,一个机器接收到了 请求之后先获取zk上的一把分布式锁,就是可以去创建一个znode,接着执行操作,然 后另外一个机器也尝试去创建那个znode,结果发现自己创建不了,因为被别人创建了, 那只能等着,等等一个机器执行完了自己再执行。
⚫ 配置信息管理:zk可以用作很多系统的配置信息的管理,比如kafka,storm等等很多分 布式系统都会选用zk来做一些元数据,配置信息的管理,包括dubbo注册中心不也支持 zk么。
⚫ | HA高可用性:这个应该是很常见的,比如hdfs,yarn等很多大数据系统,都选择基于 |
zk来开发HA高可用机制,就是一个重要进程一般会主备两个,主进程挂了立马通过zk感知到切换到备份进程。
4、说说你们的分布式 session 方案是啥?怎么做的?
⚫ Tomcat + redis
其实还挺方便的,就是使用session的代码跟以前一样,还是基于tomcat原生的session支持即可,然后就是用一个叫做tomcat RedisSessionManager的东西,让我们部署的tomcat都将session数据存储到redis即可.
⚫ Spring Session + redis
分布式会话的这个东西重耦合在tomcat,如果我要将web容器迁移成jetty,不能重新把jetty都配置一遍.
所以现在比较好用的还是基于java的一站式解决方案,使用spring session是一个很好的选择,给spring session配置基于redis来存储session数据,然后配置一个spring session的过滤器,这样的话,session相关操作都会交给spring session来管了。接着在代码中,就是用原生的session操作,就是直接基于spring session从redis中获取数据了。
5、分布式事务了解吗?
⚫ XA方案/两阶段提交方案
第一个阶段(先询问)
第二个阶段(再执行)
⚫ TCC方案
TCC的全程是:Try、Confirm、Cancel
这个其实是用到了补偿的概念,分为了三个阶段
Try阶段:这个阶段说的是对各个服务的资源做检测以及对资源进行锁定或者预留 Confirm阶段:这个阶段说的是在各个服务中执行实际的操作
Cancel阶段:如果任何一个服务的业务方法执行出错,那么这里就需要进行补偿,就是执行已经成功的业务逻辑的回滚操作
⚫ 本地消息表
⚫ 可靠消息最终一致性方案
⚫ 最大努力通知方案
6、那常见的分布式锁有哪些解决方案?
⚫ Reids的分布式锁,很多大公司会基于Reidis做扩展开发
⚫ 基于Zookeeper
⚫ 基于数据库,比如Mysql
7、ZK 和 Redis 的区别,各自有什么优缺点?
先说Redis:
⚫ Redis只保证最终一致性,副本间的数据复制是异步进行(Set是写,Get是读,Reids 集群一般是读写分离架构,存在主从同步延迟情况),主从切换之后可能有部分数据没有 复制过去可能会丢失锁情况,故强一致性要求的业务不推荐使用Reids,推荐使用zk。
⚫ Redis集群各方法的响应时间均为最低。随着并发量和业务数量的提升其响应时间会有明 显上升(公有集群影响因素偏大),但是极限qps可以达到最大且基本无异常
再说ZK:
⚫ 使用ZooKeeper集群,锁原理是使用ZooKeeper的临时节点,临时节点的生命周期在 Client与集群的Session结束时结束。因此如果某个Client节点存在网络问题,与 ZooKeeper集群断开连接,Session超时同样会导致锁被错误的释放(导致被其他线程 错误地持有),因此ZooKeeper也无法保证完全一致。
⚫ ZK具有较好的稳定性;响应时间抖动很小,没有出现异常。但是随着并发量和业务数量 的提升其响应时间和qps会明显下降。
8、MySQL 如何做分布式锁?
方法一:
利用 Mysql 的锁表,创建一张表,设置一个 UNIQUE KEY 这个 KEY 就是要锁的 KEY,所以同一个 KEY 在mysql表里只能插入一次了,这样对锁的竞争就交给了数据库,处理同一个 KEY 数据库保证了只有一个节点能插入成功,其他节点都会插入失败。
DB分布式锁的实现:通过主键id的唯一性进行加锁,说白了就是加锁的形式是向一张表中插入一条数据,该条数据的id就是一把分布式锁,例如当一次请求插入了一条id为1的数据,其他想要进行插入数据的并发请求必须等第一次请求执行完成后删除这条id为1的数据才能继续插入,实现了分布式锁的功能。
方法二:
使用流水号+时间戳做幂等操作,可以看作是一个不会释放的锁。
9、你了解业界哪些大公司的分布式锁框架
⚫ | Google:Chubby |
Chubby是一套分布式协调系统,内部使用Paxos协调Master与Replicas。
Chubby lock service被应用在GFS, BigTable等项目中,其首要设计目标是高可靠性,而不是高性能。
Chubby被作为粗粒度锁使用,例如被用于选主。持有锁的时间跨度一般为小时或天,而不是秒级。
Chubby对外提供类似于文件系统的API,在Chubby创建文件路径即加锁操作。
Chubby使用Delay和SequenceNumber来优化锁机制。Delay保证客户端异常释放锁时,Chubby仍认为该客户端一直持有锁。Sequence number 指锁的持有者向Chubby服务端请求一个序号(包括几个属性),然后之后在需要使用锁的时候将该序号一并发给 Chubby 服务器,服务端检查序号的合法性,包括 number 是否有效等。
⚫ 京东SharkLock
SharkLock是基于Redis实现的分布式锁。锁的排他性由SETNX原语实现,使用timeout与续租机制实现锁的强制释放。
⚫ 蚂蚁金服SOFAJRaft-RheaKV 分布式锁
RheaKV 是基于 SOFAJRaft 和 RocksDB 实现的嵌入式、分布式、高可用、强一致的 KV 存储类库。
RheaKV对外提供lock接口,为了优化数据的读写,按不同的存储类型,提供不同的锁特性。RheaKV提供wathcdog调度器来控制锁的自动续租机制,避免锁在任务完成前提前释放,和锁永不释放造成死锁。
⚫ Netflix: Curator
Curator是ZooKeeper的客户端封装,其分布式锁的实现完全由ZooKeeper完成。
在ZooKeeper创建EPHEM ERAL_SEQUENTIAL 节点视为加锁,节点的EPHEMERAL特性保证了锁持有者与ZooKeeper断开时强制释放锁;节点的SEQUENTIAL特性避免了加锁较多时的惊群效应。
10、请讲一下你对 CAP 理论的理解
在理论计算机科学中,CAP定理(CAP theorem),又被称作布鲁尔定理(Brewer’s theorem),它指出对于一个分布式计算系统来说,不可能同时满足以下三点:
⚫ Consistency(一致性) 指数据在多个副本之间能够保持一致的特性(严格的一致性)
⚫ Availability(可用性) 指系统提供的服务必须一直处于可用的状态,每次请求都能获取 到非错的响应(不保证获取的数据为最新数据)
⚫ | Partition tolerance(分区容错性) | 分布式系统在遇到任何网络分区故障的时候,仍 |
然能够对外提供满足一致性和可用性的服务,除非整个网络环境都发生了故障
Spring Cloud在CAP法则上主要满足的是A和P法则,Dubbo和Zookeeper在CAP法则主要满足的是C和P法则。
CAP仅适用于原子读写的NOSQL场景中,并不适合数据库系统。现在的分布式系统具有更多特性比如扩展性、可用性等等,在进行系统设计和开发时,我们不应该仅仅局限在CAP问题上。
现实生活中,大部分人解释这一定律时,常常简单的表述为:“一致性、可用性、分区容忍性三者你只能同时达到其中两个,不可能同时达到”。实际上这是一个非常具有误导性质的说法,而且在CAP理论诞生12年之后,CAP之父也在2012年重写了之前的论文。
当发生网络分区的时候,如果我们要继续服务,那么强一致性和可用性只能2选1。也就是说当网络分区之后P是前提,决定了P之后才有C和A的选择。也就是说分区容错性(Partition tolerance)我们是必须要实现的。
11、请讲一下你对BASE理论的理解
BASE理论由eBay架构师Dan Pritchett提出,在2008年上被分表为论文,并且eBay给出了他们在实践中总结的基于BASE理论的一套新的分布式事务解决方案。
BASE 是 Basically Available(基本可用) 、Soft-state(软状态) 和 Eventually Consistent(最终一致性) 三个短语的缩写。BASE理论是对CAP中一致性和可用性权衡的结果,其来源于对大规模互联网系统分布式实践的总结,是基于CAP定理逐步演化而来的,它大大降低了我们对系统的要求。
BASE理论的核心思想是即使无法做到强一致性,但每个应用都可以根据自身业务特点,采用适当的方式来使系统达到最终一致性。也就是牺牲数据的一致性来满足系统的高可用性,系统中一部分数据不可用或者不一致时,仍需要保持系统整体“主要可用”。
针对数据库领域,BASE思想的主要实现是对业务数据进行拆分,让不同的数据分布在不同的机器上,以提升系统的可用性,当前主要有以下两种做法:
⚫ 按功能划分数据库
⚫ 分片(如开源的Mycat、Amoeba等)。
12、分布式与集群的区别是什么?
分布式: 一个业务分拆多个子业务,部署在不同的服务器上
集群: 同一个业务,部署在多个服务器上。比如之前做电商网站搭的redis集群以及solr集群都是属于将redis服务器提供的缓存服务以及solr服务器提供的搜索服务部署在多个服务器上以提高系统性能、并发量解决海量存储问题。
13、请讲一下 BASE 理论的三要素
基本可用
基本可用是指分布式系统在出现不可预知故障的时候,允许损失部分可用性。但是,这绝不等价于系统不可用。
比如:
⚫ 响应时间上的损失:正常情况下,一个在线搜索引擎需要在0.5秒之内返回给用户相应的 查询结果,但由于出现故障,查询结果的响应时间增加了1~2秒
⚫ 系统功能上的损失:正常情况下,在一个电子商务网站上进行购物的时候,消费者几乎能 够顺利完成每一笔订单,但是在一些节日大促购物高峰的时候,由于消费者的购物行为激 增,为了保护购物系统的稳定性,部分消费者可能会被引导到一个降级页面
软状态
软状态指允许系统中的数据存在中间状态,并认为该中间状态的存在不会影响系统的整体可用性,即允许系统在不同节点的数据副本之间进行数据同步的过程存在延时。
最终一致性
强调的是系统中所有的数据副本,在经过一段时间的同步后,最终能够达到一个一致的状态。因此,最终一致性的本质是需要系统保证最终数据能够达到一致,而不需要实时保证系统数据的强一致性。
14、请说一下对两阶段提交协议的理解
分布式系统的一个难点是如何保证架构下多个节点在进行事务性操作的时候保持一致性。为实现这个目的,二阶段提交算法的成立基于以下假设:
⚫ 该分布式系统中,存在一个节点作为协调者(Coordinator),其他节点作为参与者 (Cohorts)。且节点之间可以进行网络通信。
⚫ 所有节点都采用预写式日志,且日志被写入后即被保持在可靠的存储设备上,即使节点损 坏不会导致日志数据的消失。
⚫ 所有节点不会永久性损坏,即使损坏后仍然可以恢复。 第一阶段(投票阶段)
⚫ 协调者节点向所有参与者节点询问是否可以执行提交操作(vote),并开始等待各参与者节 点的响应。
⚫ 参与者节点执行询问发起为止的所有事务操作,并将Undo信息和Redo信息写入日志。 (注意:若成功这里其实每个参与者已经执行了事务操作)
⚫ 各参与者节点响应协调者节点发起的询问。如果参与者节点的事务操作实际执行成功,则 它返回一个”同意”消息;如果参与者节点的事务操作实际执行失败,则它返回一个”中 止”消息。
第二阶段(提交执行阶段)
当协调者节点从所有参与者节点获得的相应消息都为”同意”:
⚫ ⚫ ⚫ ⚫ | 协调者节点向所有参与者节点发出”正式提交(commit)”的请求。 参与者节点正式完成操作,并释放在整个事务期间内占用的资源。 参与者节点向协调者节点发送”完成”消息。 协调者节点受到所有参与者节点反馈的”完成”消息后,完成事务。 |
如果任一参与者节点在第一阶段返回的响应消息为”中止”:
⚫ 协调者节点向所有参与者节点发出”回滚操作(rollback)”的请求。
⚫ 参与者节点利用之前写入的Undo信息执行回滚,并释放在整个事务期间内占用的资源。
⚫ 参与者节点向协调者节点发送”回滚完成”消息。
⚫ 协调者节点受到所有参与者节点反馈的”回滚完成”消息后,取消事务。
15、请讲一下对 TCC 协议的理解
Try Confirm Cancel
⚫ Try:尝试待执行的业务 ,这个过程并未执行业务,只是完成所有业务的一致性检查,并 预留好执行所需的全部资源。
⚫ Confirm:执行业务,这个过程真正开始执行业务,由于Try阶段已经完成了一致性检 查,因此本过程直接执行,而不做任何检查。并且在执行的过程中,会使用到Try阶段预 留的业务资源。
⚫ Cancel:取消执行的业务,若业务执行失败,则进入Cancel阶段,它会释放所有占用的 业务资源,并回滚Confirm阶段执行的操作。