[负载均衡]
大量用户发起请求的情况下, 服务器负载过高, 导致部分请求无法被响应或者及时响应.
负载均衡根据一定的算法将请求分发到不同的后端, 保证所有的请求都可以被正常的下发并返回.
[主流实现 - LVS]
LVS 是 Linux Virtual Server 的简称, 也就是 Linux 虚拟服务器, 已经是 Linux 标准内核的一部分.
采用 IP 负载均衡技术和基于内容请求分发.
调度器具有很好的吞吐率, 将请求均衡得转移到不同的服务器上执行, 且调度器可以自动屏蔽掉故障的服务器, 从而将一组服务器构成一个高可用, 高性能的服务器集群.
* 负载均衡机制
1. LVS 是四层负载均衡, 也就是说在传输层上, LVS 支持 TCP/UDP. 由于是四层负载均衡, 所以相对于其他的高层负载均衡而言, 对于 DNS 域名轮流解析, 应用层负载的调度, 客户端的调度等, 它的效率是相对较高的.
2. 四层负载均衡, 主要通过报文的目标地址和端口.(七层负载均衡又称为 "内容交换", 主要是通过报文中真正有意义的应用层内容)
3. LVS 的转发主要通过修改 IP 地址 (NAT 模式, 包括 SNAT 和 DNAT), 修改目标 Mac(DR 模式) 来实现.
* 负载均衡模式 - NAT 模式
NAT(Network Address Translation)是一种外网和内网地址映射的技术.
NAT 模式下, 网络数据包的进出都要经过 LVS 的处理. LVS 需要作为 RS(真实服务器)的网关.
当包从 Client 到达 LVS 时, LVS 做 DNAT(目标地址转换), 将 D-IP(目的地址)改变为 RS 的 IP.
RS 处理完成, 将包返回的时候, S-IP(源地址)是 RS,D-IP 是 Client 的 IP.
到达 LVS 做网关中转时, LVS 会做 SNAT(源地址转换), 将包的 S-IP 改为 VIP.
* 负载均衡模式 - DR 模式
DR(直接路由)模式下需要 LVS 和 RS 绑定同一个集群(RS 通过将 VIP 绑定在 loopback 实现).
请求由 LVS 接受, 返回的时候由 RS 直接返回给 Client.
当包到 LVS 的时候, LVS 将网络帧的 Mac 地址修改为某台 RS 的 Mac, 此包会被转发到对应的 RS 上面进行处理.
此时 S-IP 和 D-IP 都没有发生改变.
RS 收到 LVS 转发的包时, 链路层发现 Mac 地址是自己的, 网络层发现 IP 地址也是自己的, 于是包被合法接受, RS 不感知 LVS.
当包返回时, RS 直接返回给 Client, 不再经过 LVS.
由于 RS 响应的数据包是直接返回给 Client 的, 所以有效得避免了负载均衡服务器的带宽成为瓶颈.
* 负载均衡模式 - IP 隧道模式
隧道模式有点类似与 VPN, 使用网络分层的原理, 在从客户端发来的数据包的基础上, 封装一个新的 IP 头标记 (不完整, 只有目的 IP) 发送给 RS.
RS 收到后, 先把 DR 发过来的数据包的头解开, 还原数据包. 处理完成后, 直接返回给 Client.
* 负载均衡模式 - 总结
综上所述, DR 模式具有更好的性能, 也是目前大型网站比较通用的一种模式.
*LVS 调度算法
限于篇幅, 只介绍部分算法.
1. 轮询调度
2. 加权轮询调度
3. 最小连接数调度
4. 加权最小连接数调度
5. 基于局部性的最少连接(LBLC)
该算法主要用于 Cache 集群系统.
该算法根据请求的 D-IP 找出该 D-IP 地址最近使用的服务器地址, 如果此服务器可用, 则发送给此服务器. 如果不可用, 则使用最小连接数算法选择一个服务器发送报文.
6. 带复制的基于局部性的最少连接(LCLBR)
它与 LBLC 算法的不同之处是它要维护从一个目标 IP 地址到一组服务器的映射, 而 LBLC 算法维护从一个目标 IP 地址到一台服务器的映射.
在 LBLC 算法里面, 某些热门站点报文较多, 可能服务器很快会达到饱和, 然后切换到第二台又会很快达到饱和, 然后后端服务器就一直在切换, 造成资源不必要的浪费.
LCLBR 里面, 单个服务器变成了一组服务器, 就会有效避免这种情况.
7. 目标地址散列
8. 源地址散列
*LVS 的优点
1. 抗负载能力强, 由于工作在传输层上, 只做分发, 无流量产生, 所以它在所有的负载均衡里面性能是最强的, 对内存和 CPU 的消耗也比较低.
2. 配置性较低, 减少人为出错的概率, 但是也相应减少了人为自主性.
3. 工作稳定, 自身有完整的双机热备方案, 如: LVS + Keepalived
4. 无流量, 保证 IO 不会受到影响.
*LVS 的缺点
1. 软件本身不支持正则表达式处理, 不能做动静分离.
2. 网站应用比较庞大的时候, LVS/DR+Keepalive 实施较为复杂.
[主流实现 - Nginx]
Nginx 是一个很强大的高性能 web 和反向代理服务器.
最大的优势在于高负载情况下对内存和 CPU 的低消耗.
在高并发的情况下, Nginx 是 Apache 服务器不错的替代品.
* 传统基于进程或线程的模型
传统基于进程或线程的模型 (如 Apache) 在处理并发时会为每一个连接建立一个单独的进程或线程. 这种方法会在网络传输或者 I/O 操作上阻塞.
对于应用来讲, 在内存和 CPU 的使用上效率都是非常低的.
而且, 生成一个单独的进程 / 线程还需要为其准备新的运行环境(主要包括分配堆栈内存), 以及上下文执行环境.
创建这些都消耗额外的 CPU 时间, 这最终也会因为线程上下文来回切换导致性能非常差.
*Nginx 架构设计
Nginx 的架构设计是采用模块化的, 基于事件驱动, 异步, 单线程且非阻塞.
Nginx 大量使用多路复用和事件通知, nginx 启动之后, 会在系统中以 daemon(守护进程) 的方式在后台运行, 包括一个 master 进程和多个 worker 进程.
所有的进程都是单线程的, 进程间通信主要通过共享内存的方式.
多个连接, 是通过 worker 进程中高效回环 (run-loop) 机制来处理的. 对于每个 worker 进程来说, 每秒钟可以处理上千个请求和连接.
*Nginx 负载均衡
Nginx 负载均衡主要针对七层的 http 和 https, 当然, 四层 Nginx 后来也支持了(1.9.0 版本增加 stream 模块, 用来实现四层协议).
Nginx 主要是通过反向代理的方式进行负载均衡的, 所谓反向代理(Reverse Proxy), 指的是以代理服务器来接收 Client 请求, 然后将请求转发到内部服务器, 并将内部服务器处理完成的结果返回给 Client , 对外, 代理服务器就是真正的服务器, 内部服务器外部不感知.
Nginx 支持以下几种策略:
轮询. default
- weight (权重)
- ip_hash (可用于解决会话保持的问题)
fair. 第三方 (按后端服务器的响应时间来分配请求, 响应时间短的优先分配)
url_hash. 第三方 (相同的 url 定位到相同的服务器)
*Nginx 的优势
1. 跨平台, 配置简单
2. 非阻塞, 高并发(官方测试可以支撑 5 万并发数)
3. 事件驱动, 通信机制采用 epoll 模型, 支持更大的并发连接
4. 内存消耗小.(3 万并发数下, 10 个 Nginx 进程只需要 150M 内存)
5. 内置的健康检查功能. (一台后端服务器宕机了, 不会影响前端访问)
6. 节省带宽. (支持 GZIP 压缩, 可以添加浏览器缓存的 header)
7. 稳定性高. (反向代理, 宕机的概率很小)
*Nginx 的缺点
1. 对后端服务器的健康检查, 只支持通过端口检测, 不支持 url 检测.
2. 不支持 Session 的直接保持.(通过 ip_hash 可解决)
[主流实现 - Haproxy]
Haproxy 提供高可用性, 负载均衡以及基于 TCP 和 HTTP 的代理.
特别适用于那些负载特大的 Web 站点, 这些站点通常需要会话保持或七层处理.
Haproxy 支持四层和七层两种负载模式.
Haproxy 有一些 Nginx 不具有的优点, 比如支持 Session 的保持, Cookie 的引导; 同时支持通过获取指定的 URL 来检测后端服务器的状态.
Haproxy 和 LVS 类似, 本身就只是一款负载均衡软件; 单纯从效率上来讲, 比 Nginx 有更好的负载均衡速度, 在并发处理上也优于 Nginx.
Haproxy 支持的负载均衡策略也比较多: Round-robin(轮循),Weight-round-robin(带权轮循),source(原地址保持),RI(请求 URL),rdp-cookie(根据 cookie).
[三种负载均衡的比较]
比较 | HAProxy | Nginx | LVS |
优点 | 支持 session 保持,Cookie 引导。
可通过 url 检测后端服务器健康状态。
也可做 MySQL、Email 等负载均衡。
支持通过指定的 URL 对后端服务器健康检查。 | http、https、Emai 协议功能较好,处理相应请求快。
Web 能力强,配置简单,支持缓存功能、适用动静分离,低内存消耗。
支持 WebSocket 协议。
支持强大的正则匹配规则 。 | 通过 vrrp 转发(仅分发)效率高,流量通过内核处理,没有流量产生。(理论)
相当稳定可靠。
|
缺点 | 一般不做 Web 服务器的 Cache。 | 不支持 session 直接保持,但可通过 ip_hash 解决。 只能通过端口对后端服务器健康检查。 | 不支持正则,不能做动静分离,配置略复杂,需要 IP 略多。 没有后端主机健康状态检查。 |
支持算法 | 目标 uri hash(uri) url 参数 (url_params) 请求头信息调度 (hdr(name)) cookie (rdp-cookie) | 最小响应时间 自定义 hash 内容 (hash key [consistent]) url hash 最短时间和最少连接 | 最短期望延迟 (Shortest Expected Delay) 不排队 (Never Queue) 基于局部性的最少连接 (LBLC) 带复制的基于局部性最少链接 (LCLBR) |
官网 | http://www.linuxvirtualserver.org/
| ||
虚拟主机 | 支持 | 支持 | 不支持 |
适用性 | 四层,七层(常用) | 四层,七层(常用) | 四层 |
量级 | 七层重量级,四层轻量级 | 七层重量级,四层轻量级 | 四层重量级 |
常用热备 | Keepalived + 其它 | Keepalived + 其它 | Keepalived + 其它 |
* 补充区别
HAProxy 对于后端服务器会一直做健康检测(就算请求没过来的时候也会做健康检查)
后端机器故障发生在请求还没到来的时候, haproxy 会将这台故障机切掉, 但如果后端机器故障发生在请求到达期间, 那么前端访问会有异常.
也就是说 HAProxy 会把请求转到后端的这台故障机上, 并经过多次探测后才会把这台机器切掉, 并把请求发给其他正常的后端机, 这势必会造成一小段时间内前端访问失败.
Nginx 对于后端的服务器不会一直做健康检测
后端机器发生故障, 在请求过来的时候, 分发还是会正常进行分发, 只是请求不到数据的时候, 它会再转向好的后端机器进行请求, 直到请求正常为止.
也就是说 Nginx 请求转到后端一台不成功的机器的话, 还会再转向另外一台服务器, 这对前端访问没有什么影响.
因此, 如果有用 HAProxy 做为前端负载均衡的话 , 如果后端服务器要维护, 在高并发的情况, 肯定是会影响用户的.
但如果是 Nginx 做为前端负载均衡的话, 只要并发撑得住, 后端切掉几台不会影响到用户.
[Openstack LBaaS 的现状]
Neutron 中的 loadbalance 服务 lbaas, 可以将来自公网或内部网络的访问流量, 分发到云资源中的云主机上, 可以随时添加或者减少后端云主机的数量, 而不影响业务.
lbaas 在 Grizzly 版本集成到 Neutron 中.
现在社区最新的 API 版本为 V2, 在 Kilo 中发布, 包含以下概念:
Lbaas V1 与 V2 的区别如下:
功能 | lbaas | lbaasV2 |
最大连接数 | Y | Y |
TCP 负载均衡 | Y | Y |
HTTP 负载均衡 | Y | Y |
HTTPS 负载均衡 | Y | Y |
TERMINATED_HTTPS 负载均衡 | X | Y |
基于 hostname 的 url 转发 | X | Y |
基于 path 的 url 转发 | X | Y |
基于 filename 的 url 转发 | X | Y |
基于 header 的 url 转发 | X | Y |
基于 cookie 的 url 转发 | X | Y |
一个 vip 支持多种协议和端口 | X | Y |
[Octavia 介绍]
Octavia 当前作为 lbaasV2 的一个 driver 存在, 完全兼容 lbaasV2 的接口, 最终的发展趋势会作为一个独立的项目代替 lbaasV2.
架构图如下:
网络结构如下:
[参考]
octavia 相关: https://docs.openstack.org/octavia/latest/
nginx 相关: nginx.org
lvs 相关: https://www.jianshu.com/p/16e9c84fdb3c
来源: https://www.cnblogs.com/liuxia912/p/11143447.html