1、什么是负载?
负载就是服务器端的“资源”:主要就是CPU和IO。
前者适宜于计算密集型的任务,后者则对应数据密集型的任务。
2、负载均衡的前提
就是负载(或者说CPU/IO资源)可以切分,划分到不同的计算机(或者CPU核)上去。
要做到这一点,首先底层的运算应该是可以中断并调度的,IO是可以多路扩散的。否则一个简单的CPU死循环指令this: jmp this(跳回自己)就会让计算机什么也干不了,而IO嘛,IO要是不停地中断阻塞了总线,计算机也会一样啥也干不了(不过正常情况下IO总线没CPU内部总线快)
3、负载均衡的本质
负载既然可以切分到不同的计算机上去(分布式系统,这些计算机之间的一致性怎么维护、事务ACID性质怎么保持、怎么提高可用性、CAP/BASE是另外的话题),那么剩下来的关键是对外部的大规模并发请求做路由了。
首先假设每个请求对应服务器端的一台计算机处理,如果能够将外部请求对应的负载比较均匀地分布到各个计算机节点上去,则负载均衡无疑会做得比较成功。
不考虑分布式数据库的后端技术,则负载均衡的核心就在于路由。这个路由,其实就是一个Hash函数。
函数的输入是什么呢?所有可供区分的外部用户请求参数,比如:用户ID、会话ID、请求参数、网络层地址,等等。
输出是什么呢?假设最终处理请求的计算机编号为1到N,则路由Hash函数的输出就是[1..N]之间的一个整数。
很显然,如果输入均匀(随机),Hash函数可以采取线性Hash运算,就可以确保负载均衡地落在这N个处理节点上。无疑是,输入有时候可能并不均匀,往往落在某个局部区间的请求过多,这往往会导致热点/瓶颈,假如这部分不均匀输入样本的总数相比总的输入空间来说不是很大的话,理论上,还是可以找到一个能够用的非线性Hash算法(比如说SHA1/256之类),使得输入仍然能够均匀地落在区间[1..N]上。
4、多层次路由
实际应用中,前述路由Hash运算不是只在一个点上执行,而是可能在多个层次上做,比如说:网络层LB技术LVS(Linux Virtual Server)、前端代理(带Round Robin轮询的HTTP反向代理、数据库连接驱动代理)、DNS分派
这很容易让人联想到神经网络里的多层前向/反馈网络(那个深度学习不就是增加中间节点的层次深度吗),不管怎么说,多层次的路由其实就是数学上的非线性Hash映射。
负载均衡的本质差不多就是这样。对于实际应用来说,关键就在于设计一个Hash函数,使得对于此应用特定的数据而且,能够做到均匀地分发到后端处理节点上。