Linux 千万级PV规模高性能高并发网站架构
防伪码:好久不见,你会不会突然的出现。
客户端:缓存(expires)、deflate压缩
缓存服务器:CDN/cache缓存静态内容如:html、jpg、gif、js等
静态web服务器:Apache/nginx静态服务器提供html页面内容
php/java服务器:PHP/JAVA动态内容
数据库缓存服务器:数据库缓存memcache/redis
数据库服务器:MYSQL数据库
数据存储:NFS/HADOOP等
高并发访问的核心原则其实就一句话“把所有的用户访问请求都尽量往前推”。
如果把来访用户比作来犯的"敌人",我们一定要把他们挡在800里地以外,即不能让他们的请求一下打到我们的指挥部(指挥部就是数据库及分布式存储)。
如:能缓存在用户电脑本地的,就不要让他去访问CDN/cache。能缓存CDN/cache服务器上的,就不要让CDN/cache去访问源(静态web服务器)了。能访问静态web服务器的,就不要去访问动态服务器。以此类推:能不访问数据库和存储就一定不要去访问数据库和存储。
高性能高并发高可扩展网站架构访问的几个层次:
第一层:首先在用户浏览器端,使用Apache的mod_deflate压缩传输,再比如:expires功能,deflate和expires功能利用的好,就会大大提升用户体验效果及减少网站带宽,减少后端服务器的压力。
提示:有关压缩传输及expires功能nginx/lighttpd等软件同样也有。
第二层:静态页面内容缓存,如图片/js/css等或静态数据html,这个层面是网页缓存层,比如CDN(效果比公司自己部署squid/nginx/varnish要好,他们更专业,价格低廉,比如快网/CC等,而且覆盖的城市节点更多)。自己架设squid/nginx/varnish来做小型CDN是次选(超大规模的公司可能会考虑风险问题实行自建加购买服务结合),为前端的CDN提供数据源服务,以减轻后端我们的服务器数据及存储压力,而不是直接提供cache服务给最终用户。淘宝的CDN曾经因为一部分图片的尺寸大而导致CDN压力大的情况,甚至对图片尺寸大的来改小,以达到降低流量及带宽的作用。
提示:我们也可以自己架设一层cache层,对我们购买的CDN提供数据源服务,可用的软件有varnish/nginx/squid 等cache,以减轻第三层静态数据层的压力。在这层的前端我们也可以架设DNS服务器,来达到跨机房业务拓展及智能解析的目的。
第三层:静态服务器层一般为图片服务器,视频服务器,静态HTML服务器。这一层是前面缓存层和后面动态服务器层的连接纽带。
第四层:动态服务器层:php,java等,只有通过了前面3层后的访问请求才会到这个层,才可能会访问数据库及存储设备。经过前三层的访问过滤能到这层访问请求一般来说已非常少了,一般都是新发布的内容和新发布内容第一次浏览如;博文(包括微博等),BBS帖子。
特别提示:此层可以在程序上多做文章,比如向下访问cache层,memcache,redis,mysql,oracle,在程序级别实现分布式访问,分布式读写分离,而程序级别分布式访问的每个db cache节点,又可以是一组业务或者一组业务拆分开来的多台服务器的负载均衡。这样的架构会为后面的数据库和存储层大大的减少压力,那么这里呢,相当于指挥部的外层了。
第五层:数据库cache层,比如:memcache,redis等等。
根据不同的业务需求,选择适合具体业务的数据库。对于memcache、redis,可以在第四层通过程序来实现对本层实现分布式访问,每个分布式访问的节点都可能是一组负载均衡(数十台机器)。
第六层:数据库层,一般的不是超大站点都会用mysql主从结构,程序层做分布式数据库读写分离,一主(或双主)多从的方式,访问大了,可以做级连的主从及环状的多主多从,然后,实现多组负载均衡,供前端的分布式程序调用,如果访问量再大,就需要拆业务了,比如:分司把www服务,blog服务,bbs服务都放一个服务器上,然后做主从。这种情况,当业务访问量大了,可以简单的把www,blog,bbs服务分别各用一组服务器拆分开。当然访问量再大了,可以继续针对某一个服务拆分如:www库拆分,每个库做一组负载均衡,还可以对库里的表拆分。需要高可用可以通过MHA等工具做成高可用方式。对于写大的,可以做主主或多主的MYSQL REP方式。
像百度等巨型公司除了会采用常规的mysql及oracle数据库库外,会在性能要求更高的领域,大量的使用nosql数据库(非关系型的数据库),然后前端在加DNS,负载均衡,分布式的读写分离,最后依然是拆业务,拆库,。。。逐步细化,然后每个点又可以是一组或多组机器。
特别提示:数据库层的硬件好坏也会决定访问量的多少,尤其是要考虑磁盘IO的问题,大公司往往在性价比上做文章,比如核心业务采用硬件netapp/emc及san光纤架构,对于资源数据存储,如图片视频,会采用sas或固态ssd盘,如果数据超大,可以采取热点分取分存的方法:如:最常访问的10-20%使用ssd存储,中间的20-30%采用sas盘,最后的40-50%可以采用廉价的sata。
第七层:千万级PV的站如果设计的合理一些,1,2个NFS SERVER就足够了。当然可以做成drbd+heartbeat+nfs+a/a的方式。
以上1-7层,如果都搭好了,这样漏网到第四层动态服务器层的访问,就不多了。一般的中等站点,绝对不会对数据库造成太大的压力。程序层的分布式访问是从千万及PV向亿级PV的发展,当然特殊的业务还需要特殊架构,来合理利用数据库和存储。
扩展知识点1:CDN的全称是Content Delivery Network,即内容分发网络。其基本思路是尽可能避开互联网上有可能影响数据传输速度和稳定性的瓶颈和环节,使内容传输的更快、更稳定。通过在网络各处放置节点服务器所构成的在现有的互联网基础之上的一层智能虚拟网络,CDN系统能够实时地根据网络流量和各节点的连接、负载状况以及到用户的距离和响应时间等综合信息将用户的请求重新导向离用户最近的服务节点上。其目的是使用户可就近取得所需内容,解决 Internet网络拥挤的状况,提高用户访问网站的响应速度。
举个通俗的例子:
谈到CDN的作用,可以用早些年买火车票来比喻:在没有火车票代售点和12306.cn之前。那时候火车票还只能在火车站的售票大厅购买,而小县城并不通火车,火车票都要去市里的火车站购买,而从县城到市里,来回就得n个小时车程。
到后来,小县城里出现了火车票代售点,可以直接在代售点购买火车,方便了不少,人们再也不用在一个点排队买票了。
CDN就可以理解为分布在每个县城的火车票代售点,用户在浏览网站的时候,CDN会选择一个离用户最近的CDN节点来响应用户的请求,这样海南移动用户的请求就不会千里迢迢跑到北京电信机房的服务器(假设源站部署在北京电信机房)上了。
CDN的基本原理为反向代理,反向代理(Reverse Proxy)方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求连接的客户端,此时代理服务器对外就表现为一个节点服务器。通过部署更多的反向代理服务器,来达到实现多节点CDN的效果。
首先,让我们先看传统的未加缓存服务的访问过程,以便了解CDN缓存访问方式与未加缓存访问方式的差别:
用户提交域名→浏览器对域名进行解析→得到目的主机的IP地址→根据IP地址访问发出请求→得到请求数据并回复
由上可见,用户访问未使用CDN缓存网站的过程为:
1)、用户向浏览器提供要访问的域名;
2)、浏览器调用域名解析函数库对域名进行解析,以得到此域名对应的IP地址;
3)、浏览器使用所得到的IP地址,向域名的服务主机发出数据访问请求;
4)、浏览器根据域名主机返回的数据显示网页的内容。
通过以上四个步骤,浏览器完成从用户处接收用户要访问的域名到从域名服务主机处获取数据的整个过程。CDN网络是在用户和服务器之间增加Cache层
如何将用户的请求引导到Cache上获得源服务器的数据,主要是通过接管DNS实现,下面让我们看看访问使用CDN缓存后的网站的过程:
通过上图,我们可以了解到,使用了CDN缓存后的网站的访问过程变为:
1)、用户向浏览器提供要访问的域名;
2)、浏览器调用域名解析库对域名进行解析,由于CDN对域名解析过程进行了调整,所以解析函数库一般得到的是该域名对应的CNAME记录,为了得到实际IP地址,浏览器需要再次对获得的CNAME域名进行解析以得到实际的 IP地址;在此过程中,使用的全局负载均衡DNS解析,如根据地理位置信息解析对应的IP地址,使得用户能就近访问。
3)、此次解析得到CDN缓存服务器的IP地址,浏览器在得到实际的IP地址以后,向缓存服务器发出访问请求;
4)、缓存服务器根据浏览器提供的要访问的域名,通过Cache内部专用DNS解析得到此域名的实际IP地址,再由缓存服务器向此实际IP地址提交访问请求;
5)、缓存服务器从实际IP地址得得到内容以后,一方面在本地进行保存,以备以后使用,另一方面把获取的数据返回给客户端,完成数据服务过程;
6)、客户端得到由缓存服务器返回的数据以后显示出来并完成整个浏览的数据请求过程。
通过以上的分析我们可以得到,为了实现既要对普通用户透明(即加入缓存以 后用户客户端无需进行任何设置,直接使用被加速网站原有的域名即可访问,只要修改整个访问过程中的域名解析部分,以实现透明的加速服务。
下面是CDN网络实现的具体操作过程。
使用了CDN服务后,用户的访问流程如下图所示:
1.用户向浏览器输入www.web.com这个域名,浏览器第一次发现本地没有dns缓存,则向网站的DNS服务器请求;
2.网站的DNS域名解析器设置了CNAME,指向了www.web.51cdn.com,请求指向了CDN网络中的智能DNS负载均衡系统;
3.智能DNS负载均衡系统解析域名,把对用户响应速度最快的IP节点返回给用户;
4.用户向该IP节点(CDN服务器)发出请求;
5.由于是第一次访问,CDN服务器会向原web站点请求,并缓存内容;
6.请求结果发给用户。
CDN网络是在用户和服务器之间增加Cache层,如何将用户的请求引导到Cache上获得源服务器的数据,主要是通过接管DNS实现,这就是CDN的最基本的原理,当然很多细节没有涉及到,比如第1步,首先向本地的DNS服务器请求。第5步,内容淘汰机制(根据TTL)等。但原理大体如此。
当用户访问加入CDN服务的网站时,域名解析请求将最终交给全局负载均衡DNS进行处理。全局负载均衡DNS通过一组预先定义好的策略,将当时最接近用户的节点地址提供给用户,使用户能够得到快速的服务。同时,它还与分布在世界各地的所有CDNC节点保持通信,搜集各节点的通信状态,确保不将用户的请求分配到不可用的CDN节点上,实际上是通过DNS做全局负载均衡。
对于普通的Internet用户来讲,每个CDN节点就相当于一个放置在它周围的WEB。通过全局负载均衡DNS的控制,用户的请求被透明地指向离他最近的节点,节点中CDN服务器会像网站的原始服务器一样,响应用户的请求。由于它离用户更近,因而响应时间必然更快。
每个CDN节点由两部分组成:负载均衡设备和高速缓存服务器
负载均衡设备负责每个节点中各个Cache的负载均衡,保证节点的工作效率;同时,负载均衡设备还负责收集节点与周围环境的信息,保持与全局负载DNS的通信,实现整个系统的负载均衡。CDN的管理系统是整个系统能够正常运转的保证。它不仅能对系统中的各个子系统和设备进行实时监控,对各种故障产生相应的告警,还可以实时监测到系统中总的流量和各节点的流量,并保存在系统的数据库中,使网管人员能够方便地进行进一步分析。通过完善的网管系统,用户可以对系统配置进行修改。
理论上,最简单的CDN网络有一个负责全局负载均衡的DNS和各节点一台Cache,即可运行。DNS支持根据用户源IP地址解析不同的IP,实现就近访问。为了保证高可用性等,需要监视各节点的流量、健康状况等。一个节点的单台Cache承载数量不够时,才需要多台Cache,多台Cache同时工作,才需要负载均衡器,使Cache群协同工作。
CDN的典型拓扑图如下:
CDN和反向代理的基本原理都是缓存数据,区别就在于CDN部署在网络提供商的机房,使用户在请求网站服务时,可以从距离自己最近的网络提供商机房获取数据。
CDN对网络的优化作用:
CDN系统通过在网络各处放置节点服务器,从而将网站的内容放置到离用户最近的地方,避免了影响互联网传输性能的“第一公里”和“网间互联瓶颈”等各个环节,为改善互联网环境、解决网站的服务质量和提高用户的上网速度提供了有效的解决方案。
CDN对网络的优化作用主要体现在如下几个方面:
解决服务器端的“第一公里”问题
缓解甚至消除了不同运营商之间互联的瓶颈造成的影响
减轻了各省的出口带宽压力
缓解了骨干网的压力
提起CDN,一般人都会望而止步,因为CDN太贵,都是大企业才能用得起的贵族式服务,而如今面对中小企业的CDN技术开发已经实现,并进入市场开始运营。
现在市面上CDN提供商计费方式多样,有按每月最低消费的,有按带宽收费的,有按请求数收费的,有包月包季包年限制的,还有些大多人看不懂的技术指标收费的,总之比较复杂,CDN服务在所有计费方式中,中小企业一致认为按流量收费最为合理,另外大多按流量计费方式中会有时间限制,规定时间内用不完就会全部作废,对于流量把握不好的中小企业,存在相当一部分浪费。所以企业自已也可以使用squid/varnish/nginx等构建缓存服务器。
扩展知识点2:pvuvip
PV(page view):即页面浏览量,或点击量,PV是网站分析的一个术语,用以衡量网站用户访问的网页的数量。一般来说,PV与来访者的数量成正比,但是PV并不直接决定页面的真实来访者数量,如同一个来访者通过不断的刷新页面,也可以制造出非常高的PV。
UV(unique visitor)即独立访客数:指访问某个站点或点击某个网页的不同IP地址的人数。在同一天内,UV只记录第一次进入网站的具有独立IP的访问者,在同一天内再次访问该网站则不计数。UV提供了一定时间内不同观众数量的统计指标,而没有反应出网站的全面活动。
通过cookie是判断UV值的方式:
用Cookie分析UV值:当客户端第一次访问某个网站服务器的时候,网站服务器会给这个客户端的电脑发出一个Cookie,通常放在这个客户端电脑的C盘当中。在这个Cookie中会分配一个独一无二的编号,这其中会记录一些访问服务器的信息,如访问时间,访问了哪些页面等等。当你下次再访问这个服务器的时候,服务器就可以直接从你的电脑中找到上一次放进去的Cookie文件,并且对其进行一些更新,但那个独一无二的编号是不会变的。所以当客户端再次使用cookie访问网站时,会附带此Cookie,那么此时服务器就会认为是同一个客户端,那么只会记录一次的UV
使用Cookie方法比分析客户端HTTP请求头部信息更为精准,但是会有缺点,那就是用户可能会关闭了Cookie功能。或者自动删除了cookie等操作,所以获取的指标也不能说是完全准确。
IP即独立IP数:
IP可以理解为独立IP的访问用户,指1天内使用不同IP地址的用户访问网站的数量,同一IP无论访问了几个页面,独立IP数均为1。但是假如说两台机器访问而使用的是同一个IP,那么只能算是一个IP的访问。
IP和UV之间的数据不会有太大的差异,通常UV量和比IP量高出一点,每个UV相对于每个IP更准确地对应一个实际的浏览者。
①UV大于IP
这种情况就是在网吧、学校、公司等,公用相同IP的场所中不同的用户,或者多种不同浏览器访问您网站,那么UV数会大于IP数。
②UV小于IP
在家庭中大多数电脑使用ADSL拨号上网,所以同一个用户在家里不同时间访问您网站时,IP可能会不同,因为它会根据时间变动IP,即动态的IP地址,但是实际访客数唯一,便会出现UV数小于IP数。
PV和UV是衡量一个网站流量好坏的一个重要指标,对于网站的PV和UV的统计,可使用第三方统计工具进行统计,只需要将第三方统计工具的JS代码放置于网站需要统计PV和UV的页面即可,然后登录统计工具后台查询网站的PV和UV量(如可使用的第三方统计工具为百度统计);
查询方法
1. 使用alexa统计
2. 一般大型网站都有自己的一套流量统计系统,可以到自己的后台查看。
3. 如果没有的话,可以借助GoogleAnalytics、cnzz、51.la等统计平台查看数据。
IP、PV、UV的计算
对IP计算
1.分析网站的访问日志,去除相同的IP地址
2.使用第三方统计工具
3.在网页后添加多一个程序代码统计字段,然后使用日志分析工具对程序代码字段进行统计。
对PV的计算
1.分析网站的访问日志,计算HTML及动态语言等网页的数量
2.使用第三方统计工具
3.在网页后添加多一个程序代码统计字段,然后使用日志分析工具对程序代码字段进行统计。
对UV的计算
1.分析客户端的HTTP请求报文,将客户端特有的信息记录下来进行分析。若能满足共同的特征将会被认为是同一个客户端,那么此时将记录为一个UV。
2.通过cookie
当客户端访问一个网站时,服务器会向该客户端发送一个Cookie,Cookie具有独一性,所以当客户端再次使用cookie访问网站时,会附带此Cookie,那么此时服务器就会认为是同一个客户端,那么只会记录一次的UV
缺点:使用Cookie方法比分析客户端HTTP请求头部信息更为精准,但是会有缺点,那就是用户可能会关闭了Cookie功能。或者自动删除了cookie等操作,所以获取的指标也不能说是完全准确。
每秒并发数预估:
1. 假如每天的pv为6000万;
2. 集中访问量:24*0.2=4.8小时,会有6000万*0.8=4800万(二八原则);
3. 每分并发量:4.8*60=288分钟,每分钟访问4800/288=16.7万(约等于);
4. 每秒并发量:16.7万/60=2780(约等于);
5. 假设:高峰期为平常值的二到三倍,则每秒的并发数可以达到5560~8340次。
千万PV级别WEB站点架构设计
1、代理层可以使用Haproxy或nginx,Haproxy/nginx是非常优秀的反向代理软件,十分高效、稳定。可以考虑用F5-LTM或成熟的开源解决方案LVS实现代理层负载均衡方案。
2、缓存层可以使用Squid或Varnish,缓存服务器作为网页服务器的前置cache服务器,可以代理用户向 web服务器请求数据并进行缓存。
3、静态web服务器(apache/nginx)提供静态内容访问,实现静动分离;通过相关工具(lvs/haproxy/nginx)做负载均衡(Load Balancer)
4、动态内容服务器(php/java)通过相关工具如xcache缓存解析过的动态内容。
5、数据库缓存(memcache/redis)作为数据库缓存都非常理想。
6、数据库层主流开源解决方案Mysql是首选,主从复制(一主对多从或多主多从)是目前比较靠谱的模式。
7、存储层作为数据的存储可以考虑nfs、分布式文件系统(如mfs)、hadoop(hadoop适合海量数据的存储与处理,如做网站日志分析、用户数据挖掘等)
当用户请求的是静态资源(图片/视频/html等),不需要计算处理时,在CDN或缓存层就结束了,当缓存不能命中时,就会去web server中取相应的数据。只有当用户请求动态资源时,才会到动态内容服务器。动态内容服务器可以从数据库缓存或者MySQL中获得数据。
此外,如果前端的程序和数据的存取不同步,是需要异步访问的。这就需要使用一些消息队列,如rabbitmq,这在后面openstack相关学习做进一步的讲解。同时Apache的开源项目中的activemq也能提供相关的功能。
注:消息队列可以解决子系统/模块之间的耦合,实现异步,高可用,高性能的系统。是分布式系统的标准配置。
例如消息队列在购物,配送环节的应用。
用户下单后,写入消息队列,后直接返回客户端;
库存子系统:读取消息队列信息,完成减库存;
配送子系统:读取消息队列信息,进行配送;
欢迎加技术群:323779636(Shell/Python运维开发群)
本文出自 “一盏烛光” 博客,谢绝转载!