课程简介:端节点算法学.doc

上传人:创****公 文档编号:1179332 上传时间:2018-12-17 格式:DOC 页数:15 大小:155KB
下载 相关 举报
课程简介:端节点算法学.doc_第1页
第1页 / 共15页
课程简介:端节点算法学.doc_第2页
第2页 / 共15页
课程简介:端节点算法学.doc_第3页
第3页 / 共15页
课程简介:端节点算法学.doc_第4页
第4页 / 共15页
课程简介:端节点算法学.doc_第5页
第5页 / 共15页
点击查看更多>>
资源描述

1、端节点算法学端节点算法学是网络算法学在端节点尤其是服务器上的运用。我们可以认为它是建立高速服务器的一组系统性技术。随着网络功能虚拟化的提出,将来数据中心绝大部分的网络设备都会在通用服务器上实现,因此端节点算法学的重要性就更突出了。消除不必要的拷贝如果我们跟踪一个网络包从进入网卡到完成处理的整个过程,会发现网络包在终端中被拷贝了多次,具体场景稍后会看到。为什么我们要把数据拷贝这个问题单独提出来讨论,是因为在计算机中进行拷贝会消耗两个非常宝贵的资源:内存带宽和内存本身。内存带宽反映了系统读写数据的能力。由于现代计算机中访存是最大的瓶颈,如果 web 服务器处理一个报文涉及到 k 次拷贝,那么这个

2、web 服务器的吞吐量就可能降至 1/k。计算机中内存的容量是确定的,如果一个报文在内存中存 k 份,则会降低内存的有效容量。能够进入内存或 cache 的数据量少了,访问数据的延迟就增大了。所以说数据拷贝是影响计算机系统性能的重要因素。本章关注如何消除不必要的拷贝(P1 ) 。一个拷贝如果不是由硬件要求的,该拷贝是不必要的。比如,网络适配器将收到的数据拷贝到计算机内存,这是硬件要求的;然而,应用程序和操作系统之间的拷贝,主要是由操作系统的结构化产生的要求,除此之外没有什么特别的理由,这个拷贝是可以考虑消除的。除了拷贝之外,这一章还将讨论其它需要对数据包载荷进行的操作(如计算检查和) 。5.1

3、 为什么要拷贝数据我们首先看看在终端中数据的多次拷贝是怎么发生的。考虑用户向 web 服务器请求一个静态文件,该文件在磁盘上;web 服务器从磁盘中读出文件,发送到网络上。我们关注在此过程中,数据在 web 服务器中的转移过程。图 5.2 给出了涉及到的计算机系统的主要部件和拷贝过程。涉及到的主要硬件为 CPU、存储器、内存总线、I/O 总线、硬盘和网卡,主要软件为 web 应用程序和内核程序。这里涉及到两个主要的内核子系统,文件子系统和网络子系统。文件子系统负责文件管理,网络子系统负责报文收发和协议处理。为简单起见,图中只画出了一个 CPU(许多服务器有多个处理器) ,并且只关注对静态内容的

4、请求,即文件直接从磁盘中读出。如果请求的是动态内容,web 服务器后面还需要一个数据库,由服务器侧的一个 CGI 程序处理请求,从数据库中读数据,构造网页,再传给 web 服务器。注意,图中将文件子系统和网络子系统的代码画在处理器中。实际上,这些代码也存放在主存中,由处理器从主存中获取。然而,位于处理器指令 cache中的代码可以看成是在处理器中的。一个简单的故事直观上,这个故事是很简单的。首先 web 应用程序通过一个系统调用(如read())将文件从磁盘读入到它的缓冲区(应用缓冲区) ;然后构造一个 HTTP响应头,通过一个系统调用(如 write())将响应头和缓冲区内容交给网络子系统(

5、TCP/IP 程序) ;网络子系统将数据划分成适当大小的块,加上各层协议头后交给网络适配器发送。如果讲原理,一般就讲到这个程度。一个真实的故事实际上,这个故事的细节要复杂得多。首先,文件一般先从硬盘读入到一个称为文件缓冲区的内核空间,我们称 copy 1。这个做法是值得提倡的,这样随后对该文件的请求就可以直接从内存得到,而不需要每次都去读硬盘。所有的 web 服务器都是这么做的,这样可以极大地减小响应时间。其次,文件数据从文件缓冲区拷贝到 web 程序的应用缓冲区,我们称 copy 2。接着,web 程序对一个 TCP 套接字执行一个 write()系统调用。在 write()调用中描述的应用

