高负载、高并发网站架构知识汇总-大流量网站架构的几点认识

高负载、高并发网站架构知识汇总-大流量网站架构的几点认识

[ 其它]
post by Wrong-T / 2010-6-7 16:43 Monday

 

一:硬架构 mysql

 

1 :机房的选择: 程序员

在选择机房的时候,根据网站用户的地域分布,能够选择网通或电信机房,但更多时候,可能双线机房才是合适的。越大的城市,机房价格越贵,从成本的角度看能够在一些中小城市托管服务器,好比说广州的公司能够考虑把服务器托管在东莞,佛山等地,不是特别远,可是价格会便宜不少。 sql

2 :带宽的大小: 数据库

一般老板花钱请咱们架构网站的时候,会给咱们提出一些目标,诸如网站天天要能承受100PV 的访问量等等。这时咱们要预算一下大概须要多大的带宽,计算带宽大小主要涉及两个指标(峰值流量和页面大小),咱们不妨在计算前先作出必要的假设: apache

第一:假设峰值流量是平均流量的5 倍。
第二:假设每次访问平均的页面大小是100K 字节左右。
编程

若是100PV 的访问量在一天内平均分布的话,折合到每秒大约12 次访问,若是按平均每次访问页面的大小是100K 字节左右计算的话,这12 次访 问总计大约就是1200K 字节,字节的单位是Byte ,而带宽的单位是bit ,它们之间的关系是1Byte = 8bit ,因此1200K Byte 大体就至关于9600K bit ,也就是9Mbps 的样子,实际状况中,咱们的网站必须能在峰值流量时保持正常访问,因此按照假设的峰值流量算,真实带宽的需求应该在45Mbps  左右。 缓存

固然,这个结论是创建在前面提到的两点假设的基础上,若是你的实际状况和这两点假设有出入,那么结果也会有差异。 服务器

3 :服务器的划分: 架构

先看咱们都须要哪些服务器:图片服务器,页面服务器,数据库服务器,应用服务器,日志服务器等等。 并发

对于访问量大点的网站而言,分离单独的图片服务器和页面服务器至关必要,咱们能够用lighttpd 来跑图片服务器,用apache 来跑页面服务 器,固然也能够选择别的,甚至,咱们能够扩展成不少台图片服务器和不少台页面服务器,并设置相关域名,如img.domain.com www.domain.com ,页面里的图片路径都使用绝对路径,如<img src="http://img.domain.com/abc.gif" /> ,而后设置DNS 轮循,达到最初级的负载均衡。固然,服务器多了就不可避免的涉及一个同步的问题,这个可使用rsync 软件来搞定。

数据库服务器是重中之重,由于网站的瓶颈问题十有八九是出在数据库身上。如今通常的中小网站多使用MySQL 数据库,不过它的集群功能彷佛尚未达 到stable 的阶段,因此这里不作评价。通常而言,使用MySQL 数据库的时候,咱们应该搞一个主从(一主多从)结构,主数据库服务器使用innodb  表结构,从数据服务器使用myisam 表结构,充分发挥它们各自的优点,并且这样的主从结构分离了读写操做,下降了读操做的压力,甚至咱们还能够设定一个专门的从服务器作备份服务器,方便备份。否则若是你只有一台主服务器,在大数据量的状况下,mysqldump 基本就没戏了,直接拷贝数据文件的话,还得先中止数据库服务再拷贝,不然备份文件会出错。但对于不少网站而言,即便数据库服务仅中止了一秒也是不可接受的。若是你有了一台从数据库服务器,在备份数 据的时候,能够先中止服务(slave stop )再备份,再启动服务(slave start )后从服务器会自动从主服务器同步数据,一切都没有影响。可是主从结构也是有致命缺点的,那就是主从结构只是下降了读操做的压力,却不能下降写操做的压力。为了适应更大的规模,可能只剩下最后这招了:横向/ 纵向分割数据库。所谓横向分割数据库,就是把不一样的表保存到不一样的数据库服务器上,好比说用户表保存在A 数据库服务器上,文章表保存在B 数据库服务器上,固然这样的分割是有代价的,最基本的就是你无法进行LEFT JOIN 之类的操做了。所谓纵向分割数据库,通常是指按照用户标识(user_id )等来划分数据存储的服务器,好比说:咱们有5 台数据库服务器,那么 “user_id % 5 + 1” 等于1 的就保存到1 号服务器,等于2 的就保存到2 好服务器,以此类推,纵向分隔的原则有不少种,能够视状况选择。不过和横向分割数据库同样,纵向分割 数据库也是有代价的,最基本的就是咱们在进行如COUNT, SUM 等汇总操做的时候会麻烦不少。综上所述,数据库服务器的解决方案通常视状况每每是一个混合的方案,以其发挥各类方案的优点,有时候还须要借助 memcached 之类的第三方软件,以便适应更大访问量的要求。

若是有专门的应用服务器来跑PHP 脚本是最合适不过的了,那样咱们的页面服务器只保存静态页面就能够了,能够给应用服务器设置一些诸如 app.domain.com 之类的域名来和页面服务器加以区别。对于应用服务器,我仍是更倾向于使用prefork 模式的apache ,配上必要的 xcache 之类的PHP 缓存软件,加载模块要越少越好,除了mod_rewrite 等必要的模块,没必要要的东西通通舍弃,尽可能减小httpd 进程的内存消耗,而那些图片服务器,页面服务器等静态内容就可使用lighttpd 或者tux 来搞,充分发挥各类服务器的特色。

