技术开发 频道

高并发高流量网站架构

    4.4 内存级缓存

    内存级别的缓存是指将需要动态生成的内容暂时缓存在内存里,在一个可接受的延迟时间范围内,同样的请求不再动态生成,而是直接从内存中读取。Linux环境下内存级缓存Memcached[31]是一个不错的选择。
   
    Memcached是danga.com(运营Live Journal[32]的技术团队)开发的一套非常优秀的分布式内存对象缓存系统,用于在动态系统中减少数据库负载,提升性能。和 Squid 的前端缓存加速不同,它是通过基于内存的对象缓存来减少数据库查询的方式改善网站的性能,而其中最吸引人的一个特性就是支持分布式部署;也就是说可以在一群机器上建立一堆 Memcached 服务,每个服务可以根据具体服务器的硬件配置使用不同大小的内存块,这样,理论上可以建立一个无限大的基于内存的缓存系统。

    Memcached 是以守护程序方式运行于一个或多个服务器中,随时接受客户端的连接操作,客户端可以由各种语言编写,目前已知的客户端 API 包括 Perl/PHP/Python/Ruby/Java/C#/C 等等[附录1]。客户端首先与 Memcached 服务建立连接,然后存取对象。每个被存取的对象都有一个唯一的标识符 key,存取操作均通过这个 key 进行,保存的时候还可以设置有效期。保存在 Memcached 中的对象实际上是放置在内存中的,而不是在硬盘上。Memcached 进程运行之后,会预申请一块较大的内存空间,自己进行管理,用完之后再申请一块,而不是每次需要的时候去向操作系统申请。Memcached将对象保存在一个巨大的Hash表中,它还使用NewHash算法来管理Hash表,从而获得进一步的性能提升。所以当分配给Memcached的内存足够大的时候,Memcached的时间消耗基本上只是网络Socket连接了[33]。

    Memcached也有它的不足。首先它的数据是保存在内存当中的,一旦服务进程重启(进程意外被关掉,机器重启等),数据会全部丢失。其次Memcached以root权限运行,而且Memcached本身没有任何权限管理和认证功能,安全性不足。第一条是Memcached作为内存缓存服务使用无法避免的,当然,如果内存中的数据需要保存,可以采取更改Memcached的源代码,增加定期写入硬盘的功能。对于第二条,我们可以将Memcached服务绑定在内网IP上,通过Linux防火墙进行防护。

    4.5 CPU与IO均衡

    在一个网站提供的所有功能中,有的功能可能需要消耗大量的服务器端IO资源,像下载,视频播放等,而有的功能则可能需要消耗大量的服务器CPU资源,像视频格式转换,LOG统计等。在一个服务器集群中,当我们发现某些机器上CPU和IO的利用率相差很大的时候,例如CPU负载很高而IO负责很低,我们可以考虑将该服务器上的某些耗CPU资源的进程换成耗IO的进程,以达到均衡的目的。均衡每一台机器的CPU和IO消耗,不仅可以获得更充分的服务器资源利用,而且还能够支持暂时的过载,遇到突发事件,访问流量剧增的时候, 实现得体的性能下降(Graceful performance degradation)[34],而不是立即崩溃。

    4.6 读写分离

    如果网站的硬盘读写性能是整个网站性能提升的一个瓶颈的话,可以考虑将硬盘的读,写功能分开,分别进行优化。在专门用来写的硬盘上,我们可以在Linux下使用软件RAID-0(磁盘冗余阵列0级)[35]。RAID-0在获得硬盘IO提升的同时,也会增加整个文件系统的故障率——它等于RAID中所有驱动器的故障率之和。如果需要保持或提高硬盘的容错能力,就需要实现软件RAID-1,4或5,它们能在某一个(甚至几个)磁盘驱动器故障之后仍然保持整个文件系统的正常运行[36],但文件读写效率不如RAID-0。而专门用来读的硬盘,则不用如此麻烦,可以使用普通的服务器硬盘,以降低开销。

    一般的文件系统,会综合考虑各种大小和格式的文件的读,写效率,因而对特定的文件读或写的效率不是最优。如果有必要,可以通过选择文件系统,以及修改文件系统的配置参数来达到对特定文件的读或写的效率最大化。比如说,如果文件系统中需要存储大量的小文件,则可以使用ReiserFS[37]来替代Linux操作系统默认的ext3系统,因为ReiserFS是基于平衡树的文件系统结构,尤其对于大量文件的巨型文件系统,搜索速度要比使用局部的二分查找法的ext3快。 ReiserFS里的目录是完全动态分配的,因此不存在ext3中常见的无法回收巨型目录占用的磁盘空间的情况。ReiserFS里小文件(< 4K)可以直接存储进树,小文件读取和写入的速度更快,树内节点是按字节对齐的,多个小文件可共享同一个硬盘块,节约大量空间。ext3使用固定大小的块分配策略,也就是说,不到4K的小文件也要占据4K的空间,导致的空间浪费比较严重[38]。 但ReiserFS对很多Linux内核支持的不是很好,包括2.4.3、2.4.9 甚至相对较新的 2.4.16,如果网站想要使用它,就必须要安装与它配合的较好的2.4.18内核——一般管理员都不是很乐意使用太新的内核,因为在它上面运行的软件,都还没有经过大量的实践测试,也许有一些小的bug还没有被发现,但对于服务器来说,再小的bug也是不能接受的。ReiserFS还是一个较为年轻的,发展迅速的文件系统,它相对于ext3来说有一个很大的缺陷就是,每次ReiserFS文件系统升级的时候,必须完全重新格式化整个磁盘分区。所以在选择使用的时候,需要权衡取舍[39]。


    5 应用程序层优化

    5.1 网站服务器程序的选择

    经统计[40],当前互联网上有超过50%的网站主机使用Apache[41]服务器程序。 Apache是开源界的首选Web服务器,因为它的强大和可靠,而且适用于绝大部分的应用场合。但是它的强大有时候却显得笨重,配置文件复杂得让人望而生畏,高并发情况下效率不太高。而轻量级的Web服务器Lighttpd[42]却是后起之秀,基于单进程多路复用技术,其静态文件的响应能力远高于Apache。 Lighttpd对PHP的支持也很好,还可以通过Fastcgi方式支持其他的语言,比如Python等。 虽然Lighttpd是轻量级的服务器,功能上不能跟Apache比,某些复杂应用无法胜任,但即使是大部分内容动态生成的网站,仍免不了会有一些静态元素,比如图片、JS脚本、CSS等等,可以考虑将Lighttpd放在Squid的前面,构成 Lighttpd->Squid->Apache的一条处理链,Lighttpd在最前面,专门处理静态内容的请求,把动态内容请求通过Proxy模块转发给Squid,如果Squid中有该请求的内容且没有过期,则直接返回给Lighttpd。新请求或者过期的页面请求交由Apache中的脚本程序来处理。经过Lighttpd和Squid的两级过滤,Apache需要处理的请求大大减少,减少了Web应用程序的压力。同时这样的构架,便于把不同的处理分散到多台计算机上进行,由Lighttpd在前面统一分发。

    在这种架构下,每一级都是可以进行单独优化的,比如Lighttpd可以采用异步IO方式,Squid可以启用内存来缓存,Apache可以启用MPM(Multi -Processing Modules,多道处理模块)等,并且每一级都可以使用多台机器来均衡负载,伸缩性好。

    著名视频分享网站YouTube就是选择使用Lighttpd作为网站的前台服务器程序。

0
相关文章