前提: Lamp架构(原理上虽然jsp,.net等都一样,但我现在只懂php了) 1.用户对准确度的要求是不一样的.银行会要求客户帐上的钱的数目永远是精确的,但是论坛的在线人数,贴子数没这个必要.每天有成千上成的贴子发表。谁会去对质?我们只半个小时算一个甚至每天算一次就行了.所以,应用中要是没加Cron,那就肯定不是一个好应用.想象一下awstats,每当你的老板让你给演示一下前一周的访问周数据时,它就嘎吱嘎吱地算上老半天,然后在你的老板快要睡着时IE终于弹出一个页:服务器超时…. 你就知道要把一些服务设为定时跑一次,而不是时时保持最新最准确了 2.瓶颈永远是先在CPU/内存/磁盘IO中的一个出现.他们很少是同时告急的.因此,针对这个设计一个.比如:某台服务器上CPU占用平均为60%左右,而内存占用是5%左右。那么我们可以预先猜测,CPU资源会首先占尽。由于日志显示占用CPU最多的是mysqld进程,说明mysql查询耗尽了CPU.再查之,原来是贴子主题太多,一个表有上G大小,索引不当. 找到问题,于是马上做出改进.原来的URL已经优化成***.com/topic/10/10001.html,***.com/topic/12/12001.html…这样的了,但其实后台是用rewrite的.而id从1到100,000的主题都因为已经太老,无人参与回复了,所以没必要每次都查库.马上写个脚本,将***.com/topic/1.html….***.com/topic/10/10001.html…这些页面都读下来,保存为web根下/topic/***/***.html文件。现在这些文件是实际存在的了,Apache会优先读这个静态文件,而不是适用rewriterule了. (注:我的apache 的rewrite规则是这样写的,这样文件找不到的时候会交给index.php来处理. rewriteEngine on RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d rewriterule . /index.php [L] ) 现在再看一看,mysqld占CPU是少了不了.但还是不够啊.咱们的内存还没有用上呢。才10%,不行.于是又有了办法:架上squid或是类似缓存服务,大量起用内存缓存,现在就好多了.内存,CPU都用上了.如果这时CPU使用率仍然领先内存,那咱们再启用mem_cache,不过启用mem_cache后要改程序,改得好才能真正提交效率. 3.同是数据,用户名跟用户发的贴子内容这两个数据就不一样.一个咱们用varchar存在库中,另一个咱们得用text来存.这两个占用资源也大不一样啊.而且,贴子主题和发表用户名的读取的次数远大于贴子内容读取次数.这也是一个不均衡。于是基于这样的考虑,我把存储贴子数据表分开了。 现在的表是这样的:一个表存储用户名,发表时间,贴子标题等信息.另外建10个表,专门用来存储发贴内容.具体存在哪一个表,由这个主题贴ID的最后一位来定. 好了,由于发贴内容比较长,我把它分表(为了简化模型,是分表。实际有可能是分库,分服务器)了.而贴子主题由于要进行列表显示,搜索等操作,就没有分表.内容的查询效率是提高了。可是由于贴子主题要进行大量列表显示和搜索,且都在一个表中,还是慢啊. 不急,咱再分析. a:这个表中存储的数据都比较短小. b:这个表中常用来做列表显示,用户往往在论坛中是看了第一页标题,可能没什么吸引人的,于是又点了下一页…部分贴子会进去看一下内容.但是你见过用户一直点到第100页吗?而且,用户看贴子的量也绝对大于发贴子….除非他是供职于某论坛的版主…. 好了,又总结出不均衡性来了.大多数情况下用户只看前100页,那咱们就把这100页数据拿出来,建一个内存表,再放一份.Mysql内存表有一个限制,就是字段不能超过255字节,但咱们的这个表刚好符合.现在咱们写数据时主题表和存主题的内存表中都写入一次,读数据的时候,就从内存表中读…这样是不是快很多了? 参考: 把握web 开发的平衡与不平衡, http://www.162cm.com/archives/388.html