6、缓冲区被拷贝到一个套接字缓冲区,这是内核中不同于文件缓冲区和应用缓冲区的另一个缓冲区,这称为 copy 3。最后,每个数据块在加上了各层协议头之后,由驱动程序将数据包拷贝到位于网卡的缓冲区中,发送出去。这称为 copy 4。在传输到网络之前,TCP 程序还要扫描一遍数据,计算 TCP 检查和。以上过程涉及到 4 次拷贝和 1 次涉及全部包数据的检查和计算。资源消耗情况我们看一下资源消耗情况。不同内存区域之间的拷贝(copy 2 和 copy 3)需要 CPU 的参与,每个字都要通过内存总线读一次和写一次,是消耗资源最多的。计算 TCP 检查和需对每个字读一次,最后写一个简单结果,因此使用内存总

7、线一次。涉及外设的拷贝(copy 1 和 copy 4) ,如果由 CPU 来做拷贝(称程序输入输出) ,其代价与内存区域之间的拷贝一样,每个字都要通过内存总线读、写各一次。如果由设备来做拷贝(DMA) ,则每个字只需通过内存总线读一次或写一次。涉及外设的拷贝还会消耗 I/O 总线带宽(copy 1 和 copy 4) 。对服务器吞吐量的影响在 web 服务器的例子中,即使使用了 DMA,每一个字也要使用内存总线 7次。因此,web 服务器的吞吐量不会超过 T/7,其中 T 为内存速度和内存总线速度中的较小值。其次,额外的拷贝消耗了内存。在图中,一个文件被存储在文件缓冲区、应用缓冲区和套接字缓

8、冲区。通常 web 服务器希望使用尽可能多的文件缓冲区来避免频繁地访问硬盘。一个文件存在 3 处,将减少文件缓冲区可用的容量,降低缓存命中率,从而极大地降低整个服务器的性能。总而言之,多余的拷贝在两个重要的方面损害了服务器的性能:1)由于使用了过多的总线和内存带宽,使得服务器的运行速度低于总线速度;2)由于使用了过多的内存,使得服务器不得不大量地去从磁盘读文件,而不是从主存中读文件。需要注意的是,我们只描述了获取静态内容的情形,实际上相当一部分请求是关于动态内容的。动态内容通常由一个专门的 CGI 程序生成,然后通过某种进程间通信机制交给 web 服务程序去发送,这里又会涉及到一次拷贝。下面我

9、们将讨论这些拷贝,哪些是可以避免的,怎么避免。5.2 利用适配器内存消除 copy 4我们首先关注与网络相关的拷贝,即 copy 4。为什么需要 copy 4?一个简单的解释是,因为适配器内存位于适配器上,而内核存储空间位于存储子系统,不在同一个硬件上。但是这个理由并不充分。我们知道在一个内存映射的体系结构中,设备的寄存器被映射到一块内存区域,CPU 通过读写这块内存区域与设备通信。因此从理论上说,在一个内存映射的体系结构中,内存可以位于总线上的任何地方。所以,尽管内核存储空间通常是位于存储子系统的,但没有理由认为部分内核空间就不能位于网络适配器中(网络适配器通常包含一定容量的存储器) 。利用

