[后台开发工程师总结系列] 11. 分布式原理

分布式

什么是分布式

分布式系统是一组通过网络进行通信,为完成共同任务而协调工作节点组成的计算机系统。分布式系统的出现是为了用廉价的、普通的单机完成无法计算、存储的任务。其目的是利用更多的机器, 处理更多的数据。

分布式系统挑战

分布式系统需要大量机器协作,面临诸多挑战:

  1. 异构的机器与网络

分布式中的机器配置不一样、运行的服务语言、架构不同、因此处理能力不一样。而且网络带宽、延时、丢包率也不一样。

  1. 普遍的节点故障

虽然单个节点的故障率低,但是节点数据达到一定规模,出故障的概率就变高了。分布式需要故障发生时,系统仍然是可用的。

  1. 不可靠的网络

节点间通过网络通信,而网络问题:分割、延时、丢包、乱序

分布式特性

透明性、可扩展性、可靠和可用性、高性能、一致性

组件、理论、协议

使用web、APP、SDK通过HTTP、TCP连接到系统,在分布式系统中,为了高并发、高可用,一般都是多个节点提供相同的服务。选择哪个节点来进行服务,这就是负载均衡。负载均衡思想简单、使用很广泛,在分布式系统、大型网站方方面面有应用。

通过负载均衡找到一个节点,然后处理真正的用户请求。请求有可能很简单,也有可能很复杂。简单的请求比如读取数据,可能是有缓存的,及分布式缓存。如果缓存没有明忠,就绪数据库中拉取数据。复杂的请求可能还会调用其他服务。

假设服务A需要调用B的服务,两个节点需要通信,通信建立在TPC|IP上,但是每个应用都写socket是复杂的事情,同理http,于是有了进一步的抽象,有了RPC,远程调用跟本地一样方便。

一个请求可能包含诸多操作,其实涉及到多个服务。一个服务怎么去找到另一个服务呢?通信地址是需要的,怎么获取这个地址,最简单的方法就是写死配置,或者写入数据库。但是这些方法操作不方便,这时候需要注册与发现:提供一个节点向协调中心注册自己的地址,便于服务去拉取地址

以上可以看到,协调中心提供了中心化的服务:一组节点提供类似单点的服务,比如命令服务、分布式锁、注明的就是chubby、 zookeeper

回到用户,请求操作会产生数据、日志、通常为信息。这时有一些系统可能对这些信息感兴趣,如个性化推荐、监控等,这里就抽象出了两个概念(消息生产者与消费者)。那么生产者怎么发送给消费者呢,RPC需要指定发送消息,但是实际情况生产者并不清楚,也不关心谁会消费这个消息。简单来说生产者只需往消息队里传入消息即可。消息队列起到了异步处理、解耦的作用

上面提到,用户会产生一些数据,这些数据忠实记录了用户操作习惯、爱好,是各个行业宝贵的财富。这就产生了分布式计算平台如 Hadoop、Storm

最后用户操作完成后需要持久化,但是数据量很大,单个节点难以存储。这就需要分布式储存,将数据划分到不同的节点上,同时防止数据丢失,进行备份。

1551595235757

  • 负载均衡

Nginx 高性能、高并发 的负载均衡服务器,负载均衡、反向代理、静态内容缓存、访问控制

LVS 基于集群技术和linux操作系统实现高性能、高可用服务器

  • webserver

java: Tomacat Apache

Python: gunicorn、uswgi、twisted

  • service

SOA、微服务、spring boot 、django

  • 容器

docker

  • cache

memcache、 redis

  • 协调中心

zookeeper、 etcd

  • RPC框架

grpc、dubbo(阿里RPC框架)

  • 消息队列

kafka、rabbitMQ

异步处理、应用解耦、流量削峰、消息通信

  • 实时数据平台

storm

  • 离线数据平台

hadoop、spark

  • DB

MySQL、Oracle、MongoDB

负载均衡

集群中应用服务器节点通常被设计成无状态,用户可以请求任何一个节点

负载均衡服务器会根据每个节点的情况将用户请求转发到合适的节点上

