分布式锁 哨兵模式_2019大厂面试必备:分布式(一)

分布式分为分布式缓存(Redis)、分布式锁(Redis或Zookeeper)、分布式服务(Dubbo或SpringCloud)、分布式服务协调(Zookeeper)、分布式消息队列(Kafka、RabbitMq)、分布式Session、分布式事务、分布式搜索(elastaticSearch)等。
不可能所有分布式内容都熟悉,一定要在某个领域有所专长。更多整理资料,需要的朋友自行领取。

分布式理论

Q:分布式有哪些理论?
CAP、BASE。
分布式CAP理论,任何一个分布式系统都无法同时满足Consistency(一致性)、Availability(可用性)、Partition tolerance(分区容错性) 这三个基本需求。最多只能满足其中两项。
而Partition tolerance(分区容错性) 是必须的,因此一般是CP,或者AP。Q:你怎么理解分布式一致性?
数据一致性通常指关联数据之间的逻辑关系是否正确和完整。
在分布式系统中,数据一致性往往指的是由于数据的复制,不同数据节点中的数据内容是否完整并且相同。
一致性还分为强一致性,弱一致性,还有最终一致性。
强一致性就是马上就保持一致。
最终一致性是指经过一段时间后,可以保持一致。

分布式事务

Q:你怎么理解分布式事务?分布式事务的协议有哪些?
分布式事务是指会涉及到操作多个数据库的事务。目的是为了保证分布式系统中的数据一致性。
分布式事务类型:二阶段提交2PC,三阶段提交3PC。
2PC:第一阶段:准备阶段(投票阶段)和第二阶段:提交阶段(执行阶段)。
3PC:三个阶段:CanCommit、PreCommit、DoCommitQ:分布式事务的解决方案有哪些?
分布式事务解决方案:补偿机制TCC、XA、消息队列MQ。Q:怎么保证分布式系统的幂等性?

Rpc

Q:讲一下Dubbo
服务提供者提供服务,服务消费者可以通过Rpc进行服务消费。Q:Dubbo支持哪些协议?
Dubbo支持Dubbo、rmi、hessian、http、webservice、thrift、Redis等多种协议Q:Dubbo默认的协议是什么?
Dubbo协议。Q:Dubbo的序列化有哪些方式?
Dubbo协议。
连接方式:长连接。默认协议:dubbo协议。序列化:hession二进制。
其他协议:
rmi协议。连接方式:短连接。序列化:java自带的二进制
hessian。连接方式:短连接。序列化:表单序列化Q:Dubbo和SpringCloud有哪些区别?
Dubbo是Soa(面向服务的架构),SpringCloud是微服务架构,除了服务,还有注册中心、熔断、配置中心。
Dubbo基于Rpc(远程过程调用),SpringCloud基于restFul,基于http协议。Q:Soa和微服务架构,有哪些区别?Q:除了Zookeeper,你用过哪些注册中心?有什么区别?
Zookeeper,Redis,Eureka
Zookeeper,是分布式中的CP,能够更好地保证分布式一致性。
Redis基于发布/订阅模式。
Eureka在SpringCloud中应用较多。Eureka是分布式中的AP,也就是注重可用性。Q:如果想实现一个Rpc框架,需要考虑哪些东西?
动态代理、反射、序列化、反序列化、网络通信(netty)、编解码、服务发现和注册、心跳与链路检测Q:Dubbo的服务提供者、服务消费者需要配置哪些信息?
服务提供者需要配置ip、端口、Dubbo协议、注册中心地址等Q:Dubbo有哪些负载均衡策略?
一致性Hash均衡算法、随机调用法、轮询法、最少活动调用法。Q:讲一下Dubbo的SPI机制。Q:你们用的是哪个版本的Dubbo?Q:你们的服务划分了几个模块?分别是哪些模块?

Redis

