分布式系统问题及解决方案

1. 分布式系统简介

1.1 分布式系统背景

单一应用架构:当网站流量下的时候,所有功能都集成在一个应用,也只需要部署一个应用,这样可以减少部署节点和成本。
垂直应用架构:当网站流量较大的时候,靠新增机器数量提升效率达不到要求,便会将系统垂直拆分为几个不相干的应用。
分布式系统架构:当垂直应用越拆越多的时候,各应用之间无可避免的需要交互,这时候可以考虑拆分出一些核心业务作为单独服务部署,逐渐形成稳定的服务中心,以便更快的速度响应业务需要。

1.2 分布式系统简介

“分布式系统是若干独立计算机的集合,这些计算机对于用户来说就像是单个相关系统”——《分布式系统原理和范型》。从进程角度看,两个程序分别运行在两台主机的进程上,他们互相协作最终完成同一个服务或者功能,那么理论上这两个程序所组成的系统,也可以称作是“分布式系统”。当然这两个程序可以是不同的程序,也可以是相同的程序。如果是相同的程序有另一个名称叫“集群”,即相同程序横向扩展提高服务能力的方式。
分布式听起来和微服务概念差不多,他们的区别是:微服务架构偏向于业务,比如可以将微服务按子业务、数据库、接口等维度拆分成不同的微服务;分布式架构偏向于机器,可以说微服务架构都是分布式架构,因为大部分微服务都是单独的部署。

1.3 分布式系统需要解决的问题

1.3.1 分布式Session

session粘滞

session粘滞即当用户访问集群中的某台机器后,将当前用户的后续请求都转发到这台机器上。
使用场景:服务器数量适中、对稳定性要求不是很苛刻
优点:实现简单、配置方便、没有额外网络开销
缺点:网络中有宕机时,用户session会丢失容易造成单点故障
方案:Nginx的ip_hash负载均衡算法

session复制

session复制即将一台服务器的session数据广播复制到集群中的其余集群上
使用场景:机器较少、网络流量较小
优点:实现简单、配置较少、宕机不影响用户访问
缺点:广播式复制session有延时,需要额外网络开销
方案:开源的Tomcat-redis-session-manager

缓存集中式管理

缓存集中式管理即将session写入分布式缓存集群中,当用户访问时优先从缓存中获取session信息
使用场景:服务器较多、网络环境复杂
优点:可靠性好
缺点:实现复杂,需要额外网络开销、稳定性依赖于缓存系统的稳定性
方案:开源的Spring Session,也可以自己实现,主要是重写HttpServletRequestWrapper中的getSession方法

1.3.2 分布式配置中心

在分布式系统中,涉及的服务可能几千台,所有程序一一重启发布新的应用将是一个复杂且耗时过程。那么如何在不停用服务集群的情况下,调整整个集群运行时的行为特征呢?分布式系统配置中心就出现了。常见的分布式系统配置变更:线程池、连接池大小;开关、限流配置;数据源主备容灾切换;路由规则等。开源解决方案有很多,比如:
disconf:百度开源,与spring集成的很好,有web管理界面,只是client指支持JAVA。
diamond:阿里开源,阿里内部广泛使用,由http server、diamond server、web组成,diamond server连接统一mysql,数据通过mysql dump文件同步,支持订阅发布,客户端也只支持Java。
etcd,CoreOS开源,轻量级k-v数据库,可以实现集群环境的服务发现和注册,他提供了数据TTL失效、数据改变监视、多指、目录监听、分布式锁原子操作等功能,来管理节点状态。
zookeeper,成熟的分布式配置解决方案。

1.3.3 分布式事务

分布式事务解决的用户最本质诉求就是保证数据一致。目前大致的解决方案如下:XX事务方案,柔性事务、基于消息的最终一致、业务补偿与人工订正等。

1.3.4 分布式锁

目前几乎很多大型网站及应用都是分布式部署的,分布式场景中的数据一致性问题一直是比较重要的话题。分布式CAP理论(见1.3.5)告诉我们,任何一个分布式系统都无法同时满足一致性、可用性、和分区容错性,最多只能满足CP或者AP两项。在大多数场景中都是保证AP,牺牲强一致性但保证最终一致性。分布式锁实现方案包括:mysql、Redis、zookeeper等。

1.3.5 CAP理论

