PHP构建高性能系统

如何解决系统中可能存在的性能问题呢?

首先,咱们须要清楚在业务上有什么要样的性能需求;前端

第二步,根据性能的要求去考虑系统的设计,mysql

第三步,系统的开发过程当中去关注可能存在的局部性能问题。sql

评估系统的性能要求:

没有开发过性能敏感系统的团队,容易犯的错误是,不去考虑系统未来有多少人使用,并发访问有多高,须要存贮多少数量的数据? 直接就开始作系统的开发,抱着等着出了性能问题再说。系统作出来上线以后,性能的问题就暴露出来。但这时候,要解决好性能问题将要负出沉重的代价,每每是 一个系统的重写。 进度的压力成为了避免考质量与性能的理由。形成一个现象:咱们没有时间去把一个系统作好,但咱们有时间去把同一个系统作上几遍。短时间是高效率的,但长期是低效率的。数据库

在开发一个新系统时,请搞清楚如下的几个问题:

  • 系统的用户有多少? 万级 、 十万级、百万级、仍是更多?
  • 系统的使用的高峰阶段有多少人来使用? 每钞能处理多少个请求(QPS)?
  • 系统存贮的数据记录有多少条? 数据量是G,10G,仍是100G?

我举例说明一下:后端

*广告投放系统:

10个用户以对系统有写的访问, 1000万级的用户对系统有访问。
广告主要投放在网站上, 一个页面每每具备几个广告的展示。天天要达到上亿的PV。高峰的QPS所达到上十亿。
广告天天的数据量在1G之内,没有历史数据须要处理。缓存

*互动贴吧:

千万级的用户量,而且都进行读写操做。
系统在热门期间,须要支持1亿的PV,高峰QPS 要达到1250 * 2 = 2500 QPS
贴吧的贴子数: 10000贴吧 * 1000主题 * 100 贴子 = 10亿个贴子; 一个贴子平均200个汉字,即有 400G的数据量。性能优化

*B2B网站:

用户量应具备百万级.
以每用户天天平均访问3次计算,那 100万 * 2 * 20(平均每次访问PV数)= 4000万的PV,在高峰期以平均的QPS*2 = 500 *2 = 1000 (QPS)服务器

看到这些数据,你们都会有很大的疑问:网络

太超前了,如今的业务发展状况远远不须要的这样高的性能业支持,若是以很大的代价来实现,实在是太浪费,而且业务当前所须要的紧急的问题,是功能、是易用性并非性能。
这的确是一个现实的状况,这里我将在第三部份来计论这个状况,如今假设咱们须要应对这些高性能的挑战吧。并发

性能设计的指导原则

咱们面对上千万级的用户、几千的QPS、百G以上的数据。 实在没有办法以单独的服务器来支撑,所以在设计系统时,第一个要考虑的就是:

系统的水平扩展能力:

你们应很容易就理解和认同这种作法。 可是作起来确并非简单的事情,须要根据具体的应用来设计。

假设咱们须要5000的QPS,那我分解成 500 * 10,使用10组服务器来支持。 这时咱们须要考虑的问题是:

  • 用户能使用不一样的服务器来完成他的操做么?
  • 用户的会话状态,是存贮在客户端,仍是服务端?
  • 服务端有数据同步么?怎么在多台服务器来实现
  • 须要多少数据库服务器来存贮数据? 须要数据分割么?

在数据存贮方面,超过千万级的数据记录,上10G的数据,就考虑到水平扩展的能力。不管是咱们经常使用的mysql仍是oracle, 单表处理数据量是有一个性能拐点的。就须要考虑到折表,单机的数据库处理能力也是有限的,就要考虑到使用数据量的集群。

系统的水平扩展能力是解决性能敏感系统的首要原则,它使得系统具备经过增长更多的硬件设备来提升性能。
而且须要让这个扩展是容易进行的。

另外,即便咱们系统有很好的水平提展能力,提搞单机的QPS仍是很是必要。 单机的QPS过低,使得服务器的成本变得不可接受。

区别对待系统的读写访问

当面对高性能的访问时,你分析发现,在互联网的WEB应用,用户的读写访问在通常都会达到100:1,甚至会更高。高并发访问的性能问题,就会减化为, 如何提升并发的读访问速度和保证写访问的正确性有及时性。

