文章目录
- 引言
- LVS为什么属于四层负载均衡
- 为什么说Lvs调度开销小
- 内核态为什么开销小
- 为什么lvs可以工作在内核态
引言
对于负载均衡器而言,可以按照网络层次划分来分类,如下图:
位于第二层的交换机和第三层的路由器也可以作为负载均衡,但是我们接下去提到的都是指应用侧的负载均衡,而不是路由侧的负载均衡。
网络层和数据链路层负责数据转发,只不过真正传输中是以数据链路层为实际传输层,网络层起到引导的作用。这是因为网络中负责传输的硬件网卡,网卡的mac地址是网络种真正的物理地址,而IP地址只是逻辑上的地址,理解这一点很重要,后文会再次提到。
基于分工协作的考虑,应用侧的负载均衡当然是由传输层或者应用层去实现比较好,而二、三层专注于路由转发即可。
LVS为什么属于四层负载均衡
有人说lvs
应该属于三层的负载均衡,有的说属于四层的负载均衡,较真起来意义不大,但是可以从如下的思路来理解。
lvs 属于应用侧的负载均衡,要转发的必定是第四层传输层的信息。如果转发的是网络层的信息,那么TCP连接三次握手请求,网络层无法判断这些请求是否属于握手的,所以只能按照设定好的均衡规则去转发三个握手数据包。
从这一点来看,Lvs工作在四层。
但是,以后我们接触到 lvs 转发实现原理时,会发现它工作在 网络层,都是对IP报文的修改。
为什么说Lvs调度开销小
(负责转发的)因为所有的操作都是在Linux操作系统核心空间中将完成的,它的调度开销很小,所以它具有很高的吞吐率。
这里有两个关键问题需要回答,即:
- 内核态为什么开销小
- 为什么lvs所有转发操作可以工作在内核态而不经过用户态
内核态为什么开销小
该部分涉及到进程、系统内核、虚拟内存等相关概念,难以一篇文章说清楚,此处仅简要描述。
这里说的内核指的是 操作系统的内核
。
操作系统和CPU共同制定了一套机制,该机制有几个重要的点:
- CPU制定了一个指令权限等级RingX,不同等级对应不同的指令范围,依靠一个寄存器来表示当前等级。系统内核为Ring0,而用户进程一般为Ring3等级。
- CPU和操作系统共同制定了
虚拟内存
这种机制,使得每一个进程有如下感觉:
- 系统中只运行着自己
- 一切资源自己独享
基于这种机制,进程看到的内存中也就包括了操作系统内核占用的内存块。
- 内核占用的内存块,不能被用户进程直接访问,相当于这块空间CPU对其设置了等级保护。
- 其次,cpu 提供一个
syscall
的指令,表示这是系统调用指令。系统调用,就是系统内核对外暴露的API接口,应用进程通过 syscall 指令控制CPU去执行相关API的指令,此时,就进入了内核态的环境,CPU运行在Ring0级别,去执行内核已经制定好的指令。 - 这一过程,相当于应用进程间接的通过系统调用接口访问到了 内存块中属于 内核的部分。
那么,从用户态转到内核态多了哪些开销呢?
- 状态的切换效果等价于,当前执行的是应用进程,但是切换后就开始执行内核进程。所以,相关的堆栈信息需要保存,要做一些切换设置
- 数据的拷贝。I/O类请求都是将数据先保存在内核缓冲区,然后再拷贝到用户缓冲区
虽然差别不大,但是扛不住量大,随着频繁的切换状态,调度开销自然会变高。
由于网络请求都属于I/O请求,应用程序都要经过系统调用才可以进行正常的交互,那么就不可避免地多了许多状态切换地调度开销。
为什么lvs可以工作在内核态
因为 lvs 由两段代码组成:ipvsadm 和 ipvs,其中
- ipvs 工作在内核空间,是真正实现调度地代码
- ipvsadm工作在用户空间,负责规则制定等。
linux2.4内核以后地版本中,已经包括了ipvs了。所以,该真正实现调度地模块就运行在内核态,而避免了和用户态之间的频繁切换。收到网络I/O中断后,直接在内核空间完成即可。
经包括了ipvs了。所以,该真正实现调度地模块就运行在内核态,而避免了和用户态之间的频繁切换。收到网络I/O中断后,直接在内核空间完成即可。
下篇文章,我们对lvs的工作机制进行学习。