Welcome everyone

分布式理论

分布式 汪明鑫 943浏览 0评论

为什么使用分布式

传统的单体应用随着业务规模扩大已经远远不够开始出现瓶颈甚至很多问题。
部署在一个JVM下容易造成内存泄漏、异常退出。
分布式更能适应当今大数据、大流量的场景。访问量、数据量大。

 

什么是分布式

任务分解 & 节点通信

一个业务拆分成多个子系统,部署在不同的服务器上

 

什么是集群

同一个业务,部署在多个服务器上
根据负载均衡策略打在不同的服务器上

 

一些中间件也有集群,如redis分片集群、zk集群、kafka集群、HDFS集群等。

 

分布式系统的优缺点

优点:

模块化,重用度高,开发和发布速度快,系统扩展性、维护性强,故障影响范围小。

 

缺点:

网络间调用存在延时,存在网络分区造成的一致性或可用性问题

 

 

分布式系统基本架构

 

 

 

 

soa架构和微服务架构

SOA (Servcie Oriented Architecture) 面向服务的架构

各个服务之间通过网络调用。

微服务类似SOA,是SOA的升华,业务需要彻底的组件化和服务化

 

CAP理论

一致性(Consistency)、可用性(Availablity)、分区容忍性(Partition)

三者不可能同时满足,即“三选二”

 

 

一致性(Consistency): 所有节点上的数据,时刻保持一致 但是会有一定的延迟。要么获得最近写入的数据,要么获得一个错误的数据,所有节点看到的是同一份数据。

可用性(Availability):每个请求都能够收到一个响应,无论响应成功或者失败,有重试机制,不保证返回的是最新写入的数据。
分区容错(Partition-tolerance):表示系统出现脑裂以后,可能导致某些server与集群中的其他机器失去联系。完整集群被分成相互独立的小集群。是否还能继续提供服务。

 

分区容忍是必须的,可能由于通信延迟或者节点故障,当发生网络分区时,是选择一致性还是选择可用性。

 

可用性和一致性往往是冲突的,很难使它们同时满足。在多个节点之间进行数据同步时,
  • 为了保证一致性(CP),就需要让所有节点下线成为不可用的状态,等待同步完成;
  • 为了保证可用性(AP),在同步过程中允许读取所有节点的数据,但是数据可能不一致。

 

CAP理论需要抓住一个核心就是当网络出现分区时

1)如果系统不允许写入,意味降低了系统的可用性,但不同分区的数据保持一致,选择了一致性

2)如果系统允许写入,不同分区的数据会产生不一致,可用性得到保障选择了可用性

 

注意:在不同业务场景下对可用性和一致性的要求不一样,可用性和一致性的范围是动态变化的,并不是非黑即白。

 

CP:zookeeper

AP: 注册中心  (注册中心要保证可用性,服务的注册)

 

BASE理论

基于CAP理论,CAP理论并不适用于数据库事务(因为更新一些错误的数据而导致数据出现紊乱,无论什么样的数据库高可用方案都是
徒劳) ,虽然XA事务可以保证数据库在分布式系统下的ACID特性,但是会带来性能方面的影响;
eBay尝试了一种完全不同的套路,放宽了对事务ACID的要求。提出了BASE理论

1,Basically available  : 基本可用 。系统可以出现暂时不可用的状态并会快速恢复。
数据库采用分片模式, 把100W的用户数据分布在5个实例上。如果破坏了其中一个实例,仍然可以保证80%的用户可用
2,soft-state: 软状态  “有状态”和“无状态”的服务的一种中间状态
3,Eventually consistent:数据的最终一致性

 

BASE系统是允许系统出现暂时性问题。

 

单数据库事务遵循ACID,属于刚性事务,分布式事务属于柔性事务,满足BASE理论。

 

 

冷备和热备

热备:安排2个领导,一个领导挂了,另一个领导顶上去
冷备:安排1个领导,这个领导挂了,选举出一个新领导

 

分布式事务

如一笔交易涉及到2个系统、2个库,如何保证分布式情况下的事务安全,而不仅仅是单机情况下的ACID。

 

分布式事务产生的原因:
1, 数据库分库分表
2,服务soa化
3,在分布式系统中,每一个机器节点虽然都能明确的知道自己执行的事务是成功还是失败,但是却无法知道其他分布式节点的事务执行情况。因此,当一个事务要跨越多个分布式节点的时候(比如,下单流程,下单系统和库存系统可能就是分别部署在不同的分布式节点中),为了保证该事务可以满足ACID,就要引入一个协调者(Cooradinator)。其他的节点被称为参与者(Participant)。协调者负责调度参与者的行为,并最终决定这些参与者是否要把事务进行提交。

 

案例:转账和交易等涉及到跨库或跨系统,要么同时成功,要么同时失败。

 

2pc

事务提交的情况:

都说yes,则最终ack

 