若是条件容许,独立的日志服务器也是必要的,通常小网站的作法都是把页面服务器和日志服务器合二为一了,在凌晨访问量不大的时候cron 运行前一天 的日志计算,不过若是你使用awstats 之类的日志分析软件,对于百万级访问量而言,即便按天归档,也会消耗不少时间和服务器资源去计算,因此分离单独的日志服务器仍是有好处的,这样不会影响正式服务器的工做状态。

二:软架构

1 :框架的选择:

如今的PHP 框架有不少选择,好比:CakePHPSymfonyZend Framework 等等,至于应该使用哪个并无惟一的答案,要根据Team 里团队成员对各个框架的了解程度而定。不少时候,即便没有使用框架,同样能写出好的程序来,好比Flickr 听说就是用Pear+Smarty 这样的类库写出来的,因此是否用框架,用什么框架,通常不是最重要,重要的是咱们的编程思想里要有框架的意识。

如今的.NET 框架有不少选择,好比:cnForums.textcs, Castle, 等等

2 :逻辑的分层:

网站规模到了必定的程度以后,代码里各类逻辑纠缠在一块儿,会给维护和扩展带来巨大的障碍,这时咱们的解决方式其实很简单,那就是重构,将逻辑进行分层。一般,自上而下能够分为表现层,应用层,领域层,持久层。

所谓表现层,并不只仅就指模板,它的范围要更广一些,全部和表现相关的逻辑都应该被归入表现层的范畴。好比说某处的字体要显示为红色,某处的开头要空两格,这些都属于表现层。不少时候,咱们容易犯的错误就是把本属于表现层的逻辑放到了其余层面去完成,这里说一个很常见的例子:咱们在列表页显示文章标题的时候,都会设定一个最大字数,一旦标题长度超过了这个限制,就截断,并在后面显示“..” ,这就是最典型的表现层逻辑,可是实际状况,有不少程序员都是在非表现层代码里完成数据的获取和截断,而后赋值给表现层模板,这样的代码最直接的缺点就是一样一段数据,在这个页面我可能想显示前10 个字,再另外一个 页面我可能想显示前15 个字,而一旦咱们在程序里固化了这个字数,也就丧失了可移植性。正确的作法是应该作一个视图助手之类的程序来专门处理此类逻辑,好比说:Smarty 里的truncate 就属于这样的视图助手(不过它那个实现不适合中文)。

所谓应用层,它的主要做用是定义用户能够作什么,并把操做结果反馈给表现层。至于如何作,一般不是它的职责范围(而是领域层的职责范围),它会经过委派把如何作的工做交给领域层去处理。在使用MVC 架构的网站中,咱们能够看到相似下面这样的URLdomain.com/articles/view/123 ,其内部编码实现,通常就是一个Articles 控制器类,里面有一个view 方法,这就是一 个典型的应用层操做,由于它定义了用户能够作一个查看的动做。在MVC 架构中,有一个准则是这么说的:Rich Model Is Good 。言外之意,就是Controller 要保持 一些比较好,进而说明应用层要尽可能简单,不要包括涉及领域内容的逻辑。

所谓领域层,最直接的解释就是包含领域逻辑的层。它是一个软件的灵魂所在。先来看看什么叫领域逻辑,简单的说,具备明确的领域概念的逻辑就是领域逻辑,好比咱们在ATM 机上取钱,过程大体是这样的:插入银联卡,输入密码,输入取款金额,肯定,拿钱,而后ATM 吐出一个交易凭条。在这个过程当中,银联卡 在ATM 机器里完成钱从账户上划拨的过程就是一个领域逻辑,由于取钱在银行中是一个明确的领域概念,而ATM 机吐出一个交易凭条则不是领域逻辑,而仅是一 个应用逻辑,由于吐出交易凭条并非银行中一个明确的领域概念,只是一种技术手段,对应的,咱们取钱后不吐交易凭条,而发送一条提醒短信也是可能的,但并非必定如此,若是在实际状况中,咱们要求取款后必须吐出交易凭条,也就是说吐出交易凭条已经和取款紧密结合,那么你也能够把吐出交易凭条看做是领域逻辑 的一部分,一切都以问题的具体状况而定。在Eric 那本经典的领域驱动设计中,把领域层分为了五种基本元素:实体,值对象,服务,工厂,仓储。具体能够参 阅书中的介绍。领域层最常犯的错误就是把本应属于领域层的逻辑泄露到了其余层次,好比说在一个CMS 系统,对热门文章的定义是这样的:天天被浏览的次数多 于1000 次,被评论的次数多于100 次,这样的文章就是热门文章。对于一个CMS 来讲,热门文章这个词无疑是一个重要的领域概念,那么咱们如何实现这个逻辑的设计的?你可能会给出相似下面的代码:“SELECT ... FROM ... WHERE  浏览 > 1000 AND  评论 > 100” ,没错,这是最简单的实现方式,可是这里须要注意的是 天天被浏览的次数多于1000 次,被评论的次数多于100 这个重要的领域逻辑被隐藏到了SQL 语句中,SQL 语句显然不属于领域层的范畴,也就是说,咱们的领域逻辑泄露了。

所谓持久层,就是指把咱们的领域模型保存到数据库中。由于咱们的程序代码是面向对象风格的,而数据库通常是关系型的数据库,因此咱们须要把领域模型 碾平,才能保存到数据库中,可是在 PHP 里,直到目前尚未很是好的 ORM 出现,因此这方面的解决方案不是特别多,参考 Martin 的企业应用架构模式一   书,大体可使用的方法有行数据入口( Row Data Gateway )或者表数据入口( Table Data Gateway),或者把领域层和持久层合二为一变成活动记录(Active Record)的方式。

相关文章
相关标签/搜索