Q:Redis有哪些优势?
1.速度快,因为数据存在内存中
2.支持丰富数据类型,支持string,list,set,sorted set,hash
3.支持事务,操作都是原子性,所谓的原子性就是对数据的更改要么全部执行,要么全部不执行
4.丰富的特性:可用于缓存,消息,按key设置过期时间,过期后将会自动删除
5.单线程,单进程,采用IO多路复用技术。Q:Redis支持哪些数据结构?
string(字符串),hash(哈希),list(队列),set(集合)及zset(sorted set:有序集合)。Q:Redis的数据结构,有哪些应用场景?
string,简单地get/set缓存。
hash,可以缓存用户资料。比如命令: hmset user1 name "lin" sex "male" age "25" ,缓存用户user1的资料,姓名为lin,性别为男,年龄25。
list,可以做队列。往list队列里面push数据,然后再pop出来。
zset,可以用来做排行榜。Q:Redis的持久化方式有哪些?有哪些优缺点?
aof,就是备份操作记录。aof由于是备份操作命令,备份快,恢复慢。
rdb,就是备份所有数据,使用了快照。rdb恢复数据比较快。Q:aof文件过大,怎么处理?
会进行aof文件重写。
1.随着AOF文件越来越大,里面会有大部分是重复命令或者可以合并的命令
2.重写的好处:减少AOF日志尺寸,减少内存占用,加快数据库恢复时间。
执行一个 AOF文件重写操作,重写会创建一个当前 AOF 文件的体积优化版本。Q:讲一下Redis的事务
先以 MULTI 开始一个事务, 然后将多个命令入队到事务中, 最后由 EXEC 命令触发事务, 一并执行事务中的所有命令。如果想放弃这个事务,可以使用DISCARD命令。
Redis事务无法回滚,那怎么处理?Q:怎么设置Redis的key的过期时间?
key的的过期时间通过EXPIRE key seconds命令来设置数据的过期时间。返回1表明设置成功,返回0表明key不存在或者不能成功设置过期时间。Q:Redis的过期策略有哪些?
Redis key过期的方式有三种:
被动删除:当读/写一个已经过期的key时,会触发惰性删除策略,直接删除掉这个过期key
主动删除:由于惰性删除策略无法保证冷数据被及时删掉,所以Redis会定期主动淘汰一批已过期的key
当前已用内存超过maxmemory限定时,触发主动清理策略,也就是Redis的内存回收策略。Q:Redis 的内存回收机制都有哪些?
LRU、TTL。
noeviction:默认策略,不会删除任何数据,拒绝所有写入操作并返回客户端错误信息,此时Redis只响应读操作。
volatitle-lru:根据LRU算法删除设置了超时属性的键,知道腾出足够空间为止。如果没有可删除的键对象,回退到noeviction策略。
allkeys-lru:根据LRU算法删除键,不管数据有没有设置超时属性,直到腾出足够空间为止。
allkeys-random:随机删除所有键,知道腾出足够空间为止。
volatitle-random:随机删除过期键,知道腾出足够空间为止。
volatitle-ttl:根据键值对象的ttl属性,删除最近将要过期数据。如果没有,回退到noeviction策略Q:手写一下LRU算法 。Q:Redis如何实现分布式锁?
使用setnx命令。
setnx key value,当key不存在时,将 key 的值设为 value ,返回1。若给定的 key 已经存在,则setnx不做任何动作,返回0。
当setnx返回1时,表示获取锁,做完操作以后del key,表示释放锁,如果setnx返回0表示获取锁失败。Q:Redis实现的分布式锁,如果某个系统获取锁后,宕机了怎么办?
Redis宕机的话,会通过Redis集群的哨兵模式,将某个从机变成新的主机。
系统模块宕机的话,可以通过设置过期时间(就是设置缓存失效时间)解决。系统宕机时锁阻塞,过期后锁释放。Q:设置缓存失效时间,那如果前一个线程把这个锁给删除了呢?Q:Redis做分布式锁,Redis做了主从,如果设置锁之后,主机在传输到从机的时候挂掉了,从机还没有加锁信息,如何处理?
可以使用开源框架Redisson,采用了redLock。(待补充)Q:讲一下Redis的redLock。Q:Redis的搭建有哪些模式?
主从模式、哨兵模式、Cluster(集群)模式。
最好是用集群模式。Q:你用过的Redis是多主多从的,还是一主多从的?集群用到了多少节点?用到了多少个哨兵?
集群模式。三主三从。Q:Redis采用多主多从的集群模式,各个主节点的数据是否一致?Q:Redis集群有哪些特性?
master和slaver。主从复制。读写分离。哨兵模式。Q:Redis集群数据分片的原理是什么?
Redis数据分片原理是哈希槽。
Redis 集群有 16384 个哈希槽。 每一个 Redis 集群中的节点都承担一个哈希槽的子集。
哈希槽让在集群中添加和移除节点非常容易。例如,如果我想添加一个新节点 D,我需要从节点 A,B, C 移动一些哈希槽到节点 D。同样地,如果我想从集群中移除节点 A,我只需要移动 A 的哈希槽到 B 和 C。 当节点 A 变成空的以后,我就可以从集群中彻底删除它。 因为从一个节点向另一个节点移动哈希槽并不需要停止操作,所以添加和移除节点,或者改变节点持有的哈希槽百分比,都不需要任何停机时间(downtime)。Q:集群的拓扑结构有没有了解过?集群是怎么连接的?
无中心结构。Redis-Cluster采用无中心结构,每个节点保存数据和整个集群状态,每个节点都和其他所有节点连接。Q:讲一下Redis主从复制的过程。
从机发送SYNC(同步)命令,主机接收后会执行BGSAVE(异步保存)命令备份数据。
主机备份后,就会向从机发送备份文件。主机之后还会发送缓冲区内的写命令给从机。
当缓冲区命令发送完成后,主机执行一条写命令,就会往从机发送同步写入命令。Q:讲一下Redis哨兵机制。
下面是Redis官方文档对于哨兵功能的描述:
监控(Monitoring):哨兵会不断地检查主节点和从节点是否运作正常。
自动故障转移(Automatic Failover):当主节点不能正常工作时,哨兵会开始自动故障转移操作,它会将失效主节点的其中一个从节点升级为新的主节点,并让其他从节点改为复制新的主节点。
配置提供者(Configuration Provider):客户端在初始化时,通过连接哨兵来获得当前Redis服务的主节点地址。
通知(Notification):哨兵可以将故障转移的结果发送给客户端。