10、网络适配器中已有的存储空间(P4)和内核存储空间放置的自由度(P13) ,我们可以将套接字缓冲区放在网络适配器中。这样应用缓冲区的内容直接拷贝到网络适配器的内存中。如何计算检查和?但是这里有一个问题,网络子系统在收发 TCP 包时需要计算 TCP 检查和,如果数据在应用缓冲区和适配器之间直接传递,那么 TCP 检查和怎么计算呢?这里的一个想法是运用 P2c(共享开销) 。数据从应用缓冲区拷贝到适配器上的缓冲区,假如这个拷贝由 CPU 完成,那么可以让 CPU 捎带着同时计算检查和。比如,使用一个寄存器,对已经传输的数据进行累加。但是这个方法有个致命的问题,就是在接收数据包的时候,CPU 边拷贝

11、数据边计算检查和,当发现数据接收错误时,数据已经进入到应用缓冲区中,这是违背 TCP 语义的。所以这个方法从未被实施。后来这个方法被 HP 实验室的研究人员采纳,应用到他们的网络适配器(称为 Afterburner)中。数据传输不是由 CPU 完成,而是由网卡通过 DMA 完成。由于 CPU 不参与 DMA 过程,因此检查和计算是由网卡完成的。这种网卡称为 TCP 卸载引擎,它将 TCP 的数据传输下放到网卡上完成,以减轻 CPU 的负担。需要注意的是,考虑到 TCP 连接管理的复杂性,TCP 连接的管理(建立、关闭等)仍由主 CPU 完成,只是将建立好的 TCP 连接移交给网络适配器。这种方

12、法的问题是,网络适配器需要很大的内存空间和较强的处理器来支持大量的 TCP 连接,网卡成本很高。5.3 消除 copy 3下面考虑消除 copy 3。注意,我们现在是独立地考虑每一种数据拷贝的消除方法,这些措施能否组合使用需要仔细考虑。应用和内核之间需要一次拷贝有两个原因。 (1)应用和内核使用不同的虚拟地址空间,需要通过拷贝传递数据。但是这个理由不是充分的,因为完全可以通过内存映射,将套接字缓冲区映射给应用程序使用。 (2)socket API 使用拷贝语义,应用程序在将缓冲区的内容写入套接字(交给网络子系统)后,它可以往缓冲区中写入新的数据。但是 TCP 通常需要缓存数据以备重发,因此TC

13、P 不能与应用共用一块缓冲区,需要通过数据拷贝来解除应用和内核之间的耦合。第 2 个理由使得拷贝看起来是必要的。如果不能避免拷贝,那我们能够减小拷贝的开销吗?特别是,如果应用并不需要立即写缓冲区,那么每次都执行拷贝是否必要?写时拷贝有些操作系统(如 Mac)提供写时拷贝(copy-on-write)功能,在很多情况下可以避免实际的拷贝。写时拷贝的实现写时拷贝的基础是虚拟内存。程序使用虚拟地址,虚拟地址通过一个页表映射到物理地址,页表用虚拟页号(虚拟地址的高 20 位)进行索引。如果需要的页不在内存中,硬件产生一个缺页中断,操作系统将相应的页读入内存。查找页表的开销可以通过使用 TLB 来消除。

14、我们用一个例子说明写时拷贝的实现。假定进程 P1 的虚拟页 X 映射到物理页 L,需要复制 X 的内容到进程 P2 的虚拟页 Y。写时拷贝(续):不幸的是,许多操作系统(如 UNIX 和 Windows)不提供写时拷贝。但是理解了写时拷贝的原理之后,类似的效果是可以实现的。因为现代计算机都使用虚拟内存,通过修改页表来避免物理拷贝是能够做到的,只是需要找到一种替代 COW 位的保护机制。 (COW 保护机制采用硬件检测、触发操作系统异常来解决)5.4 优化页面重映射写时拷贝的例子忽略了很多细节,以致于让人觉得页面重映射是很简单的一个操作,一个大的缓冲区通过一个写页表操作就可以从应用程序传递到内核