事务中断的情况:

一人说no,则回滚

 

 

3pc

 

 

分布式session存储方案

Session Stick

Session Stick 方案即将客户端的每次请求都转发至同一台服务器,这就需要负载均衡器能够根据每次请求的会话标识(SessionId)来进行请求转发,如下图所示。

对于Web服务器来说和单机的情况一样。但是可能会带来如下问题:

如果有一台服务器宕机或者重启,那么这台机器上的会话数据会全部丢失。
会话标识是应用层信息,那么负载均衡要将同一个会话的请求都保存到同一个Web服务器上的话,就需要进行应用层(第7层)的解析,这个开销比第4层大。
负载均衡器将变成一个有状态的节点,要将会话保存到具体Web服务器的映射。和无状态节点相比,内存消耗更大,容灾方面也会更麻烦。

 

Session Replication

Session Replication 的方案则不对负载均衡器做更改,而是在Web服务器之间增加了会话数据同步的功能,各个服务器之间通过同步保证不同Web服务器之间的Session数据的一致性,如下图所示。

Session Replication 方案对负载均衡器不再有要求,但是同样会带来以下问题:

同步Session数据会造成额外的网络带宽的开销,只要Session数据有变化,就需要将新产生的Session数据同步到其他服务器上,服务器数量越多,同步带来的网络带宽开销也就越大。
每台Web服务器都需要保存全部的Session数据,如果整个集群的Session数量太多的话,则对于每台机器用于保存Session数据的占用会很严重。

 

Session 数据集中存储
Session 数据集中存储方案则是将集群中的所有Session集中存储起来,Web服务器本身则并不存储Session数据,不同的Web服务器从同样的地方来获取Session,如下图所示。

 

相对于Session Replication方案,此方案的Session数据将不保存在本机,并且Web服务器之间也没有了Session数据的复制,但是该方案存在的问题在于:

读写Session数据引入了网络操作,这相对于本机的数据读取来说,问题就在于存在时延和不稳定性,但是通信发生在内网,则问题不大。
如果集中存储Session的机器或集群出现问题,则会影响应用。

 

Cookie Based

 

Cookie Based 方案是将Session数据放在Cookie里,访问Web服务器的时候,再由Web服务器生成对应的Session数据,如下图所示。

 

但是Cookie Based 方案依然存在不足:

Cookie长度的限制。这会导致Session长度的限制。
安全性。Seesion数据本来是服务端数据,却被保存在了客户端,即使可以加密,但是依然存在不安全性。
带宽消耗。这里不是指内部Web服务器之间的宽带消耗,而是数据中心的整体外部带宽的消耗。
性能影响。每次HTTP请求和响应都带有Seesion数据,对Web服务器来说,在同样的处理情况下,响应的结果输出越少,支持的并发就会越高。

 

一般采用Session Sticky和Session数据集中存储。

 

服务的注册和发现

 

注册中心

  • 服务提供者在启动时,根据服务发布文件中配置的发布信息向注册中心注册自己的服务。
  • 服务消费者在启动时,根据消费者配置文件中配置的服务信息向注册中心订阅自己所需要的服务。
  • 心跳汇报接口:服务提供者通过调用心跳汇报接口完成节点存活状态上报。
  • 注册中心返回服务提供者地址列表给服务消费者。
  • 当服务提供者发生变化,比如有节点新增或者销毁,注册中心将变更通知给服务消费者。

 

配置中心

  • 静态配置 在软件启动时的一些配置,运行时基本不会进行修改,也可以理解为是环境或软件初始化时需要用到的配置。
  • 动态配置 而所谓动态配置其实就是软件运行时的一些配置,在运行时会被修改。比如,日志级别、降级开关、活动开关。当配置发生变更时,应用服务能及时获得通知。

 

注:区分注册中心和配置中心,注册中心是服务的注册和发现,配置中心是做一些配置

 

服务调用负载均衡

如dubbo:

 

Random LoadBalance
随机,按权重设置随机概率。
在一个截面上碰撞的概率高,但调用量越大分布越均匀,而且按概率使用权重后也比较均匀,有利于动态调整提供者权重。
RoundRobin LoadBalance
轮循,按公约后的权重设置轮循比率。
存在慢的提供者累积请求的问题,比如:第二台机器很慢,但没挂,当请求调到第二台时就卡在那,久而久之,所有请求都卡在调到第二台上。(服务堆积)
LeastActive LoadBalance
最少活跃调用数,相同活跃数的随机,活跃数指调用前后计数差。
使慢的提供者收到更少请求,因为越慢的提供者的调用前后计数差会越大。
ConsistentHash LoadBalance
一致性Hash,相同参数的请求总是发到同一提供者。
当某一台提供者挂时,原本发往该提供者的请求,基于虚拟节点,平摊到其它提供者,不会引起剧烈变动。

 