CAP 理论是针对分布式数据库而言的,它是指在一个分布式系统中,一致性(Consistency, C)、可用性(Availability, A)、分区容错性(Partition Tolerance, P)三者不可兼得。

  • 一致性(C)
    一致性是指“all nodes see the same data at the same time”,即更新操作成功后,所有节点在同一时间的数据完全一致。一致性可以分为客户端和服务端两个不同的视角:从客户端角度来看,一致性主要指多个用户并发访问时更新的数据如何被其他用户获取的问题;从服务端来看,一致性则是用户进行数据更新时如何将数据复制到整个系统,以保证数据的一致。一致性是在并发读写时才会出现的问题,因此在理解一致性的问题时,一定要注意结合考虑并发读写的场景。一致性还可以分为强一致性(必须一致)、弱一致性(可以不一致)和最终一致性(一致性允许有延迟)。
  • 可用性(A)
    可用性是指“reads and writes always succeed”,即用户访问数据时,系统是否能在正常响应时间返回结果。好的可用性主要是指系统能够很好地为用户服务,不出现用户操作失败或者访问超时等用户体验不好的情况。在通常情况下,可用性与分布式数据冗余、负载均衡等有着很大的关联。
  • 分区容错性(P)
    分区容错性是指“the system continues to operate despite arbitrary message loss or failure of part of the system”,即分布式系统在遇到某节点或网络分区故障的时候,仍然能够对外提供满足一致性和可用性的服务。分区容错性和扩展性紧密相关。在分布式应用中,可能因为一些分布式的原因导致系统无法正常运转。分区容错性高指在部分节点故障或出现丢包的情况下,集群系统仍然能提供服务,完成数据的访问。分区容错可视为在系统中采用多副本策略。

CAP 理论认为分布式系统只能兼顾其中的两个特性,即出现 CA、CP、AP 三种情况,在实践中,可根据实际情况进行权衡,或者在软件层面提供配置方式,由用户决定如何选择 CAP 策略。CAP 理论可用在不同的层面,可以根据 CAP 原理定制局部的设计策略,例如,在分布式系统中,每个节点自身的数据是能保证 CA 的,但在整体上又要兼顾 AP 或 CP。如图所示。
在这里插入图片描述

  • CA without P
    如果不要求 Partition Tolerance,即不允许分区,则强一致性和可用性是可以保证的。其实分区是始终存在的问题,因此 CA 的分布式系统更多的是允许分区后各子系统依然保持 CA。
  • CP without A
    如果不要求可用性,相当于每个请求都需要在各服务器之间强一致,而分区容错性会导致同步时间无限延长,如此 CP 也是可以保证的。很多传统的数据库分布式事务都属于这种模式。
  • AP without C
    如果要可用性高并允许分区,则需放弃一致性。一旦分区发生,节点之间可能会失去联系,为了实现高可用,每个节点只能用本地数据提供服务,而这样会导致全局数据的不一致性。

1.3.6 BASE理论

是由eBay架构师提出的。BASE是对CAP中一致性和可用性权衡的结果,其来源于对大规模互联网分布式系统实践的总结,是基于CAP定律逐步演化而来。其核心思想是即使无法做到强一致性,但每个应用都可以根据自身业务特点,才用适当的方式来使系统打到最终一致性。BASE理论是Basically Available(基本可用),Soft State(软状态)和Eventually Consistent(最终一致性)三个短语的缩写。

扫描二维码关注公众号,回复: 10089315 查看本文章
  • Basically Available(基本可用)
    基本可用是指分布式系统在出现故障的时候,允许损失部分可用性(例如响应时间、功能上的可用性),允许损失部分可用性。需要注意的是,基本可用绝不等价于系统不可用。
    响应时间上的损失:正常情况下搜索引擎需要在0.5秒之内返回给用户相应的查询结果,但由于出现故障(比如系统部分机房发生断电或断网故障),查询结果的响应时间增加到了1~2秒。
    功能上的损失:购物网站在购物高峰(如双十一)时,为了保护系统的稳定性,部分消费者可能会被引导到一个降级页面。
  • Soft State(软状态)
    软状态是指允许系统存在中间状态,而该中间状态不会影响系统整体可用性。分布式存储中一般一份数据会有多个副本,允许不同副本同步的延时就是软状态的体现。mysql replication的异步复制也是一种体现。
  • Eventually Consistent(最终一致性)
    最终一致性是指系统中的所有数据副本经过一定时间后,最终能够达到一致的状态。弱一致性和强一致性相反,最终一致性是弱一致性的一种特殊情况。基于BASE理论涌现出的一些关于一致性的算法和协议:两阶段提交、三阶段提交、paxos算法、zab协议。

1.3.7 分布式定时任务

什么是分布式定时任务?