15、(或反过来) 。比如在图 5.5 中,假定操作系统希望将进程 P1 的虚拟页 10(VT 10)拷贝到进程 P2(如内核)的虚拟页 8(VT 8) ,其中 VT 10 指出一个存放包数据的物理页。过于简单的想法是只需要修改 VT 8 的页表表项,使其指向存放包数据的物理页就可以了。这种过于简单的看法是很误导人的。页面重映射的开销有好几个额外的开销被这种简单的描述给掩盖了。(1)多级页表大多数现代的计算机系统使用多级页表映射(至少有两级) ,实际映射时可能要求修改多级页表,由此可能涉及多次写。为了实现跨平台运行,有些操作系统同时维护了机器无关页表和机器相关页表,则涉及的写操作更多。当页表不在内存

16、中时,还需要在内存中为页表分配一个物理页帧,将页表调入物理页帧中,为此还需要修改目录页。(若使用 32 位的虚拟地址和 4KB 的页,一个进程可以有约一百万个页,所以页表也要分页。32 位机器一般使用两级页表:每 1024 个页表项组成一个页表,这些页表的起始地址(即页表所在的物理页帧号)保存在一个目录页中;目录页有 1024 个表项,目录页的起始地址保存在一个全局寄存器中。虚拟地址的前10 位用于查找目录页,得到页表的地址;虚拟地址的中间 10 位用于查找页表,得到虚拟页的物理页帧号。当包含虚拟页页号的页表已经在内存中时,页面映射只需修改对应的页表项;当页表不在内存中时,还需要在内存中为页表

17、分配一个物理页帧,将页表调入物理页帧中,为此还需要修改目录页。 )(2)要求锁页表是共享资源,修改页表必须用锁保护,因此修改页表前后要有请求锁和释放锁的开销。(3)刷新 TLB为节省地址转换时间,常用的页表映射缓存在 TLB 中。当一个新的虚拟页的地址映射写入页表时,相关的 TLB 表项要清除或修正。 (TLB 只包括最近用到的虚拟页号,指令和数据页分开记录。TLB 分别保存 64 个最常用的指令和数据的虚拟页号,每个 TLB 项包括一个虚拟页号和相应的物理页帧号。 )(4)在目标域中分配虚拟内存需要为目标进程分配一个新的虚拟页(malloc ) 。新的虚拟页需要向系统去申请,为此,系统需要做

18、一些计算在目标进程中找到一个空闲的页表表项。(5)锁住相应的页物理页可能会被换出到磁盘上。为防止页被换出,页必须被锁住,这也需要开销。所有这些开销在多处理器系统中会被放大(以上不少操作都需要加锁,如malloc) 。其结果是,尽管页表映射看起来非常好,即无论包大小如何,页面重映射只需常数时间,但这个常数因子实际上是一个很大的开销(Q4 ) ,有研究人员在 90 年代早期的实验中证实了这一点。也就是说,如果只是简单地使用页表重映射来避免拷贝,结果可能不像预期的那么好。那么怎么办?数据拷贝开销很大,但页面重映射看起来开销也不小,搞不好比拷贝一个数据包的开销还要大。那是不是说页面重映射就不能用了呢?

19、好在研究人员并没有放弃这个想法,他们发明了一个称为 fbufs(fast buffers的简称)的操作系统设施,可以消除前 4 种页面映射开销的全部或大部分。Fbufs(fast buffers)Fbufs 基于这样的观察:如果一个应用正在通过内核向网络发送大量的数据包,那么一个缓冲区可能会被重用多次。方法一:提前分配好需要的包缓冲区,并计算好所有的页面映射信息(P2a) ,发送时重复使用这些包缓冲区。问题是不好预先估计所要的缓冲区数量。方法二:当数据传输开始时才按需分配包缓冲区并计算页面映射(P2b) ,然后将其缓存起来(P11a)供后续数据包使用。尽管前几个包的延迟较大,但后续的包就免除了