负载均衡服务器用来实现高可用及伸缩性

  • 高可用:当某个节点故障时, 负载均衡服务器会将用户请求发送到另外的节点上,从而保证所有的服务持续可用
  • 伸缩性:根据系统的整体负载情况,容易的添加、移除节点

负载均衡算法

  1. 轮询(Round Robin)

轮询算法把请求轮流的发送到每个服务上

1551602255585

该算法适合每个服务器性能差不多的情况,如果有性能存在差异,性能较差的服务器可能无法承担较大的负载

  1. 加权轮询

加权轮询是在轮询的基础上,根据服务器的性能差异,为服务器赋予一定 的权值。性能较高的服务器赋予较高的权值。

1551602372163

  1. 最少连接

由于每个请求的连接时间不一样,使用轮询或加权轮询,可能让一台服务器连接数过大,而另一台服务器连接数过小,造成负载不均衡。最少连接算法就是把当前的请求发送到最少连接数的服务器上。

1551602482460

4 加权最少连接

最少连接的基础上,根据服务器性能为每台服务器分配权重,根据权重处理连接数

5 随机算法

把请求随机的发送到服务器上

6 源地址hash

源地址计算hash值 后,通过对服务器数量取模取得目标服务器的序号。

转发实现

  1. HTTP重定向

HTTP重定向负载均衡服务器使用某种负载均衡算法得到IP地之后,将地址写入HTTP报文中,状态码为302,客户端收到重定向报文后重新请求。

缺点:两次请求,延迟高

HTTP 负载均衡处理能力有限,会限制集群的规模

1551602766597

  1. DNS 域名解析

在DNS域名解析服务器计算服务器IP地址

优点:DNS能够根据地理位置域名解析,返回离用户最近的IP地址

缺点:由于DNS有多级结构,每一级域名都可能被缓存,延时生效。

大型网站基本使用了DNS作为第一级的负载均衡手段,然后在内部使用其他方式作为第二季负载均衡,也就是说,域名解析的结果一般是二级负载均衡服务器的IP地址

  1. 反向代理服务器

反向代理服务器位于原服务器前,用户请求经过反向代理服务器再能达到原服务器。反向代理服务器用来缓存、日志,同时也可以作为负载均衡服务器。

这种负载均衡转发方式下,客户端不直接请求资源。

  1. 网络层

操作系统内核获取网络数据包,根据负载均衡算法计算IP地址并修改IP地址进行转发原服务器返回的请求也及经过负载均衡服务器。在内核中进行,效率较高。

  1. 链路层

修改MAC地址进行转发。通过配置服务器虚拟IP和负载均衡IP一直,不需要修改IP地址就可转发。

这是目前大型网站最广泛使用的负载均衡转发方式,在LINUX平台使用的负载均衡服务器为LVS

集群Session管理

一个用户的session信息如果存在一个服务器上,那么当负载均衡服务器把用户请求转到另一个服务器,由于用户没有用户的Session信心,用户需要重新登录。

Sticky Session

配置负载均衡服务器,是一个用户所有的请求都到同一个路由器,这样吧用户的session放在服务器中

缺点:服务器宕机时,丢失所有的session

1551603885319

Session Replication

服务器间进行同步操作,所有的服务器都有所有的session信息

缺点:占用内存过多、同步占用带宽、服务器处理时间

1551603947278

Session Server

使用一个单独的Session服务器,可使用MySQL或者Redis

优点:为了使得大型网站具有伸缩性,集群中的应用服务器保持无状态。session服务器的存在保证了应用服务器的无状态

