转载:http://blog.csdn.net/yinwenjie http://blog.csdn.net/yinwenjie/article/details/46480485 前端
在上图中咱们描述了Web系统架构中的组成部分。而且给出了每一层经常使用的技术组件/服务实现。须要注意如下几点:web
系统架构是灵活的,根据需求的不一样,不必定每一层的技术都须要使用。例如:一些简单的CRM系统可能在产品初期并不须要K-V做为缓存;一些系统访问量不大,而且可能只有一台业务服务器存在,因此不须要运用负载均衡层。算法
业务系统间通讯层并无加入传统的HTTP请求方式。这是由于HTTP请求-响应的延迟比较高,而且有不少次和正式请求无关的通讯(这在下面的内容中会详细讲到)。因此,传统的HTTP请求方式并不适合在两个高负载系统之间使用,其更多的应用场景是各类客户端(WEB、IOS、Android等)->服务器端的请求调用。sql
咱们把业务编码中常使用的缓存系统纳入到数据存储层,是由于相似于Redis这样的K-V存储系统,从本质上讲是一种键值数据库。为何Redis会很快以致于能够做为缓存使用,我将在随后的文章中进行详细的描述。数据库
还有一点须要注意的是,上面架构图中的每层之间实际上不存在绝对的联系(例如负载层必定会把请求转送的业务层,这样的必然性是不存在的),在一般状况下各层是能够跨越访问的。举例说明:若是HTTP访问的是一张图片资源,负载层不会把请求送到业务层,而是直接到部署的分布式文件系统上寻找图片资源并返回。再好比运用LVS作Mysql负载时,负载层是直接和数据存储层进行合做。缓存
实际上负载均衡的概念很普遍,所述的过程是未来源于外部的处理压力经过某种规律/手段分摊到内部各个处理节点上。在平常生活中咱们随时随地在和负载技术打交道,例如:上下班高峰期的车流量引导、民航空管局的航空流量管制、银行柜台的叫号系统。安全
这里咱们所说的负载分配层,是单指利用软件实现的计算机系统上的狭义负载均衡。一个大型(日PV一亿+)、中型(日PV一千万+)Web业务系统,是不可能只有一个业务处理服务,而是多台服务器同时进行某一个相同业务的服务。因此咱们须要根据业务形态设计一种架构方式,未来自外部客户端的业务请求分担到每个可用的业务节点上。以下图所示:性能优化
负载层还有一个做用,是根据用户的请求规则,将不一样的请求类型分派到不一样的服务器上。例如:若是某一个HTTP请求是请求一张图片,那么负载层会直接到图片存储介质上寻找相应的图片;若是某一个HTTP请求是提交的一张订单,那么负载层会根据规则将这张订单提交发送到指定的“订单服务”节点上。服务器
不一样的业务需求,使用的负载层方案也是不一样的,这就考验架构师的方案选择能力。例如Nginx只能处理TCP/IP协议的之上应用层HTTP协议,若是要处理TCP/IP协议,则要按照第三方的TCP-Proxy-Module模。更好的直接在TCP/IP层负载的方案,是使用HAProxy。网络
经常使用的负载层架构方式包括:
- 独立的Nginx负载或HAProxy方案
- LVS(DR)+ Nginx方案
- DNS轮询 + LVS + Nginx方案
- 智能DNS(DNS路由) + LVS + Nginx方案
随后的文章中将详细介绍这些负载架构方案以及这些方案的变形。
通俗来说就是咱们的核心业务层,订单业务、施工管理业务、诊疗业务、付款业务、日志业务等等。以下图所示:
很明显在中大型系统中,这些业务不多是独立存在的,通常的设计要求都会涉及到子系统间脱耦:即X1系统除了知晓底层支撑系统的存在外(例如用户权限系统),X1系统不须要知道和它逻辑对等的X2系统的存在就能够工做。这种状况下要完成一个较复杂业务,子系统间调用又是必不可少的:例如A业务在处理成功后,会调用B业务进行执行;A业务在处理失败后,会调用C业务进行执行;又或者A业务和D业务在某种状况下是不可分割的总体,只有同时成功才成功,其中有一个失败整个大的业务过程都失败。以下图所示:
这样一来业务间的通讯层又是一个逃不开的话题。 在随后的文章中,咱们将以Alibaba的Dubbo框架、基于AMQP协议的消息队列和Kafka消息队列技术的原理和使用方式,来说解业务通讯层技术,特别是业务通讯层的技术选型注意事项。
有的读者可能会问,为何业务系统间通讯层没有提到HTTP这样的调用方式。毕竟不少公司目前都采用这种方式做为业务系统间的调用方式。咱们首先经过一个图来看看HTTP方式的调用过程。(注意,此过程不考虑http客户端缓存的过程也不考虑DNS域名解析的过程,从HTTP创建可靠的TCP链接开始):
从上图中咱们能够看出如下几个问题:
基于以上的描述,本文并不推荐使用HTTP做为业务间通讯/调用的方式,而建议HTTP方式仅限于WEB、iOS、Android等这样的客户端请求服务的方式。
数据存储将是这个系列文章中将要介绍的另外一个重点。进行业务计算前的初始数据、计算过程当中的临时数据、计算完成后获得的计算结果都须要进行存储。咱们经过一张思惟导图首先从几个维度阐述一下数据存储的基本分类。
咱们经过一个最基本的在Centos6.5系统上建立Ext4文件系统的过程,讲解文件系统的最基本原理。
经过df命令查看挂载信息,以下图所示:
万变不离其宗的建立过程告诉咱们一个什么事实呢?
物理块,一个物理块是咱们上层文件系统可以操做的最小单位(一般为512字节),一个物理块在底层对应了多个物理扇区。一般一块SATA硬盘会有若干机械手臂(决定于物理盘片数量),和若干个物理扇区(物理扇区的大小是磁盘出厂时就肯定的,咱们没法改变)。
单个扇区的工做是单向的,那么映射出来的一个物理块的工做方式也是单向的。原理就是机械手臂在读取这个扇区的数据时,硬件芯片是不容许机械手臂同时向这个扇区写入数据的。
经过上层文件系统(EXT、NTFS、BTRFS、XF)对下层物理块的封装,OS是不须要直接操做磁盘物理块的,操做者经过ls这样的命令看到的一个一个文件也不须要关心这些文件在物理块的存储格式。这就是为何不一样的文件系统有不一样的特性(有的文件系统支持快照,有的文件系统支持数据恢复),基本原理就是这些文件系统对下层物理块的操做规范不同。
上一小节咱们叙述了最简单、最原始的物理块和文件格式规范的工做方式,可是随着服务器端不断扩大的数据存储容量的需求和数据安全性的需求,很显然单机的存储是没办法知足要求的,目前存储环境两种大的需求类型是:
稳定的扩展存储容量,而且不破坏目前已存储的数据信息,不影响整个存储系统的稳定性。
文件共享,让多台服务器可以共享存储数据,而且均可以对文件系统进行读写操做。
要解决这两个问题,咱们首先要将问题扩展到上一小节的图例中,以下图所示:
很明显图中两个问题的答案是确定的,也就是咱们将要介绍的块存储系统要解决的问题。
咱们先来聊一下块存储。以前咱们提到的最简单的状况就是磁盘在本地物理机上,传输的物理块I/O命令,也是经过本地物理机主板上的南桥进行的。可是为了扩展更大的磁盘空间,而且保证数据吞吐量,咱们须要将磁盘介质和本地物理机分离,而且让物理块的I/O命令在网络上进行传输:
虽然磁盘介质和本地物理机发生了分离,可是直接传输块I/O命令的本质是没有改变的。本地南桥传输I/O命令变成了光纤传输,只在本物理机内部传输I/O命令变成了网络传输,而且I/O命令经过某种通讯协议进行了规范(例如FC、SCSI等)。
文件系统的映射倒是在本地进行,而非远程的文件系统映射。上文中咱们已经提到,因为块操做的顺序性(在一个扇区进行写入的时候,是不会进行这个扇区的读取操做的),且块操做属于底层物理操做没法向上层的文件逻辑层主动反馈变化。因此多个物理主机是没法经过这个技术进行文件共享的。
块存储系统要解决的是大物理存储空间、高数据吞吐量、强稳定性的共存问题。做为上层使用这个文件系统的服务器来讲,它很是清楚,除了它之外没有其余的服务器可以对专属于它的这些物理块进行读写操做了。也就是说它认为这个庞大容量的文件存储空间只是它本地物理机上的存储空间。
固然随着技术的发展,如今已经有一些技术能够只用TCP/IP协议对标准的SCSI命令进行传输,以便减少这个块存储系统的建设成本(例如iSCSI技术)。可是这种折中方式也是以减弱整个系统的数据吞吐量为代价的。不一样的业务需求能够根据实际状况进行技术选型。
那么若是是将文件系统从本地物理机经过网络移植到远程呢?固然能够,典型的文件存储系统包括了FTP、NFS、DAS:
文件存储系统的关键在于,文件系统并不在本机。而是经过网络访问存在于远程的文件系统,再由远程的文件系统操做块I/O命令完成数据操做。
通常来讲诸如本地文件系统NTFS/EXT/LVM/XF等是不容许直接网络访问的,因此通常文件存储系统会进行一层网络协议封装,这就是NFS协议/FTP协议/NAS协议(注意咱们说的是协议),再由协议操做文件存储系统的服务器文件系统。
文件存储系统要解决的问题首要的文件共享,网络文件协议能够保证多台客户端共享服务器上的文件结构。从整个架构图上能够看到文件存储系统的数据读写速度、数据吞吐量是没办法和块存储系统相比的(由于这不是文件存储系统要解决的首要问题)。
从上面的简介中咱们能够清楚的知晓,当面对大量的数据读写压力的时候,文件存储系统确定不是咱们的首要选择,而当咱们须要选择块存储系统时又面临成本和运维的双重压力(SAN系统的搭建是比较复杂的,而且设备费用昂贵)。而且在实际生产环境中咱们常常遇到数据读取压力大,且须要共享文件信息的场景。那么这个问题怎么解决呢?
兼具块存储系统的高吞吐量、高稳定性和文件存储的网络共享性、廉价性的对象存储就是为了知足这样的需求出现的。典型的对象存储系统包括:MFS、Swift、Ceph、Ozone等。下面咱们简单介绍一下对象存储系统的特色,在后面的文章中,咱们将选择一款对象存储系统进行详细说明。
对象存储系统必定是分布式文件系统。但分布式文件系统不必定是对象存储系统
咱们知道文件信息是由若干属性进行描述的,包括文件名、存储位置、文件大小、当前状态、副本数量等信息。咱们将这些属性抽离出来,专门使用服务器进行存储(元数据服务器)。这样一来文件操做的客户端要访问某一个文件,首先会询问元数据节点这个文件的基本信息。
因为是分布式系统,那么数据一致性、资源争夺、节点异常问题都须要进行统一的协调。因此对象存储系统中通常会有监控/协调节点。不一样的对象存储系统,支持的元数据节点和监控/协调节点的数量是不一致的。但总的趋势都是“去中心化”。
OSD节点(基于对象的存储设备)用于存储文件内容信息。这里要注意,虽然OSD节点的底层和块存储底层同样都是依靠块I/O进行操做的,可是上层构造二者彻底不一样:OSD节点并不是向块存储设备那样,经过块操做命令跳过本地文件系统直接进行物理块操做。
随后的文章中咱们将选择一款流行的对象存储系统,详细剖析对象存储系统,而且对分布式存储系统中三个核心概念和取舍进行说明(CAP):一致性、扩展性和容错性。
这篇文章已经写了不少存储层的概要描述了,因此咱们熟悉或者不熟悉的数据库存储技术的概述就不在这里介绍了。
后续的文章我将使用Mysql讲解几个经常使用的架构方案和性能优化点,固然也会讲到Mysql中,诸如Innodb这样的核心数据引擎的工做方式。这些架构方案主要解决的是Mysql的单机I/O瓶颈、机房内数据容灾、数据库稳定性、跨机房数据容灾等核心问题。
后续的文章我还会选取目前流行的数据缓存系统,讲解其工做原理、核心算法和架构方案。以便读者们根据本身的业务状况设计符合业务的存储集群。固然还有非关系型数据库Cassandra、HBase、MongoDB的深刻介绍。
咱们如何来评价一个服务系统的顶层设计是否优秀呢?抛开八股文式的扩展性、稳定性、健壮性、安全性这样的套话不说。我从实际工做中为你们总结了一下几个评价要点。
任何系统架构在进行生产环境实施的时候,都是须要付出建设成本的。显然各个公司/组织对成本的承受度是不同的(这些成本包括:设计成本、资产采购成本、运维成本、第三方服务成本),因此如何利用有限的成本建设出符合业务需求、适应访问规模的系统,就是一个复杂的问题。另外,这种要求下架构师是不能进行过分设计的。
根据业务的发展,整个系统是须要进行升级的(这包括已有模块的功能升级、合并已有的模块、加入新的业务模块或者在模块功能不变的状况下提升数据吞吐量)。那么如何尽可能不影响原业务的工做,以最快的速度、最小的工做量来进行系统的横向、纵向扩展,也就是一个复杂的问题了。好的系统架构是能够在用户无任何感受的状况下进行升级的,或者只须要在某些关键子系统升级时才须要短暂的中止服务。
对系统的攻击确定是瞄准整个系统最薄弱的环节进行的,攻击可能来自于外部(例如Dos/DDos攻击)也可能来自于内部(口令入侵)。好架构的系统不是“绝对不能攻破”的系统,而是“预防很好”的系统。所谓预防,就是预防可能的攻击,分阶段对可能遇到的各类攻击进行模拟;所谓隐藏,就是利用各类手段对整个系统的关键信息进行涉密管理,ROOT权限、物理位置、防火墙参数、用户身份。
好的架构应该考虑不一样等级的容灾。集群容灾,在集群中某一个服务节点崩溃的状况下,集群中另一台主机可以接替立刻接替他的工做,而且故障节点可以脱离;分布式容灾:分布式系统通常会假设整个系统中随时都在发生单点故障/多点故障,当产生单点故障/多点故障时,整个分布式系统都还能够正常对外提供服务,而且分布式系统中的单点故障/多点故障区能够经过自动/人工的方式进行恢复,分布式系统会从新接纳它们;异地容灾(机房等级容灾):在机房产生物理灾难的状况下(物理网络断裂、战争摧毁、地震等),在某个相隔较远的异地,备份系统可以发现这样的灾难发生,并主动接过系统运行权,通知系统运维人员(根据系统不一样的运行要求,可能还有多个备份系统)。异地容灾最大的挑战性是如何保证异地数据的完整性。
系统架构归根结底仍是为业务服务的,系统架构的设计选型必定是以服务当前的业务为前提。在上文中提到的业务通讯层中,选择SOA组件仍是消息队列组件,又或者选择什么样的消息队列,就是一个很好的业务驱动事件。例如,A业务是一种WEB前端服务,须要及时反馈给客户操做结果,B业务的服务压力又很是大。A业务在调用B业务时,B业务没法在毫秒级的时间内返回给A业务调用结果。这种业务场景下可使用AMQP类型的消息队列服务。另外说明两点,目前行业内有不少为解决相同业务场景存在的不一样方案,架构师在进行方案选型的过程当中,必定要对各类解决方案的特色足够掌握,这样才能作出正确的选择;另外行业内的解决方案已经足够多,架构师在业务没有特殊要求的状况下必定不要作“ 重复发明轮子”的事情。
一套服务系统从架设之初就须要运维团队不断的进行投入。显然根据系统的复杂程度和物理机器的数量,运维团队的知识复杂性也是不同的。在架构师进行顶层架构设计时,必须还要考虑系统的运维难度和运维成本。
负载层、业务层、业务通讯层、数据存储层的详细架构方案在后续文章中咱们会用若干文章进行深刻讲解,包括核心算法、架设原理、架设案例。随后的文章中咱们将首先介绍系统负载层。
在不少系统中咱们还涉及存储的数据进行分析,造成数据分析结果。这涉及到数据分析层的架构知识。Hadoop生态系统是目前行业公认的高效率、高稳定性、高扩展性的数据分析生态系统。这个系列的博文暂时不会介绍数据分析层的架构设计和开发知识,后续将会独立成文。
各位看官咱们立刻进入负载层技术的详细讲解!