20、页面映射的开销。不管哪一种方法,都可以做到“映射一次,重复使用” 。当需要传输的数据量很大时,页面映射的开销被平摊,可以认为开销为零。为应用分配一组固定的物理页为避免用户空间和内核空间之间的拷贝,将一组物理页 P1、P2 、同时映射到内核和应用的页表中,供它们使用。考虑到端系统上可能同时运行多个应用。为进行安全隔离,设计者将一个有序的安全域序列(数据包经过的一系列处理程序)定义为一条路径,并为每一条路径预留不同的一组物理页。图 5.6 是一个路径的例子,以太网软件实现为一个内核级的驱动,TCP/IP栈实现为一个内核级的安全域,Web 应用实现在应用层。图中存在两条接收路径:(以太网,TCP/I

21、P, web) , (以太网,OSI,FTP ) 。将一定数量的物理页映射给接收路径(以太网、Tcp/IP 和 web 应用) ,再将另一组物理页映射给另一条接收路径。这样,每一个应用使用一组固定的物理页。为使该设计发挥作用,当一个数据包到达时,最底层的驱动(甚至是网络适配器)必须立即判断该数据包要被映射到哪条路径,从而将数据包拷贝到分配给这条路径的物理页中,这个功能称为提前解复用(early demultiplexing) 。在图 5.6 中,这是通过检查数据包的所有头部来确定的,比如,具有以太帧头、IP 头、 TCP 头和端口 80 的包属于路径 1。映射到同一个物理页的虚拟页号相同想一想

22、,在进程间传递缓冲区描述符会有什么问题?理论上,各个进程映射到同一个物理页上的虚拟页号可能不同。比如,第一个进程的虚拟页 10 可能和第二个进程的虚拟页 8 映射到同一个物理页上。这是很麻烦的,因为第二个进程读入 VT 10 的描述符后,它必须要知道它对应了自己的虚拟页 8。为避免这种情况,设计者规定映射到同一个物理页的虚拟页号必须相同。为此,系统将将所有进程的虚拟内存中一定数量的起始页预留为 fbuf 页。收包处理过程图中是只有两个安全域的一条路径。进程 1(writer)收到数据包后,从free fbufs 队列取一个空闲缓冲区的描述符,将数据包写入该空闲缓冲区,然后将该缓冲区的描述符写入

23、 written fbufs 队列;进程 2 从 written fbufs 队列中取包缓冲区描述符,从相应的包缓冲区中读数据处理,将释放的包缓冲区描述符写回到 free fbufs 队列。到目前为止,接收路径的问题解决了。网卡驱动将数据包装入一个空闲的包缓冲区,包缓冲区的描述符沿着接收路径传递,每个进程访问同一个物理内存页进行数据包处理,数据包处理完后,包描述符归还给驱动程序进行重用,在此过程中没有发生物理拷贝。那么发送路径呢?如何添加包头?在发送路径上,每一个安全域都要给数据包加上一个包头。然而为了实现安全保护,我们对于每条路径只允许一个写者,其余为读者,这意味着页只能由写者来修改。那么,

24、怎么允许其它进程添加包头呢?应用如何使用 fbufs?现在还剩下一个重要的问题。大量已有的应用软件是使用标准拷贝语义的socket API 书写的,即应用执行了 write()系统调用后,就可以重用包缓冲区甚至释放了。然而使用了 fbufs 之后,在包缓冲区被其它进程使用完之前,应用是不允许写或释放包缓冲区的。这个问题怎么解决呢?修改应用 API该问题最终的解决方案是:API 不再保持拷贝语义,应用必须判断能不能写 fbufs。当一个 fbuf 被交给内核后,应用不能写这个 fbuf,直至其被归还到空闲链表中。为防止出错或恶意的代码,当一个 fbuf 从应用转递到内核后,内核翻转一个写允许比特