缓存

Q:缓存雪崩是什么?
如果缓存数据设置的过期时间是相同的,并且Redis恰好将这部分数据全部删光了。这就会导致在这段时间内,这些缓存同时失效,全部请求到数据库中。这就是缓存雪崩。怎么解决缓存雪崩?
解决方法:在缓存的时候给过期时间加上一个随机值,这样就会大幅度的减少缓存在同一时间过期。Q:缓存穿透是什么?
缓存穿透是指查询一个一定不存在的数据。由于缓存不命中,并且出于容错考虑,如果从数据库查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到数据库去查询,失去了缓存的意义。怎么解决缓存穿透?Q:什么是缓存与数据库双写一致问题?
读的时候,先读缓存,缓存没有的话,就读数据库,然后取出数据后放入缓存,同时返回响应。
更新的时候,先更新数据库,然后再删除缓存。Q:先更新数据库,再删除缓存。如果删除缓存失败了,那么会导致数据库中是新数据,缓存中是旧数据,数据就出现了不一致,怎么办?
解答:先删除缓存,再更新数据库。如果数据库更新失败了,那么数据库中是旧数据,缓存中是空的,那么数据不会不一致。
因为读的时候缓存没有,所以去读了数据库中的旧数据,然后更新到缓存中。

Zookeeper

