CS-Notes/docs/notes/集群.md
2019-12-06 00:29:51 +08:00

209 lines
9.4 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!-- GFM-TOC -->
* [负载均衡](#一负载均衡)
* [负载均衡算法](#负载均衡算法)
* [转发实现](#转发实现)
* [集群下的 Session 管理](#二集群下的-session-管理)
* [Sticky Session](#sticky-session)
* [Session Replication](#session-replication)
* [Session Server](#session-server)
<!-- GFM-TOC -->
# 负载均衡
集群中的应用服务器节点通常被设计成无状态用户可以请求任何一个节点
负载均衡器会根据集群中每个节点的负载情况将用户请求转发到合适的节点上
负载均衡器可以用来实现高可用以及伸缩性
- 高可用当某个节点故障时负载均衡器会将用户请求转发到另外的节点上从而保证所有服务持续可用
- 伸缩性根据系统整体负载情况可以很容易地添加或移除节点
负载均衡器运行过程包含两个部分
1. 根据负载均衡算法得到转发的节点
2. 进行转发
## 负载均衡算法
### 1. 轮询Round Robin
轮询算法把每个请求轮流发送到每个服务器上
下图中一共有 6 个客户端产生了 6 个请求 6 个请求按 (1, 2, 3, 4, 5, 6) 的顺序发送(1, 3, 5) 的请求会被发送到服务器 1(2, 4, 6) 的请求会被发送到服务器 2
<div align="center"> <img src="pics/9daa3616-00a4-48c4-9146-792dc8499be3.jpg" width="500px"/> </div><br>
该算法比较适合每个服务器的性能差不多的场景如果有性能存在差异的情况下那么性能较差的服务器可能无法承担过大的负载下图的 Server 2
<div align="center"> <img src="pics/bfea8772-d01b-4a51-8adc-edfd7d3dce84.jpg" width="500px"/> </div><br>
### 2. 加权轮询Weighted Round Robbin
加权轮询是在轮询的基础上根据服务器的性能差异为服务器赋予一定的权值性能高的服务器分配更高的权值
例如下图中服务器 1 被赋予的权值为 5服务器 2 被赋予的权值为 1那么 (1, 2, 3, 4, 5) 请求会被发送到服务器 1(6) 请求会被发送到服务器 2
<div align="center"> <img src="pics/4ab87717-e264-4232-825d-8aaf08f14e8b.jpg" width="500px"/> </div><br>
### 3. 最少连接least Connections
由于每个请求的连接时间不一样使用轮询或者加权轮询算法的话可能会让一台服务器当前连接数过大而另一台服务器的连接过小造成负载不均衡
例如下图中(1, 3, 5) 请求会被发送到服务器 1但是 (1, 3) 很快就断开连接此时只有 (5) 请求连接服务器 1(2, 4, 6) 请求被发送到服务器 2只有 (2) 的连接断开此时 (6, 4) 请求连接服务器 2该系统继续运行时服务器 2 会承担过大的负载
<div align="center"> <img src="pics/e98deb5a-d5d4-4294-aa9b-9220d4483403.jpg" width="500px"/> </div><br>
最少连接算法就是将请求发送给当前最少连接数的服务器上
例如下图中服务器 1 当前连接数最小那么新到来的请求 6 就会被发送到服务器 1
<div align="center"> <img src="pics/43d323ac-9f07-4e4a-a315-4eaf8c38766c.jpg" width="500px"/> </div><br>
### 4. 加权最少连接Weighted Least Connection
在最少连接的基础上根据服务器的性能为每台服务器分配权重再根据权重计算出每台服务器能处理的连接数
### 5. 随机算法Random
把请求随机发送到服务器上
和轮询算法类似该算法比较适合服务器性能差不多的场景
<div align="center"> <img src="pics/a42ad3a7-3574-4c48-a783-ed3d08a0688a.jpg" width="500px"/> </div><br>
### 6. 源地址哈希法 (IP Hash)
源地址哈希通过对客户端 IP 计算哈希值之后再对服务器数量取模得到目标服务器的序号
可以保证同一 IP 的客户端的请求会转发到同一台服务器上用来实现会话粘滞Sticky Session
<div align="center"> <img src="pics/0f399a9f-1351-4b2d-b8a4-2ebe82b1a703.jpg" width="500px"/> </div><br>
## 转发实现
### 1. HTTP 重定向
HTTP 重定向负载均衡服务器使用某种负载均衡算法计算得到服务器的 IP 地址之后将该地址写入 HTTP 重定向报文中状态码为 302客户端收到重定向报文之后需要重新向服务器发起请求
缺点
- 需要两次请求因此访问延迟比较高
- HTTP 负载均衡器处理能力有限会限制集群的规模
该负载均衡转发的缺点比较明显实际场景中很少使用它
<div align="center"> <img src="pics/02a1fbfd-7a9d-4114-95df-ca2445587a1f.jpg" width="500px"/> </div><br>
### 2. DNS 域名解析
DNS 解析域名的同时使用负载均衡算法计算服务器 IP 地址
优点
- DNS 能够根据地理位置进行域名解析返回离用户最近的服务器 IP 地址
缺点
- 由于 DNS 具有多级结构每一级的域名记录都可能被缓存当下线一台服务器需要修改 DNS 记录时需要过很长一段时间才能生效
大型网站基本使用了 DNS 做为第一级负载均衡手段然后在内部使用其它方式做第二级负载均衡也就是说域名解析的结果为内部的负载均衡服务器 IP 地址
<div align="center"> <img src="pics/d2c072cc-8b17-480c-813e-18cdb3b4b51f.jpg" width="500px"/> </div><br>
### 3. 反向代理服务器
反向代理服务器位于源服务器前面用户的请求需要先经过反向代理服务器才能到达源服务器反向代理可以用来进行缓存日志记录等同时也可以用来做为负载均衡服务器
在这种负载均衡转发方式下客户端不直接请求源服务器因此源服务器不需要外部 IP 地址而反向代理需要配置内部和外部两套 IP 地址
优点
- 与其它功能集成在一起部署简单
缺点
- 所有请求和响应都需要经过反向代理服务器它可能会成为性能瓶颈
### 4. 网络层
在操作系统内核进程获取网络数据包根据负载均衡算法计算源服务器的 IP 地址并修改请求数据包的目的 IP 地址最后进行转发
源服务器返回的响应也需要经过负载均衡服务器通常是让负载均衡服务器同时作为集群的网关服务器来实现
优点
- 在内核进程中进行处理性能比较高
缺点
- 和反向代理一样所有的请求和响应都经过负载均衡服务器会成为性能瓶颈
### 5. 链路层
在链路层根据负载均衡算法计算源服务器的 MAC 地址并修改请求数据包的目的 MAC 地址并进行转发
通过配置源服务器的虚拟 IP 地址和负载均衡服务器的 IP 地址一致从而不需要修改 IP 地址就可以进行转发也正因为 IP 地址一样所以源服务器的响应不需要转发回负载均衡服务器可以直接转发给客户端避免了负载均衡服务器的成为瓶颈
这是一种三角传输模式被称为直接路由对于提供下载和视频服务的网站来说直接路由避免了大量的网络传输数据经过负载均衡服务器
这是目前大型网站使用最广负载均衡转发方式 Linux 平台可以使用的负载均衡服务器为 LVSLinux Virtual Server
参考
- [Comparing Load Balancing Algorithms](http://www.jscape.com/blog/load-balancing-algorithms)
- [Redirection and Load Balancing](http://slideplayer.com/slide/6599069/#)
# 集群下的 Session 管理
一个用户的 Session 信息如果存储在一个服务器上那么当负载均衡器把用户的下一个请求转发到另一个服务器由于服务器没有用户的 Session 信息那么该用户就需要重新进行登录等操作
## Sticky Session
需要配置负载均衡器使得一个用户的所有请求都路由到同一个服务器这样就可以把用户的 Session 存放在该服务器中
缺点
- 当服务器宕机时将丢失该服务器上的所有 Session
<div align="center"> <img src="pics/1623f524-b011-40c8-b83f-eab38d538f76.png" width="400px"/> </div><br>
## Session Replication
在服务器之间进行 Session 同步操作每个服务器都有所有用户的 Session 信息因此用户可以向任何一个服务器进行请求
缺点
- 占用过多内存
- 同步过程占用网络带宽以及服务器处理器时间
<div align="center"> <img src="pics/40c6570d-c1d7-4c38-843e-ba991b2328c2.png" width="400px"/> </div><br>
## Session Server
使用一个单独的服务器存储 Session 数据可以使用传统的 MySQL也使用 Redis 或者 Memcached 这种内存型数据库
优点
- 为了使得大型网站具有伸缩性集群中的应用服务器通常需要保持无状态那么应用服务器不能存储用户的会话信息Session Server 将用户的会话信息单独进行存储从而保证了应用服务器的无状态
缺点
- 需要去实现存取 Session 的代码
<div align="center"> <img src="pics/fdc45a09-f838-4348-8959-d2c793727788.png" width="600px"/> </div><br>
参考
- [Session Management using Spring Session with JDBC DataStore](https://sivalabs.in/2018/02/session-management-using-spring-session-jdbc-datastore/)
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-2.png"></img></div>