当前位置:   article > 正文

分布式各种理论学习_分布式学习理论

分布式学习理论

分布式学习

  • CAP理论

    • C:一致性。通俗来讲就是对于分布式的系统,如果一个节点改了数据,其他节点要能看到改了以后的数据。官话:通过某个节点的写操作结果对后面通过其他节点的读操作可见。如果能保证就是强一致性,如果允许部分或者全部感知不到就是弱一致性。如果能保证最后能看见,那么就是最终一致性。
    • A:可用性。任何一个没有发生故障的节点,必须在有限的时间内返回合理的结果。
    • P:分区容忍性。指的分布式系统中的某个节点或者网络分区出现了故障的时候,整个系统仍然能对外提供满足一致性和可用性的服务。
  • BASE理论 我觉得说了和没说一样,其实就是CA每一个都做了点妥协

    • 基本可用:允许失去一部分可用性,就比如出现了短暂性的故障,导致返回结果的时间延长了1-2s,比如高并发的购物请求,我们把客户的结果引导到一个降级页面。
    • 弱状态:允许不同节点的数据副本之间存在同步延时。
    • 最终一致性:也就是最终一致性,不要求强一致性。
  • 限流

    • 降级

      降级是指自己的待遇下降了,从RPC调用环节来讲,就是去访问一个本地的伪装者而不是真实的服务。 当双11活动时,把无关交易的服务统统降级,如查看蚂蚁深林,查看历史订单,商品历史评论,只显示最后100条等等。

      什么是服务降级?当服务器压力剧增的情况下,根据实际业务情况及流量,对一些服务和页面有策略的不处理或换种简单的方式处理,从而释放服务器资源以保证核心交易正常运作或高效运作。

    • 熔断

      熔断机制是应对雪崩效应的一种微服务链路保护机制。在微服务架构中,熔断机制也是起着类似的作用。当扇出链路的某个微服务不可用或者响应时间太长时,会进行服务的降级,进而熔断该节点微服务的调用,快速返回错误的响应信息。当检测到该节点微服务调用响应正常后,恢复调用链路。

      在Spring Cloud框架里,熔断机制通过Hystrix实现。Hystrix会监控微服务间调用的状况,当失败的调用到一定阈值,缺省是5秒内20次调用失败,就会启动熔断机制。

    • 微服务的雪崩–通过熔断框架来解决

      A调用B,B调用C,C调用D,但D发生故障的时候,C会进行重试,但是A还是会继续发请求给B,导致B占用内存CPU标高,最后大家一起坏掉。

    • SpringCloud的限流zuul

    • 令牌桶:

      想象有一个木桶,系统按照固定速率,例如10ms每次,往桶里加入Token,如果桶已经满了就不再添加。新请求来临时,会各自拿走一个Token,如果没有Token 就拒绝服务。这里如果一段时间没有请求时,桶内就会积累一些token,下次一旦有突发流量,只要token足够,也能一次处理。

      总结下令牌桶算法的特点,令牌桶即可以控制进入系统的请求请求量,同时允许突发流

    • 漏桶

      限定流出的速度,请求放到桶里面去,如果满了,就终止服务。

    • 使用guava的RateLimiter类—只能单机使用,因为这个类只存在这个服务器上。redis集群部署(也是一主多从)会保证全局一致性。

      RateLimiter.tryAcquire(时间),等待获取令牌如果超过一定时间就结束请求。

      RateLimiter.acquire(),获取令牌。

    • **漏桶和令牌桶的区别:**从上面的例子估计大家也能看出来了,漏桶只能以固定的速率去处理请求,而令牌桶可以以桶子最大的令牌数去处理请求

    • redis实现:

      hmset rateLimit 
      last_ms 20 			-- 最后时间毫秒
      now_permits 20		-- 当前可用的令牌
      max_permits 40		-- 令牌桶最大数量
      rate 10    --1ms生成多少个令牌
      
      lua的逻辑是:
      if(last_ms == null){ // 如果没有记录上一次操作的时间 那么就是第一次请求
      	now_permits = max_permits - 1; // 初始化40个数量
          last_ms = CURRENT_TIME;
      } else { // 获取一个token
          now_permits = (CURRENT_TIME - last_ms) * 1000 * rate + now_permits;
          now_permits = Math.min(now_permits,max_permits);
          if(now_permits <=0 ) {
          	return false;
          }    
          now_permits--;
          return true ;
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
    • redis的缓存击穿

      key过期了,然后大量的请求进来。

  • 分布式和集群:

    集群就是一台机干不了,我就搞两台机。–nginx进行负载均衡

    分布式是微服务,一个业务拆分成多个业务,分布在不同的服务器上。

  • 异地多活

    就是机房在不同地方,如果一个地方的机房断电了,其他机房是否能够一起承担去往坏机房的请求,其实本质是要解决数据库的问题,程序什么的都是一样的,关键是不同机房的数据是否一致,最基本的解决办法就是分布式经常用到的多个备份,这个库的备份是存在其他机房的。

  • 分层架构

    就是指ui、业务实现层、持久层。

  • 分布式事务:

    分布式锁:保证多个线程或者多个程序操作一个变量的时候,保证这个变量只有一个线程或者程序在使用,保证变量的安全性。

    分布式事务:保证不同数据库的一致性

    • 单一架构下的事务(一个服务),我们叫做本地事务,一般就是通过try catch finnally来进行的事务。
    • 多个服务之间的调用,每个服务都会访问不同的数据库,保证这整个事务的一致性那么就是分布式事务。
  • 分布式事务的解决方案

    1. XA协议的两段提交–强一致

      由事务管理器来让某一个服务开始事务,这个服务执行完后把结果返回给事务管理器,当所有的服务事务都成功的时候,事务管理器才会让各个服务提交,否则就回滚。

      这种形式需要你在每个服务写上开启事务,回滚事务的代码,事务管理器也要自己实现,一般有实力的公司才会这么做。

      缺点:同步阻塞:当管理好几个服务的事务的时候,其中一个要执行很久,那么其他的服务已经执行完了也还是在等待那个执行久的,是阻塞的。

      缺点如果事务管理器故障了,那么大家都阻塞了,尤其是在第二阶段,事务也没提交,也没回滚,大问题。

    2. 三阶段提交3PC

      • can commit状态,询问所有参与者是否可以执行事务。参与者返回确认信息。

      • pre commit状态:向各个参与者发送pre commit请求。事务执行了,但是不提交,返回执行结果

      • do commit状态:向各个参与者发送提交通知。

      主要是解决XA协议的单点阻塞问题,如果有一个服务有问题,那么就会默认执行commit。缺点就是这个某个服务commit执行了,其他没有执行不就有问题了么。。

    3. TCC协议其实也就是三段提交只不过有些微不同:

      • try还是先查询是否可以执行

      • 但所有的服务try都返回ok的时候,事务协调器发送confirm请求,大家开始执行事务,在各自的confirm中提交事务。

      • 如果有一个服务失败了。事务协调器调用每个服务器的cancle,来恢复原来的状态。

        其实就是把回滚操作抽出来了一个cancle接口,是要程序员手写sql的,try也要写代码sql实现。。

在这里插入图片描述

 ​		缺点就是要写很多业务代码,try,cancle都要写。
  • 1
  1. MQ来实现事务

    rocketMQ支持事务消息,kafka和activeMQ不支持但是可以通过他们的ack来实现,这个后面讲:

    • 一个服务要执行事务之前,先给RoMQ发送一个propare信息(这个消息是不不能被消费的),然后直接执行事务,但不提交,执行完以后发送confirm消息给消息队列。
    • 这个时候消费者会消费到这条消息,然后开始执行他自己的事务,返回ack结果(可能是失败的也可能是成功的消息,消费成功与否)。如果消费失败,当你订单服务挂了,重新连接的时候会重新去消费那条消息。
    • 最后商品服务根据ROMQ的结果是提交还是回滚。
      在这里插入图片描述
  • 分布式锁-学习redis实现和zookeeper实现

    分布式锁具有的条件:非阻塞的,单个服务可重入的,可以实现公平与非公平锁。

    • redis实现分布式锁:

      关键方法:(记住有个超时的设置)

      setnx(); setnx(key,value) 如果key不存在,那么设置当前key的值为value,返回1,如果存在就返回0.
      
      expire(),设置key的有效时限senx 不能直接设置有效时间,只能通过exprie(). 是为了防止,如果程序崩溃了,这个锁一直存在	 (释放锁是通过删除key就行了)。所以设置一个过期时间,自动释放。这个是redis自己控制的过期时间。
      
      getset(key,value) 往里面设置值的时候,如果成功就返回旧值,如果第一次的话是返回null。这个用于程序自己控制过期时间,	防止我的业务还没执行完,你的所要失效了,通过getset方法来演唱失效时间。
      
      1 vaule应该是这个客户端的uuid
      2 释放的时候应该先判断当前是否当前持有锁的线程再进行释放.
      3 另外就是必须有过期时间.
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
    Long startTime = currentTime();
    
    while(true){
    	if(currentTime > startTime +Time_Out){
    		return false;
        }
        if(tryLock(key)){
    		return true;
        }else[
            Thread.sleep(1ms);
        ]
    }
    
    public boolean tryLock(key){
        boolean result = setNx(key,guoqishijian);  // 设置key的过期时间
        if(result){ // 如果设置成功,那么就是代表获得锁了
            return true;
        }
        if(checkLock(key)){
    		getSet(key,time)// 设置当前这个服务应该超时的时间。
        }
    }
    
    public boolean checkLock(){
    	Loang time = get(key); // 获取key的超时时间
        if(time > currenttime){
    		return true;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    redis锁的缺点:这对于单点的redis能很好地实现分布式锁,如果redis集群,会出现master宕机的情况。如果master宕机,此时锁key还没有同步到slave节点上,会出现机器B从新的master上获取到了一个重复的锁。

    • zookeeper实现分布式锁原理:

      首先知道一下zookeeper的一些东西。他一般有多个节点构成,采用zab协议实现高一致性。它本身有一个持久节点,然后有一些临时节点,这些临时节点是这么来的:一个客户端连接上了zk,就会创建一个临时节点,客户端断开连接这个节点就会取消掉。

      临时节点按照时间顺序创建node1,node2…

      通过watcher机制和临时节点机制,来实现分布式锁。临时节点占用普通节点(持久节点),也可以说是在持久节点下创建临时节点,然后看看自己是不是locker下面最小的节点,如果是说明占有了锁,如果不是就对其调用exits方法watch监听最小的节点,但最小的节点消失后,再看看自己是不是最小的节点。

      优点:如果客户端宕机了,他会自动断开,锁也就释放了,不需要做什么超时处理。

      缺点:也是如果客户端宕机了,他自动断开,但他如果很快的脸上来了,却还是要排队到后面去。同时性能不高,他是对leader进行操作的,我们知道zookeeper会把leader的所有信息同步到所有follwer上。 另外创建节点和销毁节点费时,消耗zk资源。

  • zookeeper 注册中心

  • dubbo 服务发现和调用

  • docker

    docker images

    docker pull 下载容器

    docker run -di --name=xxx -p xxx 制作容器

    docker start 哈希码

    docker ps -a 查看启动的容器

  • springCloud

    • 注解:

      @restController

      @CrossOrigin 给不同微服务之间调用的

      @RequestMapping

      @RestControllerAdvice AOP增强 搭配下面的方法:@ExceptionHandller

    • JPA的东西:

      @Entity @table(name = ‘’)指向一个数据库的表PO类

      dao层Extends JPArepository

    • zuul hystix fegin eruka

  • 一致性算法:

    为了解决数据一致性,尤其是分布式下分区,脑类情况下(不同机房)某一个区崩溃了,也还是能够保证数据一致性。

    Paxos、raft、zab

    • paxos

      提议者proposer:提出提案

      决策者acceptor:参与决策,接受提议者的提案,如果这个提案获得大多数决策者同意,那么就称该提案被批准。

      最终决策学习者leaner

    • 一致性hash算法:

      原来我们要保存一张图片,会把这个图片进行hash然后,对服务器的数量进行取模,确定落到哪台机上。但是如果我们增加了一台服务器,取模的数字变了,原来落在服务器A的照片就跑到B去了,如果是缓存,查找的时候就去B上去找了,而B是没有的,就需要去后台找,导致缓存雪崩。

      哈希一直算法就是有一个哈希换长度是232,首先制定好各个服务器所在的位置,然后我们计算完要查询或者保存的文件的hash,之后对232取模,确定他在什么位置,顺时针到下一个服务器,这个服务器就是他要去找的服务器。

      这种样式可以减少很大一部分增加了服务器(增加了一台服务器,就指定在环上的一个地方),图片保存的服务器位置变了的情况。

      D是新增加的节点,也就是Cd之间的文件会重新落到不同服务器,但是其他的并不会。

在这里插入图片描述
其实你也看出来,他的最大问题就是如果节点数量不够,分布不均会导致hash倾斜,这样要重新确定服务器的数量还是很多。办法就是,创建更多的节点,当你的服务器数量并不是很多的时候,你可以创建虚拟映射节点。

  • raft算法

    raft中的主副节点的同步和kafka是一样的,两阶段状态(这个两阶段要和分布式事务的区别开来,分布式事务是TCC三阶段,和MQprepared+comfirm(这个有点像)+两阶段提交(事务控制器))+ack机制。

    一开始:每个节点都在等待超时,第一个变成超时的节点就是candidate,然后发起投票,一般就是他变成leader了(每个节点的超时时间是不一样的,但接收到其他节点发过来的ping的时候,这个超时倒计时会重新开始计时)

    对于主从文件的复制,和kafka有点区别就是kafka等其他replica返回同步的信息后就直接commit了,而raft算法还需要主动发给消息给从节点让他们也commit。

    太厉害了!!

  • zab选主是怎么样的?

    给自己投票,广播,比较服务器id,数据id,逻辑时钟,比较透给谁

    比较数据,逻辑时钟。。

    原则是投票超过半数的就获胜。最可靠最完全。

  • kafka选主是怎么样的?

    kafka有一个controller负责选组(这个controller是zookeeper实现的,watch监控器,应该就是每一个broker去注册controller,策成功了就是controller,失败了就一直监听controller是否挂了,如果挂了就变成controller。这个又有点像zookeeper实现分布式事务锁了),同时在zookeeper中维护了ISR列表,controller去ISR列表中选择第一个,叫做偏爱分区法

    重新选举,去ISR列表中找一个和leadre一样的节点。

  • redis的哨兵模式

    其实也是选主,他首选要选一个哨兵leader,是发现故障的那个哨兵发起的投票,看看自己是否能够成为选举性leader的主导致。然后选举leader的原则是:slave of 优先级设置高的,数据偏移量最大的,runid(估计是服务器id_最小的)。

就变成controller。这个又有点像zookeeper实现分布式事务锁了),同时在zookeeper中维护了ISR列表,controller去ISR列表中选择第一个,叫做偏爱分区法

重新选举,去ISR列表中找一个和leadre一样的节点。

  • redis的哨兵模式

    其实也是选主,他首选要选一个哨兵leader,是发现故障的那个哨兵发起的投票,看看自己是否能够成为选举性leader的主导致。然后选举leader的原则是:slave of 优先级设置高的,数据偏移量最大的,runid(估计是服务器id_最小的)。

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/526223
推荐阅读
相关标签
  

闽ICP备14008679号