你们的再哥面试复习-分布式

1.redis

常用数据类型:

  String 最常用

  List  

  Set  可以全局去重

  布隆过滤器  防止缓存击穿

 

部署方式:

  单机部署

  哨兵模式 

   一个主节点和多个从节点,主节点用来写,从节点用来读,主节点会同步数据给从节点,每个节点防止单点再使用备用服务器

  缺点就是每个服务器的数据一样,很浪费内存空间,并且有脑裂问题,就是主节点因为网络等原因连接不上,认为他挂了然后再选举一个,然后原来的又恢复了,导致数据不一致。

  集群模式

   集群模式是把redis分成固定数量的插槽,然后每台服务器分配不同的插槽,数据是不一样的,访问也快速,缺点是有单点问题,而且其中有一台挂了导致整个不可用,所以还需要添加备用节点

 

redis为什么快:

  因为基于内存的,以及是单线程操作,不用考虑锁或者上下文切换问题

  而且是使用多路io复用模型。。。讲几种io模型

 

redis的数据同步方式:

从服务器启动的时候会发送一个psync命令给主库要求进行同步数据,master会再起一个线程来进行生成rdb快照进行传输到从库,

从库解析加载到内存,然后主库在传输的时候如果还新的数据写入,会把这部分数据写入缓冲区,再继续传给从服务器,这时候数据就全了。如果这个过程中链接中断会自动重连

 

redis持久化方式:

持久化有rdb和aof两种方式

rdb就周期性的同步,每隔一段时间生成快照保存成一个文件代表这个时间点的数据,代表某一时间段缺点就是可能会丢数据,以及同步的时候如果文件比较大可能会卡顿。

aof是实时的把操作写到日志里,类似mysql的binlog,缺点是aof的日志文件比rdb的大,如果有问题恢复的没那么快

这两种是可以同时开启的,如果真正出现问题了,我们可以拿rdb的日志文件来进行恢复到某个时间点,因为间隔时间同步一次的,还会缺一些数据,然后可以从aof的日志进行补全。

 

redis的内存回收策略:

Redis的删除有定期删除和惰性删除2种

定期删除是redis每100秒就会抽取一些设置了过期时间的key来判断是否过期,过期了就删除,但是这个只是随机抽取不是全量遍历所以有一些还是没有删除

所以有了惰性删除,就是等到你get这个key的时候再检查是否过期,如果过期就返回空并且把这个key删了

不过还有问题,如果你一直不get就一直不会删除了,内存就会越堆越多,然后就会触发redis的内存淘汰机制,当内存不足以加入新的数据时候,有几种策略:报错,或者随机删除一个,这些策略,但我们一般常用的是删除一个最近最少使用的。

 

redis做秒杀锁:

商品或者优惠券之类的比如只有5个,但有100个人同时抢,如何保证?

主要逻辑是数量-1这里,最简单的方法就是加syc,但是这样会锁住所有商品,而且分布式情况下也行不通,所以需要分布式锁,

可以用redis的setnx方法的原子性来实现,而且可以优化一下锁的粒度不是锁住所有商品,而且锁住当前这个商品就行,具体做法比如把这个商品的id作为锁set到redis里,set成功的说明拿到了锁,其他人等待。

redis做分布式锁会有其他问题,比如执行过程中抛出异常锁没释放,需要try cahch起来进行释放锁

还有极端情况下,执行到一般 服务器挂了,也没能释放锁,所以需要设置锁的超时时间,并且要主要设置锁的超时时间不能太短,

比如你设置2秒,然后你执行出了问题,cpu,Load太高啊,或者数据库问题,或者下游有问题执行了3秒,锁提前释放了,别的线程进来了,就会出现并发问题。

 

2.dubbo

服务暴露的时候 组装服务的参数 包括 方法名 参数类型 参数值  版本号等,封装成一个invoke存到map里,然后向注册中心进行注册

然后调用这个服务的时候消费者从注册中心拿到ip地址列表,使用dubbo协议进行二进制流的方式传输到对方服务器,但实际我们调用的方法是调用的代理类

然后代理类再用Client进行远程调用,调用的时候会进行序列化,在多台机器多个ip的情况下就涉及到负载算法

一般有权重随机,轮询,最少活跃,hash等算法,而且调用的方式也有同步异步,同步就是等待结果,异步的话就是先直接返回,但是传过去有一个唯一id,等服务放处理完了,就能用这个id找回原点进行回调。

然后再说说服务方收到了这个方法调用,该怎么做,首先会把这个请求处理任务丢到线程池来执行,真正开始执行的时候也是调用的代理类来进行,

解析反序列化消息体,我们暴露服务的时候不是封装了invoke存到map里吗,然后现在再根据key拿出来,进行调用  ok

负载算法:

轮询

hash

权重

最少活跃

随机

失败策略:

默认这台挂了马上换另一台

快速失败,抛出异常

先返回空,再启用线程定时调用

 

序列化方式:

Java自带的序列化

Hessian2 是默认的

Fst

 

netty:

dubbo的远程调用是基于netty来进行网络通信的,因为netty快,netty基于nio (说说io模型), 以及零拷贝还有Reactor多线程模型

 

3.消息队列

作用:

 肖峰填谷:在大促的时候大量的请求服务器没法一下子处理,所以需要消息队列来存储来慢慢消费