<!--服务发布的配置,需要暴露的服务接口-->
<dubbo:service
        interface="prers.wmx.IUserService"
        ref="userService" protocol="hessian"
        loadbalance="roundrobin"/>

 

 

 

数据库

分库分表

水平拆分、垂直拆分

 

分布式数据库中间件

DAL、TDDL、Mycat、Sharding JDBC、TiDB

 

缓存

缓存穿透

先检查缓存中是否存在,如果存在直接返回缓存内容,如果不存在就直接查询数据库然后再缓存查询结果返回。这个时候如果我们查询的某一个数据在缓存中一直不存在,就会造成每一次请求都查询DB,这样缓存就失去了意义,在流量大时,可能DB就挂掉了。

解决:

  • 缓存空对象
  • 布隆过滤器

 

缓存雪崩

缓存雪崩的情况是说,当某一时刻发生大规模的缓存失效的情况,会有大量的请求进来直接打到DB上面。

解决:设置不同的失效时间,在一个基础的时间上加上或者减去一个范围内的随机值。

 

缓存击穿

大量的请求同时查询一个 key 时,此时这个key正好失效了,就会导致大量的请求都打到数据库上面去。

解决:查询数据库的方法使用一个 互斥锁来锁住它。

 

消息队列

解藕、削峰、异步

activeMQ、rabbitMQ、rocketMQ、kafka

详见博客的kafka篇  http://xinyeshuaiqi.cn/tag/kafka/

 

分布式锁

详见 分布式锁调研

 

幂等

幂等接口:为了满足业务要求,如果请求参数不变,多次调用产生的效果和第一次一样。

 

为什么做幂等?

比如系统A对系统B做一个数据插入操作,如果网络超时调用失败,A会对B重试调用,因此B系统该接口必须支持幂等,否则会出现插入重复数据。

 

查询和删除都是天然的幂等性操作

 

通常做法:

一个请求用一个唯一的标识符,每次操作前去查找该标识符是否已经存在(如存在redis中   key为id : updatetime),若存在则说明已经执行过return

否则操作,并set进redis中做个记录。

 

 

多机房

这种模式主要解决不同地区高性能、高可用的问题。

随着应用用户不断的增加,用户群体分布在全球各地,如果把服务器部署在一个地方,一个机房,比如北京,那么美国的用户使用应用的时候就会特别慢,因为每一个请求都需要通过海底光缆走上个那么一秒钟(预估)左右,这样对用户体验及其不好。怎么办?使用多机房部署。

 

 

如上图所示,一个典型的用户请求流程如下:

  1. 用户请求一个链接A
  2. 通过DNS智能解析到离用户最近的机房B
  3. 使用B机房服务链接A

 

首先是数据同步问题,在中国产生的数据要同步到美国,美国的也一样,数据同步就会涉及数据版本、一致性、更新丢弃、删除等问题。

其次是一地多机房的请求路由问题,典型的是如上图,中国的北京机房和杭州机房,如果北京机房挂了,那么要能够通过路由把所有发往北京机房的请求转发到杭州机房。异地也存在这个问题。

 

优点:高可用、高性能、异地多活。

缺点:数据同步、数据一致性、请求路由。

 

 

弹性伸缩

这种模式主要解决突发流量的到来,导致无法横向扩展或者横向扩展太慢,进而影响业务,全站崩溃的问题。这个模式是一种相对来说比较高级的技术,也是各个大公司目前都在研究、试用的技术。

 

如上图所示,多了一个弹性伸缩服务,用来动态的增加、减少实例。原理上非常简单,但是这个模式到底解决什么问题呢?先说说由来和意义。

 

如淘宝双十一做活动之前:

  1. 提前准备10倍甚至更多的机器,即使用不上也要放在那里备着,以防万一。这样浪费了大量的资源。
  2. 每台机器配置、调试、引流,以便让所有的机器都可用。这样浪费了大量的人力、物力,更容易出错

活动之后还要人工做缩容

最严重的,突然间的大流量爆发,会让我们触不及防,经常要扩容,要更多的机器备着,也就出现了大量的cpu利用率为1%的机器

为此,首先把所有的计算资源整合成资源池的概念,然后通过一些策略、监控、服务,动态的从资源池中获取资源,用完后在放回到池子中,供其他系统使用。

具体实现上比较成熟的两种资源池方案是VM、docker,每个都有着自己强大的生态。监控的点有CPU、内存、硬盘、网络IO、服务质量等,根据这些,在配合一些预留、扩张、收缩策略,就可以简单的实现自动伸缩。

 

优点:弹性、随需计算,充分优化企业计算资源。

缺点:应用要从架构层做到可横向扩展化改造、依赖的底层配套比较多,对技术水平、实力、应用规模要求较高。

 

 

转载请注明:汪明鑫的个人博客 » 分布式理论

喜欢 (0)

说点什么

您将是第一位评论人!

提醒
avatar
wpDiscuz