25、,归还 fbuf 时再重新设置该位。如果应用在不允许写的情况下做了一次写操作,则会产生一个异常,应用崩溃,但不会影响其它的进程。已有的网络应用软件必须重写吗?改变 API 听起来是一个很大的改动,这是否意味着大量已有的网络应用软件必须重写呢?这显然是不可能的,这里有几种解决方案。方法一:已有的 API 增加新的系统调用。比如,增广了 fbufs 的 Solaris 除了标准的 write()外,还增加了一个 uf_writer()调用。要求高性能的应用可以用新的调用进行重写。方法二:用新的扩展实现一个公共的 I/O 库。其实,这个问题最终的考虑不是 API 是否要变,而是修改应用程序来使用该

26、API 有多难。实践表明,将应用移植到类 fbuf 的 API,对应用所做的修改不大,且是局部的。也就是说,Fbufs 方案是可行的。 (可行性很重要,一个再好的方案如果推广起来难度大,也没有人使用)5.5 使用 RDMA 避免拷贝在前面考虑的 web 服务器场景中,web 服务器接收请求,然后将文件传输到网络上,Web 服务器作为接收端并不需要保存请求消息。下面考虑在两个终端之间传输一个大文件,接收端需要保存收到的包。采用 fbufs 收包假如采用 fbufs,包到达网卡后被拷贝到一个包缓冲区,包缓冲区描述符在路径上传递,被各个安全域处理,在此过程中无数据拷贝。最后应用进程将数据拷贝到其应用

27、缓冲区中,释放包缓冲区。为什么要拷贝?因为文件内容需要保存或被应用处理,而包缓冲区要被重用。 (http 请求消息不需要保存,但是文件内容是需要保存的)采用 TOE 网卡收包假设采用 TOE 网卡。包到达网卡后,被放入相应的套接字缓冲区进行协议处理和重组。DMA 引擎将数据送入应用缓冲区,向 CPU 发出中断。网卡驱动程序通知内核模块接收数据,交给应用程序(包缓冲区描述符) 。应用程序将数据拷贝到文件缓冲区,应用缓冲区重新交给网卡使用。这里进行拷贝是为了归还应用缓冲区,为什么要重用应用缓冲区而不是重新分配一个呢?因为准备 DMA 缓冲区是一种耗时的操作,内核需要将应用缓冲区映射到连续的物理页上

28、,将缓冲区的虚拟地址翻译成能够被 DMA 使用的总线地址,然后将地址传给网卡。将一大块应用缓冲区映射到连续的物理页上,并不总是可以做到的,所以 DMA 缓冲区在初始化时准备好,然后重复使用。由于给每个套接字分配的缓冲区是有限的,在传输一个大文件的过程中,需要多次中断 CPU 来接收数据和拷贝数据。(驱动程序用来管理设备资源,提供设备操作接口、收发数据接口、进行中断处理等。应用程序通过系统调用来使用设备。内核模块是连接应用层和协议处理引擎的钩子模块。 )远程直接内存访问 RDMA通过网络进行 DMA 的愿景称 RDMA。其意图是也就是说,数据一次传输到位,不需要 CPU 再去移动数据。RDMA

