面试:第九章:分布式 、高并发、集群、负载均衡、高可用
分布式 :
分布式架构:把系统按照模块拆分成多个子系统,多个子系统分布在不同的网络计算机上相互协作完成业务流程,系统之间需要进行通信。
优点:
- 把模块拆分,使用接口通信,降低模块之间的耦合度。
- 把项目拆分成若干个子项目,不同的团队负责不同的子项目。
- 增加功能时只需要再增加一个子项目,调用其他系统的接口就可以。
- 可以灵活的进行分布式部署。
缺点:
1、系统之间交互需要使用远程通信,接口开发增加工作量。
2、各个模块有一些通用的业务逻辑无法共用。
基于soa的架构
SOA:面向服务的架构。也就是把工程拆分成服务层、表现层两个工程。服务层中包含业务逻辑,只需要对外提供服务即可。表现层只需要处理和页面的交互,业务逻辑都是调用服务层的服务来实现。
分布式架构和soa架构有什么区别?
SOA,主要还是从服务的角度,将工程拆分成服务层、表现层两个工程。
分布式,主要还是从部署的角度,将应用按照访问压力进行归类,主要目标是充分利用服务器的资源,避免资源分配不均
集群:
一个集群系统是一群松散结合的服务器组,形成一个虚拟的服务器,为客户端用户提供统一的服务。对于这个客户端来说,通常在访问集群系统时不会意识到它的服务是由具体的哪一台服务器提供。集群的目的,是为实现负载均衡、容错和灾难恢复。以达到系统可用性和可伸缩性的要求。集群系统一般应具高可用性、可伸缩性、负载均衡、故障恢复和可维护性等特殊性能。一般同一个工程会部署到多台服务器上。
常见的tomcat集群,Redis集群,Zookeeper集群,数据库集群
分布式与集群的区别:
分布式是指将不同的业务分布在不同的地方。 而集群指的是将几台服务器集中在一起,实现同一业务。一句话:分布式是并联工作的,集群是串联工作的。
分布式中的每一个节点,都可以做集群。 而集群并不一定就是分布式的。
举例:就比如新浪网,访问的人多了,他可以做一个群集,前面放一个响应服务器,后面几台服务器完成同一业务,如果有业务访问的时候,响应服务器看哪台服务器的负载不是很重,就将给哪一台去完成。
而分布式,从窄意上理解,也跟集群差不多, 但是它的组织比较松散,不像集群,有一个组织性,一台服务器垮了,其它的服务器可以顶上来。
分布式的每一个节点,都完成不同的业务,一个节点垮了,哪这个业务就不可访问了。
分布式是以缩短单个任务的执行时间来提升效率的,而集群则是通过提高单位时间内执行的任务数来提升效率。
举例:如果一个任务由10个子任务组成,每个子任务单独执行需1小时,则在一台服务器上执行该任务需10小时。
采用分布式方案,提供10台服务器,每台服务器只负责处理一个子任务,不考虑子任务间的依赖关系,执行完这个任务只需一个小时。(这种工作模式的一个典型代表就是Hadoop的Map/Reduce分布式计算模型)
而采用集群方案,同样提供10台服务器,每台服务器都能独立处理这个任务。假设有10个任务同时到达,10个服务器将同时工作,1小时后,10个任务同时完成,这样,整身来看,还是1小时内完成一个任务!
高并发:
处理高并发常见的方法有哪些?
1、HTML静态化 freemaker
其实大家都知道,效率最高、消耗最小的就是纯静态化的html页面,所以我们尽可能使我们的网站上的页面采 用静态页面来实现,这个最简单的方法其实也是最有效的方法。但是对于大量内容并且频繁更新的网站,我们无法全部手动去挨个实现,于是出现了我们常见的信息 发布系统CMS,像我们常访问的各个门户站点的新闻频道,甚至他们的其他频道,都是通过信息发布系统来管理和实现的,信息发布系统可以实现最简单的信息录 入自动生成静态页面,还能具备频道管理、权限管理、自动抓取等功能,对于一个大型网站来说,拥有一套高效、可管理的CMS是必不可少的。
除了门户和信息发布类型的网站,对于交互性要求很高的社区类型网站来说,尽可能的静态化也是提高性能的必要手段,将社区内的帖子、文章进行实时的静态化,有更新的时候再重新静态化也是大量使用的策略,像Mop的大杂烩就是使用了这样的策略,网易社区等也是如此。
同 时,html静态化也是某些缓存策略使用的手段,对于系统中频繁使用数据库查询但是内容更新很小的应用,可以考虑使用html静态化来实现,比如论坛中论 坛的公用设置信息,这些信息目前的主流论坛都可以进行后台管理并且存储再数据库中,这些信息其实大量被前台程序调用,但是更新频率很小,可以考虑将这部分 内容进行后台更新的时候进行静态化,这样避免了大量的数据库访问请求。
2、图片服务器分离
大家知道,对于Web服务器来说,不管 是 Apache、IIS还是其他容器,图片是最消耗资源的,于是我们有必要将图片与页面进行分离,这是基本上大型网站都会采用的策略,他们都有独立的图片服 务器,甚至很多台图片服务器。这样的架构可以降低提供页面访问请求的服务器系统压力,并且可以保证系统不会因为图片问题而崩溃,在应用服务器和图片服务器 上,可以进行不同的配置优化,比如apache在配置ContentType的时候可以尽量少支持,尽可能少的LoadModule,保证更高的系统消耗 和执行效率。
3、数据库集群和库表散列
大型网站都有复杂的应用,这些应用必须使用数据库,那么在面对大量访问的时候,数据库的瓶颈很快就能显现出来,这时一台数据库将很快无法满足应用,于是我们需要使用数据库集群或者库表散列。
在数据库集群方面,很多数据库都有自己的解决方案,Oracle、Sybase等都有很好的方案,常用的MySQL提供的Master/Slave也是类似的方案,您使用了什么样的DB,就参考相应的解决方案来实施即可。
上 面提到的数据库集群由于在架构、成本、扩张性方面都会受到所采用DB类型的限制,于是我们需要从应用程序的角度来考虑改善系统架构,库表散列是常用并且最 有效的解决方案。我们在应用程序中安装业务和应用或者功能模块将数据库进行分离,不同的模块对应不同的数据库或者表,再按照一定的策略对某个页面或者功能 进行更小的数据库散列,比如用户表,按照用户ID进行表散列,这样就能够低成本的提升系统的性能并且有很好的扩展性。sohu的论坛就是采用了这样的架 构,将论坛的用户、设置、帖子等信息进行数据库分离,然后对帖子、用户按照板块和ID进行散列数据库和表,最终可以在配置文件中进行简单的配置便能让系统 随时增加一台低成本的数据库进来补充系统性能。
4、缓存
缓存一词搞技术的都接触过,很多地方用到缓存。网站架构和网站开发中的缓存也是非常重要。这里先讲述最基本的两种缓存。高级和分布式的缓存在后面讲述。
架构方面的缓存,对Apache比较熟悉的人都能知道Apache提供了自己的缓存模块,也可以使用外加的Squid模块进行缓存,这两种方式均可以有效的提高Apache的访问响应能力。
网 站程序开发方面的缓存,Linux上提供的Memory Cache是常用的缓存接口,可以在web开发中使用,比如用Java开发的时候就可以调用MemoryCache对一些数据进行缓存和通讯共享,一些大 型社区使用了这样的架构。另外,在使用web语言开发的时候,各种语言基本都有自己的缓存模块和方法,PHP有Pear的Cache模块,Java就更多 了,.net不是很熟悉,相信也肯定有。
5、镜像
镜像是大型网站常采用的提高性能和数据安全性的方式,镜像的技术可以解决不同网 络接入商和地域带来的用户访问速度差异,比如ChinaNet和EduNet之间的差异就促使了很多网站在教育网内搭建镜像站点,数据进行定时更新或者实 时更新。在镜像的细节技术方面,这里不阐述太深,有很多专业的现成的解决架构和产品可选。也有廉价的通过软件实现的思路,比如Linux上的rsync等 工具。
6、负载均衡
负载均衡将是大型网站解决高负荷访问和大量并发请求采用的终极解决办法。
负载均衡技术发展了多年,有很多专业的服务提供商和产品可以选择,我个人接触过一些解决方法,其中有两个架构可以给大家做参考。
高可用:
通常企业级应用系统(特别是政府部门和大企业的应用系统)一般会采用安规的软硬件设备,如IOE(IBM的小型机、Oracle数据、EMC存储设备)系列。而一般互联网公司更多地采用PC级服务器(x86),开源的数据库(MySQL)和操作系统(Linux)组建廉价且高容错(硬件故障是常态)的应用集群。
(1)设计的目的?
保证服务器硬件故障服务依然可用,数据依然保存并能够被访问。
(2)主要的手段?
数据和服务的①冗余备份以及②失效转移:
对于服务而言,一旦某个服务器宕机,就将服务切换到其他可用的服务器上;
对于数据而言,如果某个磁盘损坏,就从备份的磁盘(事先就做好了数据的同步复制)读取数据。
高可用的服务
高可用的服务模块为业务产品提供基础公共服务,在大型站点中这些服务通常都独立分布式部署,被具体应用远程调用。
在具体实践中,有以下几点高可用的服务策略可以参考:
①分级管理:核心应用和服务具有更高的优先级,比如用户及时付款比能否评价商品更重要;
②超时设置:设置服务调用的超时时间,一旦超时后,通信框架抛出异常,应用程序则根据服务调度策略选择重试or请求转移到其他服务器上;
③异步调用:通过消息队列等异步方式完成,避免一个服务失败导致整个应用请求失败的情况。
不是所有服务都可以异步调用,对于获取用户信息这类调用,采用异步方式会延长响应时间,得不偿失。对于那些必须确认服务调用成功后才能继续进行下一步的操作的应用也不适合异步调用。
④服务降级:网站访问高峰期间,为了保证核心应用的正常运行,需要对服务降级。
降级有两种手段:一是拒绝服务,拒绝较低优先级的应用的调用,减少服务调用并发数,确保核心应用的正常运行;二是关闭功能,关闭部分不重要的服务,或者服务内部关闭部分不重要的功能,以节约系统开销,为核心应用服务让出资源;
⑤幂等性设计:保证服务重复调用和调用一次产生的结果相同;
高可用的数据
保证数据高可用的主要手段有两种:一是数据备份,二是失效转移机制;
①数据备份:又分为冷备份和热备份,冷备份是定期复制,不能保证数据可用性。热备份又分为异步热备和同步热备,异步热备是指多份数据副本的写入操作异步完成,而同步方式则是指多份数据副本的写入操作同时完成。
关系数据库的热备机制就是通常所说的主从同步机制,实践中通常使用读写分离的方法来访问Master和Slave数据库,也就是说写操作只访问Master库,读操作均访问Slave库。
②失效转移:若数据服务器集群中任何一台服务器宕机,那么应用程序针对这台服务器的所有读写操作都要重新路由到其他服务器,保证数据访问不会失败。
网站运行监控
”不允许没有监控的系统上线“
(1)监控数据采集
①用户行为日志收集:服务器端的日志收集和客户端的日志收集;目前许多网站逐步开发基于实时计算框架Storm的日志统计与分析工具;
②服务器性能监控:收集服务器性能指标,如系统Load、内存占用、磁盘IO等,及时判断,防患于未然;
③运行数据报告:采集并报告,汇总后统一显示,应用程序需要在代码中处理运行数据采集的逻辑;
(2)监控管理
①系统报警:配置报警阀值和值守人员联系方式,系统发生报警时,即使工程师在千里之外,也可以被及时通知;
②失效转移:监控系统在发现故障时,主动通知应用进行失效转移;
③自动优雅降级:为了应付网站访问高峰,主动关闭部分功能,释放部分系统资源,保证核心应用服务的正常运行;—>网站柔性架构的理想状态
主从切换
很好理解,当其中一台机器的服务宕机后,对于服务调用者来说,能够迅速的切换到其他可用服务,从服务升级为主服务,这种切换速度应当控制在秒级别(几秒钟)。
当宕机的服务恢复之后,自动变为从服务,主从服务角色切换。主从切换一定是要付出代价的,所以当主服务恢复之后,也就不再替换现有的主服务。
负载均衡
当服务的请求量比较高的时候,一台服务不能满足需求,这时候需要多台机器提供同样的服务,将所有请求分发到不同机器上。
高可用架构中应该具有丰富的负载均衡策略和易调节负载的方式。
甚至可以自动化智能调节,例如由于机器性能的原因,响应时间可能不一样,这时候可以向性能差的机器少一点分发量,保证各个机器响应时间的均衡。
易横向扩展
当用户量越来越多,已有服务不能承载更多的用户的时候,便需要对服务进行扩展,扩展的方式最好是不触动原有服务,对于服务的调用者是透明的。
负载均衡:
1.什么是负载均衡?
当一台服务器的性能达到极限时,我们可以使用服务器集群来提高网站的整体性能。那么,在服务器集群中,需要有一台服务器充当调度者的角色,用户的所有请求都会首先由它接收,调度者再根据每台服务器的负载情况将请求分配给某一台后端服务器去处理。
那么在这个过程中,调度者如何合理分配任务,保证所有后端服务器都将性能充分发挥,从而保持服务器集群的整体性能最优,这就是负载均衡问题。
下面详细介绍负载均衡的实现方式。
(1)HTTP重定向负载均衡。
这种负载均衡方案的优点是比较简单;
缺点是浏览器需要每次请求两次服务器才能拿完成一次访问,性能较差。
(2)DNS域名解析负载均衡
优点是将负载均衡工作交给DNS,省略掉了网络管理的麻烦;
缺点就是DNS可能缓存A记录,不受网站控制。
(3)反向代理负载均衡。
优点是部署简单;
缺点是反向代理服务器是所有请求和响应的中转站,其性能可能会成为瓶颈。
(4)IP负载均衡。
优点:IP负载均衡在内核进程完成数据分发,较反向代理均衡有更好的处理性能。
缺点:负载均衡的网卡带宽成为系统的瓶颈。
(5)数据链路层负载均衡。
避免负载均衡服务器网卡带宽成为瓶颈,是目前大型网站所使用的最广的一种负载均衡手段。
当用户向服务器发起请求时,请求首先被集群调度者截获;调度者根据某种分配策略,选择一台服务器,并将选中的服务器的IP地址封装在HTTP响应消息头部的Location字段中,并将响应消息的状态码设为302,最后将这个响应消息返回给浏览器。
当浏览器收到响应消息后,解析Location字段,并向该URL发起请求,然后指定的服务器处理该用户的请求,最后将结果返回给用户。
在使用HTTP重定向来实现服务器集群负载均衡的过程中,需要一台服务器作为请求调度者。用户的一项操作需要发起两次HTTP请求,一次向调度服务器发送请求,获取后端服务器的IP,第二次向后端服务器发送请求,获取处理结果。
调度服务器收到用户的请求后,究竟选择哪台后端服务器处理请求,这由调度服务器所使用的调度策略决定。
-
随机分配策略
当调度服务器收到用户请求后,可以随机决定使用哪台后端服务器,然后将该服务器的IP封装在HTTP响应消息的Location属性中,返回给浏览器即可。 -
轮询策略(RR)
调度服务器需要维护一个值,用于记录上次分配的后端服务器的IP。那么当新的请求到来时,调度者将请求依次分配给下一台服务器。
由于轮询策略需要调度者维护一个值用于记录上次分配的服务器IP,因此需要额外的开销;此外,由于这个值属于互斥资源,那么当多个请求同时到来时,为了避免线程的安全问题,因此需要锁定互斥资源,从而降低了性能。而随机分配策略不需要维护额外的值,也就不存在线程安全问题,因此性能比轮询要高。
采用HTTP重定向来实现服务器集群的负载均衡实现起来较为容易,逻辑比较简单,但缺点也较为明显。
在HTTP重定向方法中,调度服务器只在客户端第一次向网站发起请求的时候起作用。当调度服务器向浏览器返回响应信息后,客户端此后的操作都基于新的URL进行的(也就是后端服务器),此后浏览器就不会与调度服务器产生关系,进而会产生如下几个问题:
- 由于不同用户的访问时间、访问页面深度有所不同,从而每个用户对各自的后端服务器所造成的压力也不同。而调度服务器在调度时,无法知道当前用户将会对服务器造成多大的压力,因此这种方式无法实现真正意义上的负载均衡,只不过是把请求次数平均分配给每台服务器罢了。
- 若分配给该用户的后端服务器出现故障,并且如果页面被浏览器缓存,那么当用户再次访问网站时,请求都会发给出现故障的服务器,从而导致访问失败。
DNS是什么?
在了解DNS负载均衡之前,我们首先需要了解DNS域名解析的过程。
我们知道,数据包采用IP地址在网络中传播,而为了方便用户记忆,我们使用域名来访问网站。那么,我们通过域名访问网站之前,首先需要将域名解析成IP地址,这个工作是由DNS完成的。也就是域名服务器。
我们提交的请求不会直接发送给想要访问的网站,而是首先发给域名服务器,它会帮我们把域名解析成IP地址并返回给我们。我们收到IP之后才会向该IP发起请求。
那么,DNS服务器有一个天然的优势,如果一个域名指向了多个IP地址,那么每次进行域名解析时,DNS只要选一个IP返回给用户,就能够实现服务器集群的负载均衡。
首先需要将我们的域名指向多个后端服务器(将一个域名解析到多个IP上),再设置一下调度策略,那么我们的准备工作就完成了,接下来的负载均衡就完全由DNS服务器来实现。
当用户向我们的域名发起请求时,DNS服务器会自动地根据我们事先设定好的调度策略选一个合适的IP返回给用户,用户再向该IP发起请求。
一般DNS提供商会提供一些调度策略供我们选择,如随机分配、轮询、根据请求者的地域分配离他最近的服务器。
DNS负载均衡最大的优点就是配置简单。服务器集群的调度工作完全由DNS服务器承担,那么我们就可以把精力放在后端服务器上,保证他们的稳定性与吞吐量。而且完全不用担心DNS服务器的性能,即便是使用了轮询策略,它的吞吐率依然卓越。
此外,DNS负载均衡具有较强了扩展性,你完全可以为一个域名解析较多的IP,而且不用担心性能问题。
但是,由于把集群调度权交给了DNS服务器,从而我们没办法随心所欲地控制调度者,没办法定制调度策略。
DNS服务器也没办法了解每台服务器的负载情况,因此没办法实现真正意义上的负载均衡。它和HTTP重定向一样,只不过把所有请求平均分配给后端服务器罢了。
此外,当我们发现某一台后端服务器发生故障时,即使我们立即将该服务器从域名解析中去除,但由于DNS服务器会有缓存,该IP仍然会在DNS中保留一段时间,那么就会导致一部分用户无法正常访问网站。这是一个致命的问题!好在这个问题可以用动态DNS来解决。
动态DNS能够让我们通过程序动态修改DNS服务器中的域名解析。从而当我们的监控程序发现某台服务器挂了之后,能立即通知DNS将其删掉。
DNS负载均衡是一种粗犷的负载均衡方法,这里只做介绍,不推荐使用。
反向代理服务器是一个位于实际服务器之前的服务器,所有向我们网站发来的请求都首先要经过反向代理服务器,服务器根据用户的请求要么直接将结果返回给用户,要么将请求交给后端服务器处理,再返回给用户。
之前我们介绍了用反向代理服务器实现静态页面和常用的动态页面的缓存。接下来我们介绍反向代理服务器更常用的功能——实现负载均衡。
我们知道,所有发送给我们网站的请求都首先经过反向代理服务器。那么,反向代理服务器就可以充当服务器集群的调度者,它可以根据当前后端服务器的负载情况,将请求转发给一台合适的服务器,并将处理结果返回给用户。
优点
- 隐藏后端服务器。
与HTTP重定向相比,反向代理能够隐藏后端服务器,所有浏览器都不会与后端服务器直接交互,从而能够确保调度者的控制权,提升集群的整体性能。 - 故障转移
与DNS负载均衡相比,反向代理能够更快速地移除故障结点。当监控程序发现某一后端服务器出现故障时,能够及时通知反向代理服务器,并立即将其删除。 - 合理分配任务
HTTP重定向和DNS负载均衡都无法实现真正意义上的负载均衡,也就是调度服务器无法根据后端服务器的实际负载情况分配任务。但反向代理服务器支持手动设定每台后端服务器的权重。我们可以根据服务器的配置设置不同的权重,权重的不同会导致被调度者选中的概率的不同。
缺点
- 调度者压力过大
由于所有的请求都先由反向代理服务器处理,那么当请求量超过调度服务器的最大负载时,调度服务器的吞吐率降低会直接降低集群的整体性能。 - 制约扩展
当后端服务器也无法满足巨大的吞吐量时,就需要增加后端服务器的数量,可没办法无限量地增加,因为会受到调度服务器的最大吞吐量的制约。
反向代理服务器会引起一个问题。若某台后端服务器处理了用户的请求,并保存了该用户的session或存储了缓存,那么当该用户再次发送请求时,无法保证该请求仍然由保存了其Session或缓存的服务器处理,若由其他服务器处理,先前的Session或缓存就找不到了。
解决办法1:
可以修改反向代理服务器的任务分配策略,以用户IP作为标识较为合适。相同的用户IP会交由同一台后端服务器处理,从而就避免了粘滞会话的问题。
解决办法2:
可以在Cookie中标注请求的服务器ID,当再次提交请求时,调度者将该请求分配给Cookie中标注的服务器处理即可。
基于IP的负载均衡方式
1.通过NAT实现负载均衡
运作过程
- 客户端会向一个ip地址发出请求,这个ip地址是一个
VIP
(虚拟IP),这也是调度器向外公布的一个地址。 - 请求达到调度器,调度器会根据负载均衡算法(详情请见8种负载均衡算法)从
RealServer
列表中选取一个负载不高的服务器,然后把请求报文的目标地址,也就是VIP
和端口通过iptables
进行NAT
转换成选中的服务器的真实ip地址。最后,调度器会把其连接保存在一个hash表中,只要这个连接下次再发请求报文过来就会把其分发到上次选定的服务器中。 RealServer
收到报文之后,会把响应返回给调度器。- 调度器收到报文之后,会把源地址和源端口改为虚拟ip和端口,最后再返回给客户端。
特点
1.RealServer
和调度器必须位于一个ip网络之中。
2.调度器位于RealServer
和客户端之间,处理进出的通信。
3.RIP
通常是内部地址,仅用于集群之间通信。
4.RealServer
的网关必须指向调度器。
5.支持端口映射,RealServer
没必要跟调度器一个端口。
限制
响应报文一般比较大,每一次都需要NAT
转换的话,大流量的时候,会导致调度器成为一个瓶颈。
配图
image.png
2.通过直接路由实现负载均衡
描述
由于网络请求有一个特点,就是响应报文往往都是比请求报文大很多的,这就会造成上面的nat每次转发收到机器负载的影响,会成为这个请求的一个瓶颈。因此VS/DR
这个方案可以通过直接路由的方式,只转发请求,而相应则由RealServer
去直接响应给客户端,这样可以极高提高吞吐量。
运作过程
- 客户端请求一个
VIP
,这个ip地址就是调度器对外公布的地址。 - 请求到达调度器之后,调度器根据负载算法去调度请求,分发给特定的
RealServer
,调度器不会修改ip和端口,只会mac地址改为把选出的RealServer
的mac地址,RealServer
将会收到对应的报文。 RealServer
收到报文之后,发现报文的目标地址VIP
,处理结束之后,会通过路由表将响应返回给客户端。
特点
- 集群节点,
RealServer
和调度器要在同一个物理网络之中。 RIP
通常是私有网络,当然也可以是公开网络,方便监控和管理。- 调度器只负责调度请求,响应会由服务器直接对客户端进行响应。
RealServer
不能指向调度器的网关。- 不支持端口映射。
3. VS/TUN 实现虚拟服务器
描述
由于VS/DR
限制RealServer
和调度器在同一个物理网络,因此无法分散在各地,VS/TUN
就能解决这个问题。
运作过程
1.客户端通过VIP
发送请求,通过一个ip隧道,将一个ip报文封装到另一个ip报文,这样可以让目标为一个ip的地址数据转发到另一个ip地址。
2.调度器根据负载均衡算法去选择一台RealServer
,再把封装后的ip报文发送过去。
3.RealServer
获取到报文之后解封报文,获取到原来目标为VIP
的报文,服务器发现这个VIP
是位于本地的IP隧道中就会处理这个这个请求,并通过路由表去把响应报文直接回复给客户端。
特点
RealServer
和调度器必须可以公网访问。RIP
必须是公网地址。- 调度器只分配和转发请求给
RealServer
,响应报文则由RealSever
直接响应给客户端。 RealServer
的网关不能指向调度器。- 不支持端口映射。
数据链路层的负载均衡
数据链路层负载均衡其实也就是网卡的负载均衡,在下面的应用情况下,就要考虑对网卡进行负载均衡:
- 某个服务器跑的应用非高峰期间都能达到500M以上,晚高峰一般能够超过1G,主流服务器的网卡都是千兆的,超过1G的流量明显会导致丢包的问题,此时又不能停止业务对网卡进行更换,所以必须在增加一个网卡来联合提供服务,所以就必须把多张网卡捆绑做成一个逻辑网卡。
- 对网卡的高可用性要求,某些业务必须要求网卡层面的高可用性,所以必须捆绑多个网卡。
对于linux系统来说,数据链路层的解决方案就是实现多个网卡绑定,即linux bonding,在思科交换机上这称为以太网通道(Ether Channel)
linux bonding
在配置之前,我们先说说linux bonding的七种模式:
七种bond模式说明:
第一种模式:mod=0 ,即:(balance-rr) Round-robin policy(平衡抡循环策略)
特点:传输数据包顺序是依次传输(即:第1个包走eth0,下一个包就走eth1….一直循环下去,直到最后一个传输完毕),此模式提供负载平衡和容错能力;但是我们知道如果一个连接或者会话的数据包从不同的接口发出的话,中途再经过不同的链路,在客户端很有可能会出现数据包无序到达的问题,而无序到达的数据包需要重新要求被发送,这样网络的吞吐量就会下降
第二种模式:mod=1,即: (active-backup) Active-backup policy(主-备份策略)
特点:只有一个设备处于活动状态,当一个宕掉另一个马上由备份转换为主设备。mac地址是外部可见得,从外面看来,bond的MAC地址是唯一的,以避免switch(交换机)发生混乱。此模式只提供了容错能力;由此可见此算法的优点是可以提供高网络连接的可用性,但是它的资源利用率较低,只有一个接口处于工作状态,在有 N 个网络接口的情况下,资源利用率为1/N
第三种模式:mod=2,即:(balance-xor) XOR policy(平衡策略)
特点:基于指定的传输HASH策略传输数据包。缺省的策略是:(源MAC地址 XOR 目标MAC地址) % slave数量。其他的传输策略可以通过xmit_hash_policy选项指定,此模式提供负载平衡和容错能力
第四种模式:mod=3,即:broadcast(广播策略)
特点:在每个slave接口上传输每个数据包,此模式提供了容错能力
第五种模式:mod=4,即:(802.3ad) IEEE 802.3adDynamic link aggregation(IEEE 802.3ad 动态链接聚合)
特点:创建一个聚合组,它们共享同样的速率和双工设定。根据802.3ad规范将多个slave工作在同一个激活的聚合体下。
外出流量的slave选举是基于传输hash策略,该策略可以通过xmit_hash_policy选项从缺省的XOR策略改变到其他策略。需要注意的是,并不是所有的传输策略都是802.3ad适应的,尤其考虑到在802.3ad标准43.2.4章节提及的包乱序问题。不同的实现可能会有不同的适应性。
必要条件:
条件1:ethtool支持获取每个slave的速率和双工设定
条件2:switch(交换机)支持IEEE 802.3ad Dynamic link aggregation
条件3:大多数switch(交换机)需要经过特定配置才能支持802.3ad模式
第六种模式:mod=5,即:(balance-tlb) Adaptive transmit load balancing(适配器传输负载均衡)
特点:不需要任何特别的switch(交换机)支持的通道bonding。在每个slave上根据当前的负载(根据速度计算)分配外出流量。如果正在接受数据的slave出故障了,另一个slave接管失败的slave的MAC地址。
该模式的必要条件:ethtool支持获取每个slave的速率
第七种模式:mod=6,即:(balance-alb) Adaptive load balancing(适配器适应性负载均衡)
特点:该模式包含了balance-tlb模式,同时加上针对IPV4流量的接收负载均衡(receive load balance, rlb),而且不需要任何switch(交换机)的支持。接收负载均衡是通过ARP协商实现的。bonding驱动截获本机发送的ARP应答,并把源硬件地址改写为bond中某个slave的唯一硬件地址,从而使得不同的对端使用不同的硬件地址进行通信。
现在网络中常见的的负载均衡主要分为两种:
一种是通过硬件来进行进行, 常见的硬件有比较昂贵的NetScaler、F5、Radware和Array等商用的负载均衡器, 也有类似于LVS、Nginx、HAproxy的基于Linux的开源的负载均衡策略, 商用负载均衡里面NetScaler从效果上比F5的效率上更高。对于负载均衡器来说, 不过商用负载均衡由于可以建立在四~七层协议之上,因此适用面更广所以有其不可替代性, 他的优点就是有专业的维护团队来对这些服务进行维护、缺点就是花销太大, 所以对于规模较小的网络服务来说暂时还没有需要使用。
另一种负载均衡的方式是通过软件:比较常见的有LVS、Nginx、HAproxy等, 其中LVS是建立在四层协议上面的,而另外Nginx和HAproxy是建立在七层协议之上的
LVS:使用集群技术和Linux操作系统实现一个高性能、高可用的服务器, 它具有很好的可伸缩性(Scalability)、可靠性(Reliability)和可管理性(Manageability)。
LVS的特点是:
1、抗负载能力强、是工作在网络4层之上仅作分发之用,没有流量的产生;
2、配置性比较低,这是一个缺点也是一个优点,因为没有可太多配置的东西, 所以并不需要太多接触,大大减少了人为出错的几率;
3、工作稳定,自身有完整的双机热备方案;
4、无流量,保证了均衡器IO的性能不会收到大流量的影响;
5、应用范围比较广,可以对所有应用做负载均衡;
6、LVS需要向IDC多申请一个IP来做Visual IP,因此需要一定的网络知识,所以对操作人的要求比较高。
Nginx的特点是:
1、工作在网络的7层之上,可以针对http应用做一些分流的策略,比如针对域名、目录结构;
2、Nginx对网络的依赖比较小;
3、Nginx安装和配置比较简单,测试起来比较方便;
4、也可以承担高的负载压力且稳定,一般能支撑超过1万次的并发;
5、Nginx可以通过端口检测到服务器内部的故障, 比如根据服务器处理网页返回的状态码、超时等等, 并且会把返回错误的请求重新提交到另一个节点,不过其中缺点就是不支持url来检测;
6、Nginx对请求的异步处理可以帮助节点服务器减轻负载;
7、Nginx能支持http和Email,这样就在适用范围上面小很多;
8、不支持Session的保持、对Big request header的支持不是很好, 另外默认的只有Round-robin和IP-hash两种负载均衡算法。 HAProxy的特点是:
1、HAProxy是工作在网络7层之上。
2、能够补充Nginx的一些缺点比如Session的保持,Cookie的引导等工作
3、支持url检测后端的服务器出问题的检测会有很好的帮助。
4、更多的负载均衡策略比如:动态加权轮循(Dynamic Round Robin), 加权源地址哈希(Weighted Source Hash), 加权URL哈希和加权参数哈希(Weighted Parameter Hash)已经实现
5、单纯从效率上来讲HAProxy更会比Nginx有更出色的负载均衡速度。
6、HAProxy可以对Mysql进行负载均衡,对后端的DB节点进行检测和负载均衡。
现在网站发展的趋势对网络负载均衡的使用是随着网站规模的提升根据不同的阶段来使用不同的技术:
第一阶段:利用Nginx或者HAProxy进行单点的负载均衡, 这一阶段服务器规模刚脱离开单服务器、单数据库的模式,需要一定的负载均衡, 但是 仍然规模较小没有专业的维护团队来进行维护,也没有需要进行大规模的网站部署。 这样利用Nginx或者HAproxy就是第一选择,此时这些东西上手快, 配置容易, 在七层之上利用HTTP协议就可以。这时是第一选择
第二阶段:随着网络服务进一步扩大,这时单点的Nginx已经不能满足, 这时使用LVS或者商用F5就是首要选择,Nginx此时就作为LVS或者 F5的节点来使用, 具体LVS或者F5的是选择是根据公司规模,人才以及资金能力来选择的,这里也不做详谈, 但是一般来说这阶段相关人才跟不上业务的提 升,所以购买商业负载均衡已经成为了必经之路。
第三阶段:这时网络服务已经成为主流产品,此时随着公司知名度也进一步扩展, 相关人才的能力以及数量也随之提升,这时无论从开发适合自身产品的定制, 以及降低成本来讲开源的LVS,已经成为首选,这时LVS会成为主流。 最终形成比较理想的状态为:F5/LVS<—>Haproxy<—>Squid/Varnish<—>AppServer