解耦:比如订单状态要告诉系统A,调他接口告诉他状态改了,然后又来系统B,你也要告诉他,这时候就可以用消息队列,把状态往消息队列一丢,各个系统订阅就ok了,当然你提供接口给他们主动调来获取状态也行,但是会增加自己应用的压力。

异步:很好理解,我们调别人的接口,需要等待返回结果,降低吞吐量,如果不要求实时返回或者另一种方式通知结果的话,往消息队列一丢 搞定

常用消息队列:

Kafka:用于大数据以及日志收集较多,消费者主动拉取消息,分为多个broker保证高可用,但是缺点就是都是命令没有界面,以及因为保证高可用复制多份数据,上百个topic的时候性能下降

rocketMq:基于java开发的,使用较多,通过主从配置支持高可用。

rabbitMq :吞吐量万级,比上面2个有所不如,但是小型企业够用,上手简单效率快

 

如何保证消息不丢失:

发送时丢失的话,可能发送时候报错了,拿到错误对应处理,重试或者抛出异常

在消息服务器丢失,消息服务器挂了,消息没了,开启持久化

消费时丢失,有一些消息队列是默认丢给你就完事了,就当作成功了不会重试,如果你执行的时候报错了,这个消息也就丢了,所以需要开启返回成功了才是真的成功

 

如何保证消息顺序:

消息队列只能保证消息发出的顺序,但消费的顺序是无法保证的,比如你发出消息未收货,再发出消息已发货

可能已发货先消费到了就会出现问题,所以只能自己在程序进行处理,比如加状态机进行状态强制校验(画一画状态机)

 

如何保证消息不重复消费:

在分布式情况下,多台服务器都订阅了这个消息,如果通过广播的方式每一台都收得到

如何保证只有一台成功消息,那就需要分布式锁进行幂等,可以用redis,或者数据库,zookeeper来作为锁都可以

 

消息队列服务器挂了怎么办:

每个消息队列对自己的高可用的实现方式不一样,但是思想都是主备进行数据同步,通过注册中心一台挂了拿另一台

 

 

4.注册中心

分布式cap理论:

C:  一致性,所有节点数据同步

A: 可用性,保证每一次的调用是可用的

P:分区容错性,挂了不影响整个

A跟C是不可兼得的,所以每个注册中心都有自己所秉持的理念

常用注册中心:

nacos  可以通过配置切换AP和CP,并且支持配置中心,现在集成springCloud这一套非常好用,使用时注意数据配置持久化到数据库,不然会丢失。

zookeeper 秉持CP的理论,保证所有节点数据一致,简单点说就是我给你的机器是肯定对的,但是可能慢一点,因为zookeeper的选举机制会比较满,期间不能注册。

eruka  秉持AP理念,保证高可能,你一访问我就给你返回,但是给你的服务器可能不能用了,你自己试试,不行你再跟我说,eruka目前社区也不维护了。

 

 

5.分布式事务

在分布式系统中,比如应用A改了状态需要同步应用B,其中一个执行失败了会导致状态不同步,所以需要分布式事务来进行操作

 

2PC、3PC概念

2PC:就是把多个本地事务分为2个阶段提交,第一阶段告诉他们,准备好了没,保证能连接的通,然后再通知开始有了结果再通知比如A失败了

        通过一个中间协调者来进行一起成功或者一起回滚,但是这个协调者会有单点问题,还有堵塞问题,我A执行好了,一直在等你B的结果。

3PC: 引入了超时机制以及多了一段提交,解决堵塞问题

TCC概念

自己编写代码来进行提交和回滚的逻辑方案,然后自己编写逻辑来协调双方的提交和回滚

 

消息队列处理

分布式事务都是会降低吞吐量,所以强制性要求不高的话,可以使用消息队列进行处理

保证最终一致:状态消息丢出去,不用管了,总会消费的,消费失败也会重试,重试还失败需要人工排查原因了

保证可靠一致:应用A用本地事务更改状态并且发送消息,应用B监听这个消息后也执行自己的事务

                         如果A失败了,A自己回滚消息也没发出啥都没改变

                        如果B失败了,发出一条失败消息,A跟B都监听这个消息然后进行回滚

                        极端情况下,执行到一般,服务挂了 失败消息没发出,就需要定时调用接口去查询执行结果了,

Seata

阿里开源的分布式事务中间件

AT模式(业务侵入小) ,基于数据库分布式事务AX协议进行统一,缺点是吞吐量低

TCC模式  通过注册注册该服务是事务参与者

 

6.sentinel限流

限流: 在大促期间,为了保证自己的服务不被外部或者上游的流量击倒,需要对流量进行限制

降级:指的是能提前预知的,早一步的控制手段,比如知道准备大促了,关闭一些不必要的接口,关闭一些报表生成的定时器,把保存日志放到消息队列等

熔断:指的是如果有不可预知的突发情况,作最坏的打算,降低最小的损失,比如自己挂了,为了不拖累上游服务,直接快速返回失败,不要一直转圈圈把上游也拖垮了,熔断设置一定阈值触发,也能设置一定阈值恢复

 

sentinel提供页面对服务进行限流控制,需要在配置文件配置注册到sentinel服务器上

sentinel需要进行持久化

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值