29、要解决的问题毫无疑问,网络适配器应卸载全部的 TCP/IP 处理,TOE 网卡已经可以做到这一点。除此之外,还有两个问题需要解决:(1)接收端适配器如何知道应将数据放在哪儿?它不能向主机求助,否则就违背了这个意图。 (2)如何保证安全,因为恶意的数据包可能会覆盖关键的内存区域。5.5.1 VAX 的 RDMARDMA 在 VAX 集群中就已经被使用。计算机集群就是用一批廉价的计算机来代替昂贵的大型机,许多 web 服务器实际上就是服务器集群。DEC 引进的 VAX 集群是一个成功的商用产品,为可伸缩应用(如数据库应用)提供计算平台。该系统的核心是一个 140Mb/s 的网络,称为计算机互联(C

30、omputer Interconnect, CL) ,使用一个以太网风格的协议。用户可以将许多 VAX 计算机和网络硬盘连接到 CL 上。VAX 的 RDMA 解决方案接收方应用进程锁住一些物理页,用作文件传输的目标存储区域,但呈现出来的逻辑视图是由一些地址连续的虚拟页组成的一个缓冲区。然后,缓冲区ID 被传送到发送端应用。发送端应用将缓冲区 ID 及包存放的偏移量随同数据包一起发送。数据包到达后,接收端适配器根据缓冲区 ID 和偏移量,将数据包内容拷贝到正确的位置。包全部到达后,接收端不需要进行任何的页面重映射。5.5.2 RDMA 在 SAN 中的应用VAX 集群引入了一个非常早期的存储区

31、域网络。存储区域网络是一个后端网络,它将大量计算机和网络硬盘连接在一起。现在 Infiniband 在数据中心非常火,因为数据中心的节点之间需要传输大量数据。尤其是现在数据中心部署了很多的分布式机器学习应用,如进行深度神经网络的训练,需要高吞吐低延迟的通信支持。总之,如果在两台计算机之间需要传输大量的数据,采用 RDMA 是非常高效的方法,它可以节省两侧 CPU 的时间,并且数据存放一次到位,没有多余的拷贝。5.6 把避免拷贝技术扩展到文件系统前面我们讨论了如何消除与网络通信有关的拷贝,现在我们重新回到 web服务器应用场景,考虑文件系统中的拷贝。为了提高响应速度,服务器通常将请求的文件先读入

32、一个文件缓冲区(copy 1) ,然后从文件缓冲区拷贝到应用缓冲区(copy 2) ,这是必要的,因此copy 1 不在我们的考虑范围内。本节的主要目的是消除 copy 2。我们把之前讨论的避免拷贝技术扩展到文件系统,介绍三种消除文件系统冗余拷贝的技术。5.6.1 共享内存方法有了前面通过页面重映射消除拷贝的经验(fbufs) ,我们自然想到是不是也能用内存映射的方法消除 copy 2 呢?类 UNIX 操作系统提供一个方便的系统调用,称为 mmap(),它允许应用(如 web 服务器)将一个文件映射到它的虚拟内存地址空间。其它操作系统也提供类似的功能。概念上,当一个文件被映射到一个应用的地址

33、空间,这个应用就好像在它的内存中缓存了这份文件。实际上,这个缓存的文件只是一组映射。也就是说,如果 web 程序将文件映射到了自己的地址空间,则它和文件 cache 访问的是同一组物理页,从而免除了拷贝的需要。Flash Web 服务器我们看一下 Flash Web 服务器的做法。为加快响应速度, web 服务器将经常用到的文映射到自己的内存空间。注意,受到可分配给文件页的物理页数量及页表映射的限制,Flash Web 服务器只能缓存和映射最近常用的文件,不能用来长期存放大量的文件。事实上,Flash Web 服务器并没有缓存整个文件,只是缓存了一些文件分片,并使用 LRU(Least Rec

34、ently Used)策略将最近一段时间未用的文件取消映射。只缓存一些文件分片有什么意义呢?可以提高响应速度。如果要访问的文件有一些分片在缓存中(通常是头几个分片) ,那么这些分片就立即可以发出去,然后再将其余的分片映射进来。尚未解决的问题Flash Web 没有消除 CGI 程序和 web 服务器之间的拷贝。文件缓存只能缓存静态内容,动态网页要由 CGI 程序生成。CGI 程序生成的动态内容通过UNIX 管道传给 web 服务器;典型地,管道要在两个地址空间之间拷贝内容。其次,到目前为止我们的方案都没有涉及 TCP 检查和。假如同一个文件不断地被 cache 命中,那么返回的文件分片对所有请

