8.5 细分五层解说网站架构

目前网站架构一般分为网页缓存层、负载均衡层、Web服务器层、文件服务器层、数据缓存层及数据库层,一共五层,这样在后面的讨论过程中,就可以依次用这五层对网站架构进行讨论。为了更具说服力,下面将以笔者维护过并且正在维护的较大的生产环境来举例说明。

1.网页缓存层

广告:个人专属 VPN,独立 IP,无限流量,多机房切换,还可以屏蔽广告和恶意软件,每月最低仅 5 美元

首先说网页缓存层,比如CDN的租赁,其效果比公司自己部署Squid/Varnish更好更专业,毕竟Bind View需要精准细分,而且价格相当低廉,所覆盖的城市也更多,故而推荐采用CDN租赁的方式。

很多朋友喜欢尝试自建CDN,这是一个吃力不讨好的活儿,未必能达到预期目标,关于这块运维架构师在网站架设初期就应该规划好,不要等到网站流量及压力巨大时才去规划。事实上,这一层有很多优秀的开源软件都能胜任这块工作,比如传统的Squid。另外,后起之秀Nginx和Varnish因为性能优异,越来越多的朋友尝试在自己的网站使用它们作为自己的网页缓存。事实上,Nginx已经具备Squid所拥有的Web缓存加速功能。此外,Nginx对多核CPU的利用胜过Squid,现在越来越多的架构师都喜欢将Nginx同时作为“负载均衡服务器”与“Web缓存服务器”来使用,大家可以根据自己网站的情况,来决定究竟使用哪种软件来对自己的网站提供反向代理加速服务。

2.负载均衡层

我们熟悉的开源软件技术有LVS/HAProxy,还有Nginx,它们的性能都是非常优异的。HAProxy可能大家不是特别熟悉,但HAProxy在生产环境下确实表现优异,拥有强大的吞吐能力,稳定性也能与硬件相媲美,并且淘宝也在大规模地推广使用HAProxy,有兴趣的朋友可以关注一下。

建议负载均衡分成两级来处理,一级是流量四层分发,二级是应用层面七层转发,即业务层面。首先可以通过LVS或HAProxy将流量转发给二层负载均衡(一般为Nginx),即实现了流量的负载均衡,此处可以使用如轮询、权重等调度算法来实现负载的转发;然后二层负载均衡会根据请求特征再将请求分发出去。此处为什么要将负载均衡分为两层呢?

1)第一层负载均衡应该是无状态的,方便水平扩容。我们可以在这一层实现流量分组(内网和外网隔离、爬虫和非爬虫流量隔离)、内容缓存、请求头过滤、故障切换(机房发生故障后切换到其他机房)、限流、防火墙等一些通用型功能,无状态设计,可以水平扩容。

2)二层Nginx负载均衡可以实现业务逻辑,或者反向代理到如Tomcat,这一层的Nginx跟业务有关联,可实现业务的一些通用逻辑。这一层如果可能的话,也要尽量设计成无状态设计,方便水平扩容。

3.Web服务器层

Web层压力比较大的网站现在都将Web主要应用服务器换成了Nginx,事实上,它在抗并发能力和稳定性方面确实超过了预期。另外,Linux集群有一个优势,就是它的高扩展性,特别是水平(横向)扩展。就算网站的并发连接数有10万以上,也无非是多加几台Web机器(廉价的PC服务器也是可行的)。在实际的线上维护时笔者发现,即使是在高峰期间,实际上每台Web的并发并不算是特别大,所以网站的压力在这一层也能通过技术手段加以克服。

4.文件服务器层

现在大家的生产服务器一般是使用下面的方案:

1)单NFS作为文件服务器,这样的好处是维护方便,但存在着单点故障的问题,NFS机器出现故障时需要人为手动干预。

2)NFS分组,虽然这样可以分摊压力,但一样也存在着单点故障的问题,出现故障时需要人为手动干预。

3)DRBD+Heartbeat+NFS高可用文件服务器,维护方便,也不存在着单点故障的问题,但随着访问量的增大,后期一样存在着压力过大的问题。

4)采用分布式文件系统。

文件服务器磁盘I/O压力过大,这也是一个常见的问题,我们在维护自己的网站时,通常采取的做法有以下几点。

·对于静态内容,如CSS、JS、HTML还有图片文件,可以通过租赁CDN的方式来处理。

·将图片服务器独立出来,并分配独立域名。

·磁盘的优化:将程序的读写缓存区设置得尽可能大一些。这样做的好处是:程序不是每次调用都直接写磁盘,而是先缓存到内存中,等缓存区满了再写入磁盘。

·在适当的场景采用分布式文件系统,例如MooseFS。MooseFS易用、稳定,对海量小文件尤其高效,而且新版的MooseFS解决了Master Server存在的单点故障的问题,文档和社区也非常成熟,国内越来越多的公司都在使用MFS。事实上,分布式文件系统是解决文件服务器压力过大的最终途径。但是凡事总是有利有弊,越是功能强大的东西越是复杂。随着网站功能的增多,摊子越大,机器越多,维护起来就会越复杂,这样会极大地增加运维人员的工作难度。

大家可以尝试根据自己网站的情况,来决定究竟选择哪一种开源软件作为自己的文件服务器。

5.数据缓存层和数据库层

网站的PV、UV及QPS和并发连接数增加以后,数据库这块的压力是最大的,数据库的压力归根结底还是磁盘的I/O压力。

Oracle RAC是很成熟的商业分布式方案,它保证了数据的高可用性,当然了价格也是非常昂贵的(如果使用了高配置的PC服务器。Oracle一般按照CPU的个数来收费);那么如果使用免费的开源方案,例如MySQL数据库,面对这种数据库磁盘I/O压力大的情况,应该如何处理呢?

首先在业务逻辑上将数据进行分离。很多读写频繁的业务数据,比如ip list和domain等信息都没有必要用MySQL数据库来保存,我们利用redis分布式缓存来保存这些数据,这样读取速度也能得到保证,后端MySQL数据库的压力也可以得到缓减。

其次,数据库的硬件方面可以考虑投入磁盘阵列做成RAID 10,如果资金充裕,磁盘可以用SSD固态硬盘来代替SAS机械硬盘。

必须要合理地设计MySQL数据库的架构,事实上,在生产环境下,一主多从、读写分离是比较靠谱的设计方案,对于MySQL的负载均衡,这里推荐大家使用LVS/DR,这是因为从机MySQL节点机器超过10台时,HAProxy的性能将不如LVS/DR。

如果网站的业务量过大,还可以采用分库的方法,比如将网站的业务量分成Web、Blog、Mall等几组,每一组均采用主从架构,这样设计的话就避免了单组数据库压力过大的情况。

最后,还应该配合公司的MySQL DBA,在数据库参数优化、SQL语句优化、数据切分上多做功夫,避免让MySQL数据库成为网站的瓶颈。必要的时候,考虑分布式SQL解决方案,例如Redshift及Hbase等。