一、分布式系统发展历史
1.1 分布式系统的出现
- 问题描述: 随着计算机业务的复杂化,以及大数据时代的冲击,传统单机受硬件技术限制,其提供的计算、存储、服务等,逐渐无法满足日益增长的需求
- 解决方案:设计分布式系统。分布式系统(Distributed System)是分布在不同机器上的独立组件的集合,这些组件彼此共享消息以实现共同目标
“A distributed system is a collection of autonomous computing elements that appears to its users as a single coherent system.” ——《distributed systems 3rd》
- 分布式系统的两个基本特征:
- 由独立自治的节点集合而成,共同完成任务
- 对用户透明,使用户相信它是在处理单个系统
- 分布式系统对单机系统的改进:
- 【提高系统性能】:通过水平(加机器)和垂直(拆分为多个子系统)拆分系统,分布到多个节点独立运行,提高系统性能
- 【提高系统可用性】:增加冗余、提高服务质量
- 一个好的分布式系统应该支持:
- 【资源共享】:用户(应用程序)可以轻松访问和共享远程资源
* 资源包括:硬件设备、数据、文件、服务和网络 - 【用户透明】:隐藏其为分布式系统的事实,使用户相信它们是在处理单个系统
- 【开放性】:分布式系统的设计要模块化、组件化,提高复用性
- 【可扩展性】:
- 规模可扩展性:可以向系统添加更多用户和资源,而系统没有任何明显的性能损失
- 地理可扩展性:支持远距离访问,且通信延迟较小
- 管理可扩展性:支持多点共同管理
- 【资源共享】:用户(应用程序)可以轻松访问和共享远程资源
- 分布式系统工作在两层:
- 【网络层】:客户端请求、逻辑校验、调用分布式服务、然后响应客户端
- 【应用层】:响应网络层请求、进行业务处理、返回处理结果
1.2 将应用与数据的分离
- 问题描述:系统访问量增加,应用与数据杂糅的系统不便于分别管理,影响性能
- 解决方案:将应用、数据库、文件分别部署在独立的服务器上,通过应用服务器调用数据库服务器和文件服务器
1.3 使用缓存改善性能
- 问题描述:统计发现 ,80%的业务访问集中在20%的数据上(二八定律),这说明数据是有优先级的,可以尝试将最常访问的数据分离出来,以减轻数据服务器负载压力
- 解决方案:将集中访问的数据加入缓存服务器中,由应用服务器直接调用而不经过数据服务器
- 应用实例: redis
1.4 设计 服务器集群 与 负载均衡
- 问题描述:用户数量增加,一台应用服务器无法响应高并发的请求,也不能快速调用拥有海量数据的数据库服务器,导致请求阻塞(排队)
- 解决方案:使用应用服务器集群,实现负载均衡。应用服务器将接受的请求转发,请求其他服务器共同处理,从而实现负载均衡,就可以解决高并发问题
- 应用实例: LVS,Nginx(软负载)、F5(硬负载)、DNS负载
【Nginx】:高性能、高并发的web服务器;功能包括负载均衡、反向代理、静态内容缓存、访问控制;工作在应用层。
【LVS】:Linux virtual server,基于集群技术和Linux操作系统实现一个高性能、高可用的服务器;工作在网络层。
1.5 数据库服务器读写分离
- 问题描述:单个数据库服务器无法高效处理数据,“增删查改”的各种请求激烈竞争
- 解决方案:可以使用主、从数据库服务器,将读、写操作分离。主数据库负责“写”,从数据库负责“读”;根据业务特征,还可以采用一主一从、一主多从的形式提升整体性能
1.6 使用反向代理 和 CDN内容分发网络
- 问题描述:不同地域、不同网络环境的用户应该选择最适合他们的应用服务器
- 解决方案1:反向代理。在主服务器外增加一层代理服务器,用以接受、转发、回馈请求(也就是作为客户与主服务器通信的代理结点)。反向代理还可以起到保护主服务器的作用;同时,在反向代理服务器设置ache,可以有效减少主服务器的压力
- 应用实例1:Nginx
- 解决方案2:CDN(Content Delivery Network)内容分发网络。将几台CDN服务器散步在全国各地,用户就近接入CDN服务器,CDN服务器可以复制、缓存主服务器,从而提高用户响应的速度。
1.7 使用分布式数据库 与 分布式文件系统
- 问题描述:数据规模非常庞大,即便将数据库读写分离后,仍不能满足存储需求
- 解决方案:将数据库、文件系统都作成分布式系统。一般来说,可以将数据按照业务 存储到不同的数据库上,再通过某些手段将数据库之间连接起来进行通信。这是实现数据冗余的基础,也是分布式存储的重要研究领域。
- 应用实例:MySQL、NoSQL、AWS Aurora都支持分布式数据库
1.8 增强数据访问模块
- 问题描述:来自不同数据源的数据 使得 数据存储和检索的需求更加复杂,原始的数据访问模块难以胜任
- 解决方案:引入NoSQL数据库(非关系型数据库)及搜索引擎(分数据库查询技术)来增强数据访问模块
1.9 进行业务拆分
- 问题描述:过于复杂的业务功能使应用服务器(集群)不堪重负
- 解决方式:业务拆分,分别配置独立的应用服务器(集群)。同时,还可以将复用的功能拆分出来独立部署,以供调用。
- 解决各应用间的通讯问题:RPC技术,如dubbo、webservice、hessian、http
1.10 增加分布式服务器
- 问题描述:随着应用服务器越拆越小,而每个服务器都要与数据库连接,导致数据库连接难度增加
- 解决方式:将原应用服务器中与数据库相连的功能拿出来,做成独立的分布式服务器;所有的应用服务器都通过此服务器连接数据库,从而减轻数据库连接压力
二、分布式系统带来的新问题
2.1 如何找到所需的服务?—— 服务发现组件
- 问题描述:线上生产环境中,尤其容器部署情况下 服务实例地址(服务器端口) 是动态分配的,服务调用者无法提前获取服务实例地址和端口
- 解决方案:在服务运行时,通过 服务发现组件 解析服务名来获取服务实例地址和端口
- 应用实例:DNS、mDNS、Zookeeper、Etcd、Consul
2.2 如何找到实例?—— 请求分发的策略
- 问题描述:找到服务器后,还应该确定将当前请求发往服务器的哪一个实例
- 解决方案:
- 如果同一个服务的实例都是完全对等的(无状态),那么按负载均衡策略来处理就足够(随机、轮询、权重、hash、一致性 hash、fair 等各种策略)
- 如果同一个服务的实例不是对等的(有状态),那么需要通过路由服务(元数据服务等)先确定当前要访问的请求数据在哪一个实例上,然后再进行访问
2.3 如何避免雪崩?
- 问题描述:一个故障由于正反馈不断被扩大, 从而导致整个系统故障
- 解决方案:
- 【快速失败】和【降级机制】:熔断、降级、限流等,通过快速减少系统负载来避免雪崩的发生
- 【弹性扩容机制】,通过快速增加系统的服务能力来避免雪崩的发生
2.4 如何对系统进行监控?
- 问题描述:对于一个分布式系统,如果我们不能很清楚地了解内部的状态,那么高可用是没有办法完全保障的
- 解决方案:监控系统的各层
- 【硬件层面】:服务器温度、磁盘RAID阵列等
- 【系统层面】:存活状态、CPU、RAM、load负载
- 【应用层】:mysql、Nginx、Django、LVS、HAProxy
- 【业务层面】:PV、UV、订单
- 应用实例:zabbix、nagios
2.5 分布式存储如何做数据切片?
- 问题描述:既然要实现分布式数据库,那么应该如何将数据进行切片?
- 解决方案:Hash、Consistent Hash 和 Range Based 分片策略
2.6 如何设置冗余?如何复制数据?
- 问题描述:分布式存储的高可用性需要冗余来保证,那么如何做冗余?如何对数据进行复制、更新时保证两份数据的一致性?
- 解决方案:
- 【中心化方案】:主从复制、一致性协议(Raft 和 Paxos)
- 【去中心化的方案】:Quorum、Vector Clock
三、分布式系统常用技术
3.1 常用的分布式系统
- 分布式文件系统:HDFS 或者 GFS
- 分布式消息队列:Kafka 和 Pulsar
- 分布式缓存:Redis Cluster 和 Codis
3.2 常用技术
- 【负载均衡技术】
- 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