35、求都是一样的,为什么 TCP检查和不能缓存呢?当然,这里的检查和是指数据部分的检查和,TCP 头是不同的,但是检查和可以增量计算。然而,这需要一个能够从数据包内容映射到检查和的高速缓存,这在传统缓存方案中是很低效的。高速缓存实际上是一个 数组,这里 a 为数据包内容,f(a) 为检查和。可以结合 fbufs 和 mmap 吗?我们介绍了 fbufs,可以消除应用-网络之间的多余拷贝;我们介绍了mmap,可以消除文件系统的冗余拷贝。那么把 fbufs 和 mmap 结合起来,是不是就能消除 copy2 和 copy3 了呢? 如果采用 fbufs,所有进程的虚拟内存中一定数量的起始页预留为 fb

36、uf 页,应用进程的应用缓冲区不能被映射到这些物理页上。因此,如果应用将文件映射到其虚拟地址空间的一个缓冲区,那么这个缓冲区不能用 fbuf 发送,必须要有一次物理拷贝! 5.6.2 IO-Lite那么我们能够同时消除 copy2 和 copy3 吗?这里我们介绍一个称为 IO-Lite的方案,它可以一揽子解决前面所有的问题,它可以消除 copy2 和 copy3,可以消除 CGI 程序和 web 服务器之间的拷贝,还可以缓存之前传送过的数据包的检查和。由于 fbufs 和 mmap 不能同时使用,所以 IO-Lite 扩展 fbufs 到文件系统,使得可以不必使用 mmap。IO-lite

37、响应 get 请求的步骤图 5.10 给出了响应 GET 请求的步骤。当文件第一次从磁盘读入文件系统的高速缓存时,文件页被保存为 IO-Lite buffer。当应用通过一个调用来读文件时,没有进行物理拷贝,而是创建了一个缓冲区聚合体(以方便添加包头) ,指针指向 IO-Lite buffer。当应用发送文件给 TCP 进行传输时,网络系统得到一个指向相同 IO-Lite 页的指针。为防止出错,IO_Lite 系统为每个缓冲区维护一个引用计数器,仅当所有用户都使用完后才重新分配缓冲区。图 5.10 还给出了另外两个优化。应用将常用文件的 HTTP 响应维护在一个高速缓存中,通常只需简单地加上做

38、了最小修改的标准响应。其次,IO-Lite 给每个缓冲区分配一个唯一的编号(P12,增加冗余状态) ,TCP 模块维护一个以缓冲区编号为索引的检查和高速缓冲。当一个文件被传输多次时,TCP 模块在第一次计算了检查和之后,就可以避免再计算检查和。注意到这些改变消除了图 5.2 中的 copy2 和 copy3,加快了响应的处理。实现 IO-Lite尽管 IO-Lite 的核心思想很简单,但要与文件系统集成需要解决一些困难的问题。首先,IO-Lite 必须处理复杂的共享模式,。其次,IO-Lite 页既可能是虚拟内存页又可能是文件页,.第三,需要找到一种干净的方法将 IO-Lite 集成到操作系统中,避免对 OS进行外科手术式的大改动。IO-Lite 已经在 UNIX 中实现了。5.6.3 使用 I/O 拼接避免文件系统拷贝对商用 web 服务器的商业测试表明,基于 IO-Lite 思想的 web 服务器技术领先,但是其它一些 web 服务器也有优秀的性能。

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 实用文档资料库 > 公文范文

Copyright © 2018-2021 Wenke99.com All rights reserved

工信部备案号浙ICP备20026746号-2  

公安局备案号:浙公网安备33038302330469号

本站为C2C交文档易平台,即用户上传的文档直接卖给下载用户,本站只是网络服务中间平台,所有原创文档下载所得归上传人所有,若您发现上传作品侵犯了您的权利,请立刻联系网站客服并提供证据,平台将在3个工作日内予以改正。