在开发系统中,咱们经常会出现两种如下的作法:

  1. 整个系统的开发追求性能,系统没有什么结构,全部的功能的实现都是,直接在页面拼写SQL来读写数据。
  2. 全面考虑程序的结构,追求系统的扩展性和可维性。

这两种方法,都有他们适用的范围,但同时也有他们的不足。

  • 先说第二种方法,面对业务层面和系统层面的复杂性,抽象成为解决问题的有效手段。在抽象的指导下,封装、隐藏实现、隔离变化、分层都会出现系统的 设计中,但这样的设计带来的问题是间接层过多,在PHP这种动态脚本语言下,更多的代码、更多的调用层次都是会下降性能。 它适用于逻辑的复杂的系统,但性能要求在50(QPS)如下.
  • 第一种方法,有一句来形容”在山顶上速度最快的下山方法就是从山顶上直接跳下来” 用直接数据修改的方法,没法有效表达抽象,没法管理各类变化的因素,数据将不在统一的逻辑约束下变动,咱们将对变化失去控制,咱们面对将是一座千疮百孔的 烂尾楼。 正确性虽着业务屡次的修改,愈来愈得不到保证,这时性能也没有什么意义? 这种方式合适于逻辑简单的功能。

面对不一样的要求,咱们须要区别对待, 读写分离的思路,不只是程序和程序开发模式的分离,它还意味着:

  • 系统的体系结构的影响,创建集中写(单点写)、多点读的模式。 它包括前端服务器的部署、数据存贮和同步方案等。
  • 可使得读的逻辑尽量的简单,不受写逻辑的干扰。有价值的放弃对于读访问逻辑的抽象,数据不会变动,不须要统一逻辑的约束。 面对性能的要求,咱们能够弃程序的结构,以致于可重复某些代码。
  • 面对简单的读逻辑咱们能够有更多的性能优化方案。
  • 读写分离也是解决军阀割据般的网络环境(电信、网通)的方法。

举例说明:
*联盟的广告展示代码不到100行。广告的展示代码不到500行(由于定向投放),其中的逻辑只是读取本地数据,套展示模版。 全部数据都邮后端推送到前端的WEB服务器。而广告数据的生成修改,就有很复杂的系统来管理,这基本不考虑性能的问题.
*互动组开发评论系统和贴吧系统,设定的考虑也是读写分离的模式,写逻辑强调代码的结构良好,读逻辑追求性能。

考虑使用缓冲数据的机制:

在越接用户和越接用具体应用时,缓冲的效率越高。 所以可能考虑在WEB服务器来创建一缓存。 在缓存机制的设计与使用,互动团队的贴吧系统应是值得学习的项目。固然咱们也清楚那些好东西是作缓存的必备良药。Memched,BDB, varnish 须要清楚他们适合解决的问题是什么,加以利用。

无论Cache的机制如何有效,但咱们还得保证在无Cache的状况下,性能基本知足业务的须要。由于Cache老是有他的命中率的,而且也要考虑到在Cache失效后,咱们系统仍是能正常运行的。

在个人理解,”’Cache是性能的放大器。”’

在系统开发过程当中,怎么考虑处理性能的风险

在系统的开发过程的管理,本质上仍是以风险驱动的,什么最可能产生严重的问题,就应该去优先去解决。在评估性能后,咱们须要的是一个高性能要求的系统,而且系统一上线,就会立刻遇到这种性能的压力,那么我建议以下:

  1. 跟据上述的设计原则来指导你设计,并与有经验的人进行计论
  2. 借着桩的方式,快速搭建系统框架,进行性能测试,肯定总体的性能,总体的性能高于局部的性能
  3. 解决是性能关键的子系统或组件的问题,这是解决局部性能问题。
  4. 在提交功能测试前进行性能测试,不要等上线以后才发现性能的问题。

对于进度紧张,而且预期在将来半年内不会遇到性能挑战,关于上述的第3点能够先不作。但你对于系统的当前情况必定要清楚。 在系统在性能挑战出现以后,就可从容的去解决性能的问题。