首先,我们要了解计划任务这个概念,计划任务是指由计划的定时运行或者周期性运行的程序。我们最常见的就是Linux的‘crontab’和Windows的‘计划任务’。那么什么是分布式定时任务,个人总结为:把分散的,可靠性差的计划任务纳入统一的平台,并实现集群管理调度和分布式部署的一种定时任务的管理方式。叫做分布式定时任务。

为什么要采用分布式定时任务?

单点定时任务的缺点:
功能相对简单,交互性差,任务部署效率低,开发和维护成本比较高,不能很好的满足各系统定时任务的管理和控制,尤其在多系统的环境下更加明显;许多任务都是单机部署,可用性差;任务跟踪和告警难以实现。
分布式定时任务的优势:
通过集群的方式进行管理调度,大大降低了开发和维护成本;分布式部署,保证了系统的高可用性,伸缩性,负载均衡,提高了容错;可以通过控制台部署和管理定时任务,方便灵活高效;任务都可以持久化到数据库,避免了宕机和数据丢失带来的隐患,同时有完善的任务失败重做机制和详细的任务跟踪及告警策略。

流行的分布式任务框架

Quartz:
Quartz是Java领域最著名的开源任务调度工具。Quartz提供了极为广泛的特性如持久化任务,集群和分布式任务。特点:

完全由Java写成,同时可以很方便的和java的另外一个框架spring集成;
强大的调度功能:支持丰富多样的调度方法,可以满足各种常规及特殊需求;
灵活的应用方式:支持任务和调度的多种组合方式,支持调度数据的多种存储方式;
分布式和集群能力,负载均衡和高可用性。

Elastic-job:
Elastic-Job是ddframe中dd-job的作业模块中分离出来的分布式弹性作业框架。去掉了和dd-job中的监控和ddframe接入规范部分。该项目基于成熟的开源产品Quartz和 Zookeeper及其客户端Curator进行二次开发。特点:

定时任务:基于成熟的定时任务作业框架Quartz cron表达式执行定时任务;
作业注册中心:基于Zookeeper和其客户端Curator实现全局作业注册控制中心。用于注册,控制和协调分布式作业执行;
作业分片:将要给任务分片成多个小任务项到多服务器上同时执行;
弹性扩容缩容:运行中的作业服务器崩溃,或新增N台作业服务器,作业框架将在下次作业执行前重新分片,不影响当前作业执行;
支持多种作业执行模式:支持OneOff,Perpetual和SequenecePerpetual三种作业模式;
失效转移:运行中的作业服务器崩溃不会导致重新分片,只会在下次作业启动时分片。启用失效转移功能可以在本次作业执行过程中,监测其他作业服务器空闲,抓取未完成的孤儿分片项 执行;
运行时状态收集:监控作业运行时状态,统计最近一段时间处理的数据成功和失败数量,记录作业上次运行开始时间,结束时间和下次运行时间;
作业停止,恢复和禁用:用于操作作业启动和停止,并可以禁止某作业运行,一般在上线时常用;
被错过执行的作业重触发:自动记录错过执行的作业,并在上次作业完成后自动触发。
多线程快速处理数据:使用多线程处理抓取到的数据,提升吞吐量;
幂等性:重复作业任务项判定,不重复执行已运行的作业任务项;
容错处理:作业服务器和Zookeeper服务器通信失败后则立即停止作业运行,防止作业注册中心将失效的分片分项配给其他作业服务器,而当前作业服务器任在执行任务,导致重复执行。
Spring支持:支持Spring容器,自定义命名空间,支持占位符;
运维平台:提供了运维平台,可以管理作业和注册中心。

TBSchedule:
TBSchedule是一款非常优秀的高性能分布式调度框架,广泛应用于阿里巴巴、淘宝、支付宝、京东、聚美、汽车之家、国美等很多互联网企业的流程调度系统。tbschedule在时间调度方面虽然没有quartz强大,但是它支持分片功能。和quartz不同的是,tbschedule使用ZooKeeper来实现任务调度的高可用和分片。
Saturn:
Saturn是唯品会在github开源的一款分布式任务调度产品。它是基于当当elastic-job来开发的,其上完善了一些功能和添加了一些新的feature。目前在github上开源大半年,470个star。Saturn的任务可以用多种语言开发比如python、Go、Shell、Java、Php。其在唯品会内部已经发部署350+个节点,每天任务调度4000多万次。同时,管理和统计也是它的亮点。
分布式服务架构之一:Zookeeper入门及单机及集群环境搭建

发布了118 篇原创文章 · 获赞 7 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_43792385/article/details/104812815