Q:Zookeeper的原理是什么?
zab协议。
zab协议有两种模式,它们分别是恢复模式(选主)和广播模式(同步)。当服务启动或者在领导者崩溃后,zab就进入了恢复模式,当领导者被选举出来,且大多数server完成了和 leader的状态同步以后,恢复模式就结束了。状态同步保证了leader和server具有相同的系统状态。Q:Zookeeper有哪些应用场景?
Zookeeper可以作为服务协调的注册中心。还可以做分布式锁(如果没有用过分布式锁就不要说)Q:Zookeeper为什么能做注册中心?
Zookeeper的数据模型是树型结构,由很多数据节点组成,zk将全量数据存储在内存中,可谓是高性能,而且支持集群,可谓高可用。
另外支持事件监听(watch命令)。
Zookeeper可以作为一个数据发布/订阅系统。Q:Zookeeper的节点有哪些类型?有什么区别?
临时节点,永久节点。 更加细分就是临时有序节点、临时无序节点、永久有序节点、永久无序节点。  
临时节点: 当创建临时节点的程序停掉之后,这个临时节点就会消失,存储的数据也没有了。Q:Zookeeper做为注册中心,主要存储哪些数据?存储在哪里?
ip、端口,还有心跳机制。
数据存储在Zookeeper的节点上面。Q:心跳机制有什么用?Q:Zookeeper的广播模式有什么缺陷?
广播风暴。Q:Zookeeper是怎么实现分布式锁的?
分布式锁:基于Zookeeper一致性文件系统,实现锁服务。锁服务分为保存独占及时序控制两类。
保存独占:将Zookeeper上的一个znode看作是一把锁,通过createznode的方式来实现。所有客户端都去创建 /distribute_lock 节点,最终成功创建的那个客户端也即拥有了这把锁。用完删除自己创建的distribute_lock 节点就释放锁。
时序控制:基于/distribute_lock锁,所有客户端在它下面创建临时顺序编号目录节点,和选master一样,编号最小的获得锁,用完删除,依次方便。
更详细的回答如下:
其实基于Zookeeper,就是使用它的临时有序节点来实现的分布式锁。
原理就是:当某客户端要进行逻辑的加锁时,就在Zookeeper上的某个指定节点的目录下,去生成一个唯一的临时有序节点, 然后判断自己是否是这些有序节点中序号最小的一个,如果是,则算是获取了锁。如果不是,则说明没有获取到锁,那么就需要在序列中找到比自己小的那个节点,并对其调用exist()方法,对其注册事件监听,当监听到这个节点被删除了,那就再去判断一次自己当初创建的节点是否变成了序列中最小的。如果是,则获取锁,如果不是,则重复上述步骤。
当释放锁的时候,只需将这个临时节点删除即可。Q:讲一下Zookeeper的读写机制。Zookeeper是怎么保持一致性的?
Leader主机负责读和写。
Follower负责读,并将写操作转发给Leader。Follower还参与Leader选举投票,参与事务请求Proposal投票。
Observer充当观察者的角色。Observer和Follower的唯一区别在于:Observer不参与任何投票。Q:讲一下Zookeeper的选举机制。
Leader不可用时,会重新选举Leader。超过半数的Follower选举投票即可,Observer不参与投票。Q:你们的zookeeper集群配置了几个节点?
3个节点。注意,zookeeper集群节点,最好是奇数个的。
集群中的zookeeper节点需要超过半数,整个集群对外才可用。
这里所谓的整个集群对外才可用,是指整个集群还能选出一个Leader来,zookeeper默认采用quorums来支持Leader的选举。
如果有2个zookeeper,那么只要有1个死了zookeeper就不能用了,因为1没有过半,所以2个zookeeper的死亡容忍度为0;同理,要是有3个zookeeper,一个死了,还剩下2个正常的,过半了,所以3个zookeeper的容忍度为1;同理你多列举几个:2->0;3->1;4->1;5->2;6->2会发现一个规律,2n和2n-1的容忍度是一样的,都是n-1,所以为了更加高效,何必增加那一个不必要的zookeeper呢。Q:zookeeper的集群节点,如果不是奇数的,可能会出现什么问题?
可能会出现脑裂。
假死:由于心跳超时(网络原因导致的)认为master死了,但其实master还存活着。
脑裂:由于假死会发起新的master选举,选举出一个新的master,但旧的master网络又通了,导致出现了两个master ,有的客户端连接到老的master 有的客户端链接到新的master。

消息队列

Q:为什么使用消息队列?消息队列有什么优点和缺点?Kafka、ActiveMQ、RabbitMq、RocketMQ 都有什么优点和缺点?
消息队列解耦,削峰,限流。Q:如何保证消息队列的高可用?Q:如何保证消息不被重复消费?(如何保证消息消费的幂等性)Q:如何保证消息的可靠性传输?(如何处理消息丢失的问题)Q:如何保证消息的顺序性?Q:如何解决消息队列的延时以及过期失效问题?消息队列满了以后该怎么处理?有几百万消息持续积压几小时,说说怎么解决?Q:如果让你写一个消息队列,该如何进行架构设计啊?说一下你的思路。

文章篇幅原因,分享至此。还有更多内容,整理成PDF文档,需要的朋友自行领取。

Java高级架构学习资料分享+架构师成长之路​713dbae4.wiz03.com

你可能感兴趣的:(分布式锁,哨兵模式)