大型网站架构常见问题

    1. 你使用过哪些组件或者方法来提升网站性能,可用性,及并发量
  1. 提高硬件性能,增加系统服务器
  2. 使用缓存(本地缓存,分布式缓存Redis、memcache )
  3. 消息队列(解耦、削峰、异步)
  4. 分布式开发(不同服务部署在不同的机器上,利用nginx负载均衡访问,大大提高了并发量)
  5. 数据库分库(读写分离)分表(水平分表、垂直分表)
  6. 采用集群(多台机器提供相同的服务)
  7. CDN加速(将一些静态资源放在离用户最近的网络节点)
  8. 浏览器缓存
  9. 合适的连接池(数据库连接池、线程池)
  10. 适当使用多线程开发
  • 高可用系统的常用手段
  1. 降级:服务器降级是服务器压力剧增的情况下,根据当前业务对服务、页面策略的降级,以释放服务器资源保证核心任务的运行。降级往往会指定级别
  2. 限流:防止恶意请求恶意攻击超出峰值
  3. 缓存:避免大量流量直接打到数据库上
  4. 超时、重试机制:避免堆积请求
  5. 回滚机制:快速修复错误版本
  • 现代互联网系统应该具备的特点
  1. 高并发、大流量
  2. 高可用,不间断服务
  3. 海量数据
  4. 用户分布广泛、网络情况复杂、分布范围广、网络情况千差万别
  5. 安全环境恶略
  6. 需求快速变更
  7. 渐进式发展
  • 微服务领域的了解和认识

大公司及未来的趋势都是spring cloud

我们通常把spring cloud理解为一系列开源组件的集合,抽象了一套通用的开发模式。他的目的是通过抽象这套模式,让开发者更快的开发业务,而这套开发的实际载体还是依赖于RPC、网关、服务发现、配置管理、限流、分布式链路

  • 性能测试

性能测试指通过自动化测试模拟多种正常、峰值、以及异常载荷条件来对系统进行各项指标的测试。

  • 基准测试: 给系统压力较低时,查看系统的运行状况
  • 负载测试:对系统不断的增加压力,直至系统多向指标达到安全临界值
  • 压力测试:超过安全负载情况下不断施加压力,直到系统崩溃或无法处理任何请求,依次获得系统的最大压力承受能力。
  • 稳定性测试:在特定的硬件、软件、网络环境下,加载一定的业务压力观察是否稳定
  • 常见的大表优化

表单数据过大时,数据的CRUD性能会下降,常见优化措施如下

  1. 限定数据的范围: 无比进制不带任何限制范围限制条件的查询语句

  2. 读写分离 经典的数据库拆分方案(主库负责读写,从库负责读)

  3. 垂直分区:根据数据表的相关性进行拆分。例如用户表中有登录信息和基本信息,可以把这两种信息拆成两个表,甚至放到单独的库做分库。简单来说垂直拆分是数据表列的拆分。

    1551599695310垂直拆分的优点:可以使行数据变小,查询时减少读取的block数、减少IO次数。此外垂直分区可以简化表结构,易于维护

    缺点:主键出现冗余,让某些事务更加的复杂

  4. 水平分区,保持数据的表结构不变,通过某种策略进行数据分片,这样每一片数据分到不同的表或库中,达到了分布式的目的,水平拆分可以支持非常大的数据量。

    1551599846381

    水平拆分最好分库,水平拆分能够支持非常大的数据储存量,但是分片事务难以解决。

  • 消息队列的好处
  1. 通过异步提高系统的处理性能

1551599946516

不使用消息队列时,用户的请求直接写入数据库,在高并发的情况下服务器压力剧增。使得响应速度变慢。但是使用消息队列后,用户请求的消息立即返回,再由消息队列的消费者进程从消息队列中获取数据,异步写入数据库。由于消息队列服务器速度快于数据库,响应速度大大改善。

通过以上分析可以得出消息队列有很好的削峰作用–通过异步处理,将短时间高并发事务消息存在消息队列中,从而削平高峰期的并发事务。

1551600347769

数据写入消息队列中就返回用户,但是之后的请求有可能失败。因此消息队列异步处理后需要适当修改业务流程与其配合。

2 降低系统的耦合性

分布式消息队列:

利用发布-订阅者模式工作,生产者发送消息,一个或多个消息接受者(订阅者)订阅消息。从上图可以看出生产者和消费者没有直接耦合,消息发送者将消息发送至分布式消息队列中,接受者只需从后端获取并处理。