架构分布式系统及相关技术栈初了解
Posted 黑黑白白君
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了架构分布式系统及相关技术栈初了解相关的知识,希望对你有一定的参考价值。
文章目录
1)分布式系统
1.1 什么是分布式系统?
“A distributed system is a collection of autonomous computing elements that appears to its users as a single coherent system.” ——《distributed systems 3rd》
- 分布式系统是自主计算元素的集合,在用户看来是一个单一的连贯系统。
- 这个定义是指分布式系统的两个特征:
- 第一个是分布式系统是计算元素( computing elements)的集合,每个元素都能够相互独立地运行。
- 通常将计算元素称为节点(node),可以是硬件设备或软件进程。
- 第二个特征是用户(无论人还是应用程序)相信它们是在处理单个系统。
- 这意味着自主节点需要以某种方式进行协作,如何建立这种协作是开发分布式系统的核心。
分布式系统(Distributed System)是分布在不同机器上的独立组件的集合,这些组件彼此共享消息以实现共同目标。
- 因此,分布式系统对于最终用户来说就像是一个接口或单个计算机。
- 某些时候也称为分布式计算和分布式存储(Also known as distributed computing and distributed storage)
1.2 为什么需要分布式系统?
为了解决单机系统所遇到的问题,主要是利用更多的机器处理单个计算机无法完成的计算、存储任务。
- 提高系统性能:随着业务越来越复杂,服务也会变得越来越复杂,单台机器的CPU、内存已经无法满足部署一个庞大系统的性能要求。
- 通过水平(加机器)和垂直(拆分为多个子系统)拆分系统,变成了一个分布式架构。
- 提高系统可用性:在单台机器上部署服务,如果机器出现故障导致服务挂了,那么整个系统就会崩溃。
- 通过引入分布式架构来增加冗余,从而提高系统的可用性,即使单台机器挂了也能保证服务正常运作。
- 高可用HA(High Availability)是分布式系统架构设计中必须考虑的因素之一,它通常是指通过设计减少系统不能提供服务的时间。
需要明确的是,只有当单个节点的处理能力无法满足日益增长的计算、存储任务的时候,且硬件的提升(加内存、加磁盘、使用更好的CPU)高昂到得不偿失的时候,应用程序也不能进一步优化的时候,我们才需要考虑分布式系统。
- 因为,由于分布式系统多节点、通过网络通信的拓扑结构,会引入很多单机系统没有的问题。
*什么时候才需要分布式系统?
因此,为了使构建的分布式系统物有所值,需要考虑四个重要的设计目标:
- 【支持资源共享】:分布式系统的一个重要目标是使用户(和应用程序)可以轻松访问和共享远程资源。
- 资源几乎可以是任何东西,例如外围设备、存储设施、数据、文件、服务和网络。
- 【使分布透明】:分布式系统的一个重要目标是隐藏其进程和资源物理分布在可能相距很远的多台计算机上的事实。
- 换句话说,它试图使进程和资源的分布透明,即对最终用户和应用程序不可见。
- 【开放性】:分布式系统的另一个重要目标是开放性。
- 一个开放的分布式系统本质上是一个系统,它提供的组件可以很容易地被其他系统使用或集成到其他系统中。
- 同时,一个开放的分布式系统本身通常由来自其他地方的组件组成。
- 【可扩展性】:系统的可扩展性至少可以从三个不同的维度进行衡量。
- 规模可扩展性:系统可以根据其规模进行扩展,这意味着我们可以轻松地向系统添加更多用户和资源,而系统没有任何明显的性能损失。
- 地理可扩展性:地理可扩展系统是一个用户和资源可能相距很远的系统,但很少会注意到通信延迟可能很严重。
- 管理可扩展性:一个可管理可扩展的系统是一个即使跨越许多独立的管理组织,仍然可以轻松管理的系统。
1.3 分布式系统的功能解耦
-
分布式系统按层次划分:
- 网关层:主要实现:客户端请求、逻辑校验、调用分布式服务、然后响应客户端。
- 服务层:主要实现:接受网关层业务请求、进行业务处理、响应网关层、返回处理结果。
- 主业务相关功能中非主业务异步化:使用mq进行异步化。
- 不同业务功能解耦:不同的业务功能独立为单独的服务。
- 数据库解耦:不同的业务功能对应不同的数据库。
2)分布式架构的演变
在了解分布式系统的原理之前,先仔细看看各种类型的分布式系统。
-
1、初始阶段架构
初始阶段的小型系统中,应用程序、数据库、文件等所有的资源都部署在一台服务器上,通俗称为LAMP。 -
2、应用服务和数据服务分离
- 背景:随着系统访问量的再度增加,在高峰期时服务器的负载会很高,如果此时已经没办法在代码层面继续优化提高,那增加机器会是一个比较简单好用的方式。
- 特征:应用程序、数据库、文件分别部署在独立的资源上。
- 描述:数据量增加,单台服务器性能及存储空间不足,需要将应用和数据分离,并发处理能力和数据存储空间得到了很大改善。
-
3、使用缓存改善性能
缓存分为本地缓存和远程分布式缓存,本地缓存访问速度更快但缓存数据量有限,同时存在与应用程序争用内存的情况。- 特征:数据库中访问较集中的一小部分数据存储在缓存服务器中,减少数据库的访问次数,降低数据库的访问压力。
- 描述:系统访问特点遵循二八定律,即80%的业务访问集中在20%的数据上。
- 常见的缓存技术:比如 redis、memcache。
-
4、使用应用服务器集群
- 背景:突然有一天系统的访问又开始有变慢的趋势了,这个时候首先查看数据库,压力一切正常,之后查看webserver,发现apache阻塞了很多的请求,而应用服务器对每个请求也是比较快的,看来是请求数太高导致需要排队等待,响应速度变慢。
- 特征:多台服务器通过负载均衡同时向外部提供服务,解决单台服务器处理能力和存储空间上限的问题。
- 描述:使用集群是系统解决高并发、海量数据问题的常用手段。通过向集群中追加资源,提升系统的并发处理能力,使得服务器的负载压力不再成为整个系统的瓶颈。
- 负载均衡又可以分为软负载和硬负载。软负载我们可以选择nginx、Apache等,硬负载我们可以选择F5等。
- 用户如果每次访问到的服务器不一样,那么如何维护session,达到session共享的目的?可以通过配置tomcat的session共享解决。
-
5、数据库读写分离
- 背景:系统访问量高速增长后,发现系统又开始变慢了,这次又是什么状况呢,经过查找,发现数据库写入、更新的这些操作的部分数据库连接的资源竞争非常激烈,导致了系统变慢。
- 特征:主数据库处理事务性增、改、删操作(INSERT、UPDATE、DELETE),而从数据库处理SELECT查询操作。数据库复制将事务性操作导致的变更同步到集群中的从数据库。
- 描述:通过设置主从数据库实现读写分离,主数据库负责“写操作”,从数据库负责“读操作”,根据压力情况,从数据库可以部署多个以提高“读”的速度,借此来提高系统总体的性能。
-
6、反向代理和CDN加速
- 特征:采用CDN和反向代理以加快系统的访问速度。
- 描述:为了应付复杂的网络环境和不同地区用户的访问,通过CDN和反向代理加快用户访问的速度,同时减轻后端服务器的负载压力。
- CDN与反向代理的基本原理都是缓存。
-
7、分布式文件系统和分布式数据库
-
背景:随着系统的不断运行,数据量开始大幅度增长,这个时候发现分库后查询仍然会有些慢,于是按照分库的思想开始做分表的工作。
-
特征:数据库采用分布式数据库,文件系统采用分布式文件系统。
-
描述:数据库读写分离随着业务的发展最终也将无法满足需求,需要使用分布式数据库及分布式文件系统来支撑。
- 分布式数据库是系统数据库拆分的最后方法,只有在单表数据规模非常庞大的时候才使用,更常用的数据库拆分手段是业务分库,将不同的业务数据库部署在不同的物理服务器上。
- 数据库的水平/垂直拆分:
- 垂直拆分:把数据库中不同业务数据拆分到不同的数据库。
- 水平拆分:把同一个表中的数据拆分到两个甚至更多的数据库中,水平拆分的原因是某些业务数据量已经达到了单个数据库的瓶颈,这时可以采取将表拆分到多个数据库中。
-
-
8、使用NoSQL和搜索引擎
应用服务器通过统一数据访问模块访问各种数据,减轻应用程序管理诸多数据源的麻烦。而且数据库常常对模糊查找效率不是很高,使用搜索引擎能够大大提升我们系统的查询速度。- 特征:系统引入NoSQL数据库及搜索引擎。
- 描述:随着业务越来越复杂,对数据存储和检索的需求也越来越复杂,系统需要采用一些非关系型数据库如NoSQL和分数据库查询技术如搜索引擎。
- 附加的问题:比如维护索引的构建、数据同步到搜索引擎等。
-
9、业务拆分
-
特征:系统上按照业务进行拆分改造,应用服务器按照业务区分进行分别部署。
-
描述:为了应对日益复杂的业务场景,通常使用分而治之的手段将整个系统业务分成不同的产品线,应用之间通过超链接建立关系,也可以通过消息队列进行数据分发,当然更多的还是通过访问同一个数据存储系统来构成一个关联的完整系统。
- 纵向拆分:将一个大应用拆分为多个小应用,如果新业务较为独立,那么就直接将其设计部署为一个独立的Web应用系统。
- 横向拆分:将复用的业务拆分出来,独立部署为分布式服务,新增业务只需要调用这些分布式服务。
-
各个服务之间如何进行远程通信呢? 通过 RPC 技术,比较典型的有:dubbo、webservice、hessian、http、RMI 等等。
-
-
10、分布式服务
- 特征:公共的应用模块被提取出来,部署在分布式服务器上供应用服务器调用。
- 描述:随着业务越拆越小,应用系统整体复杂程度呈指数级上升,由于所有应用要和所有数据库系统连接,最终导致数据库连接资源不足,拒绝服务。
*分布式和微服务的区别?
- 分布式:分布式系统可以看做是若干个独立计算机的集合,这些服务在不同的计算机上部署,但还是属于同一个项目。
- 不同模块部署在不同服务器上,分散压力。
- 微服务:微服务是一种架构风格,相较于以往常见的单体应用,微服务的核心思想是将一个大项目的各个业务模块甚至某个单一功能抽离出来,作为一个单独的完整项目,单独部署,该应用只需要为该大项目或者其他项目的业务模块提供服务即可。
- 微服务的应用不一定是分散在多个服务器上,也可以是同一个服务器。
从分布式和微服务的概念来看,都是对一个项目系统进行了拆分,一个是在部署层面,一个是在软件架构设计层面。
- 但是微服务相较于分布式来说,细粒度更小,服务间的耦合度更低,并且可以说微服务一定是分服务分开部署的,所以其实微服务是基于分布式的,更像是对分布式系统的一种优化,因此很多时候微服务架构也被称为是分布式的架构,区别于分布式系统。
3)分布式系统带来的新问题
分布式系统通过增加工作节点来解决单机系统面临的成本和可用性问题,但是引入了对分布式系统内部工作节点的协调问题。
3.1 分布式计算引入的问题
-
如何找到所需的服务?(即服务发现,Service Discovery)
- 背景:通常访问服务是需要知道服务实例地址和端口。
- 如果服务实例地址和端口都是固定的,我们可以直接将其配置在文件中使用。
- 但大多数线上生产环境,尤其容器部署情况下服务实例地址都是动态分配的,只有当服务实例实际部署之后才能获得地址,服务调用者根本无法提前获取服务实例地址和端口,只能在运行时通过服务发现组件解析服务名来获取服务实例地址和端口。
- 服务发现:简单来讲就是通过服务名找到提供服务的实例地址和端口,主要用于解决如何获取服务实例地址问题。
- 近年来随着容器技术的兴起,大量服务分散在系统各处,服务彼此之间调用都需要通过服务发现来实现。
- 服务发现是分布式系统中不可或缺的关键组件,常用于构建服务发现解决方案的开源框架如Zookeeper、 Etcd、Consul。
- 服务发现方案:DNS、mDNS、Zookeeper、Etcd、Consul。
- 具体介绍可参考:https://juejin.cn/post/6844903937653342216
- 背景:通常访问服务是需要知道服务实例地址和端口。
-
如何找到实例?(即请求分发)
- 背景:找到服务后,当前的请求应该选择发往服务的哪一个实例。
- 服务实例:就是服务器上的具体的服务。
- 如果同一个服务的实例都是完全对等的(无状态),那么按负载均衡策略来处理就足够(随机、轮询、权重、hash、一致性 hash、fair 等各种策略)。
- 如果同一个服务的实例不是对等的(有状态),那么需要通过路由服务(元数据服务等)先确定当前要访问的请求数据在哪一个实例上,然后再进行访问。
- 无状态服务VS有状态服务:https://blog.csdn.net/u010472499/article/details/53888480
-
如何避免雪崩?
- 雪崩:系统雪崩是指故障的由于正反馈循序导致不断扩大规则的故障。
- 背景:一次雪崩通常是由于整个系统中一个很小的部分出现故障于引发,进而导致系统其它部分也出现故障。
- 比如系统中某一个服务的一个实例出现故障,导致负载均衡将该实例摘除而引起其它实例负载升高,最终导致该服务的所有实例像多米诺骨牌一样一个一个全部出现故障。
- 避免雪崩总体的策略(两个思路):
- 快速失败和降级机制(熔断、降级、限流等),通过快速减少系统负载来避免雪崩的发生。
- 弹性扩容机制,通过快速增加系统的服务能力来避免雪崩的发生。
- 根据不同的场景可以做不同的选择,或者两个策略都使用。
- 一般来说,快速失败会导致部分的请求失败,如果分布式系统内部对一致性要求很高的话,快速失败会带来系统数据不一致的问题,弹性扩容会是一个比较好的选择,但是弹性扩容的实现成本和响应时间比快速失败要大得多。
-
如何监控和告警?
- 背景:对于一个分布式系统,如果我们不能很清楚地了解内部的状态,那么高可用是没有办法完全保障的,所以对分布式系统的监控(比如接口的时延和可用性等信息),分布式追踪 Trace,模拟故障的混沌工程,以及相关的告警等机制是一定要完善的。
- 监控的对象:可以监控常用系统服务、应用、网络设备等。
- 硬件层面:服务器温度、磁盘RAID阵列等
- 系统层面:存活状态、CPU、RAM、load负载
- 应用层:mysql、Nginx、Django、LVS、HAProxy
- 业务层面:PV、UV、订单
- 常见的监控系统:zabbix、nagios。
- 详细可参考:https://www.cnblogs.com/sss4/p/9375595.html
3.2 分布式存储引入的问题
当然,3.1介绍的分布式计算的协调方式在分布式存储中同样适用。
-
如何做数据切片?
- 背景:单机的存储能力是不可能存储所有的数据的,所以需要解决怎么将数据按一定的规则分别存储到不同的机器上。
- 常见的的方案:Hash、Consistent Hash 和 Range Based 分片策略。
-
如何做数据复制?
- 背景:为了满足系统的高可用要求,需要对数据做冗余处理。
- 常见的方案:中心化方案(主从复制、一致性协议比如 Raft 和 Paxos 等)和去中心化的方案(Quorum 和 Vector Clock)。
-
如何做分布式事务?
- 背景:对于分布式系统来说,要实现事务,首先需要有对并发事务进行排序的能力,这样在事务冲突的时候,确认哪个事务提供成功,哪个事务提交失败。对于分布式系统来说,系统中机器的时间不能完全同步,并且单台机器序号也没用全局意义。
- 分布式事务:在分布式系统中实现事务,其实是由多个本地事务组合而成。
- 常见的解决方案:两阶段提交(2PC)、3PC、补偿事务(TCC)、本地消息表(异步确保)、MQ 事务消息。
- 详细可参考:https://www.cnblogs.com/mayundalao/p/11798502.html
4)相关技术
目前比较常用的分布式系统的设计有:
- HDFS 或者 GFS(分布式文件系统)
- Kafka 和 Pulsar(分布式消息队列)
- Redis Cluster 和 Codis(分布式缓存)
- MySQL 的分库分表(传统关系型数据库的分布式方案)
- MongoDB 的 Replica Set 和 Sharing 机制集以及去中心化的 Cassandra(NoSQL 数据库),中心化的 TiDB 和去中心化的 CockroachDB(NewSQL)
- 以及一些微服务框架等
-
负载均衡:
- Nginx:高性能、高并发的web服务器;功能包括负载均衡、反向代理、静态内容缓存、访问控制;工作在应用层。
- LVS: Linux virtual server,基于集群技术和Linux操作系统实现一个高性能、高可用的服务器;工作在网络层。
-
webserver:
- Java:Tomcat,Apache,Jboss
- Python:gunicorn、uwsgi、twisted、webpy、tornado
-
service:
- SOA、微服务、spring boot,django
-
容器:
- docker,kubernetes
-
cache:
- memcache、redis等
-
协调中心:
- zookeeper、etcd等
-
rpc框架:
- grpc、dubbo、brpc
- dubbo是阿里开源的Java语言开发的高性能RPC框架,在阿里系的诸多架构中,都使用了dubbo + spring boot
-
消息队列:
- kafka、rabbitMQ、rocketMQ、QSP
- 消息队列的应用场景:异步处理、应用解耦、流量削锋和消息通讯
-
实时数据平台:
- storm、akka
-
离线数据平台:
- hadoop、spark
- db:mysql、oracle、MongoDB、HBase
- 搜索:elasticsearch、solr
- 日志:rsyslog、elk、flume
【部分内容参考自】
- 《Distributed Systems》Version 3.03 (2020)
- 什么是分布式系统,如何学习分布式系统:https://www.cnblogs.com/xybaby/p/7787034.html
- Java分布式应用如何入门以及有哪些资料?:https://www.zhihu.com/question/22764869/answer/31277656
- 分布式架构的总结:https://www.cnblogs.com/zhy-1992/p/9233789.html
- 分布式和微服务的区别:https://blog.csdn.net/MrKorbin/article/details/107993544
- 分布式系统下的功能解耦场景举例:https://blog.csdn.net/jiahao1186/article/details/82456089
- 分布式系统之服务发现(Service Discovery):https://juejin.cn/post/6844903937653342216
- 干货:如何系统学习分布式系统?:https://developer.51cto.com/art/202009/626674.htm
以上是关于架构分布式系统及相关技术栈初了解的主要内容,如果未能解决你的问题,请参考以下文章