winston 发表于 2011-12-17 10:14:04

淘宝李晓拴:淘宝网电子商务应用中的PHP架构与性能优化

源自:http://tech.qq.com/a/20110512/000298.htm
大家好,大家知道淘宝搜索是一个典型PHP架构。在座同学不知道有多少人使用过淘宝搜索可以举手示意一下?在开始这个话题之前我们先谈一下Polyglot,多语言混合编程,淘宝有很多系统是利用Java来开发的。淘宝大概有上千名Java工程师,也做了非常多Java工作,我们为什么还要选择PHP呢?一方面来讲我们利用一些外部动态,PHP开发效率更高一些,另外我们技术熟练程度。
所以,也有应了那句话“没有最好,只有最适合”。其实我们发现不管是任何语言来讲,Java也好,PHP也好和C也好,我们会利用Java做一些接口,利用PHP来写一些VO的功能,同时也会利用C写一些PHP扩展。接下来进入我们今天第一个话题,搜索产品介绍。正如大家所看到一样,这个就是我们淘宝搜索首页,非常简单一个搜索框一个搜索按纽,下面是一些热门关健词,当你搜索之后就会进入我们搜索结果页,看上去有点复杂。只要大家用过淘宝,基本上大家都可能进入这样一个页面。
今天主要内容就是讲解这个页面,还有其他搜索产品,一淘,是淘宝面向站外用户推出电子商务搜索引擎,这是一淘的首页,和淘宝搜索其他产品一样,也是标准的LAMP架构。接下来一个产品是我们的排行榜,和前面有一些差别,使用NGS来做,排行榜有非常多静态内容,我们在服务器选题上采用了NGS。
接下来我来讲一讲淘宝搜索整体架构,讲架构之前,可能会讲一下共同模块,这样大家对理解架构更加容易。首先,看一下网络,这张图其实是一个非常简单的落说明图,用户访问搜索域名,会根据用户IP定位到不同机房,比如有电信机房,网通机房,和教育网。为什么有三个机房呢?第一是有中国特殊国情决定的,第二也是为了容灾,每个机房大概都有几十台机器。淘宝搜索每天流量也在每天几亿,我们每个机房部署几十台机器来控制流量。
这些机器主要来请求PHP,页面还有很多资源文件,像CSC,还有图片,这是部署在我们CDN上。每台机器普通64位Linux系统,安装是阿帕奇,没有用5.3,因为我们一些扩展可能也是历史原因,一些扩展目前还不能迁移到5.3上,这也是我们接下来要做的工作。这个是放大搜索结果页,大家可以看到图上整个页面大概分了几个区域。最上面是搜索框,比如说有LOGO,有搜索框,再下面有一些导航条,中间这个区域我们把它叫做智能导航模块,右侧叫做掌柜推荐,大家可以理解为广告。
这个其实是所有搜索结果页基本都比较类似的,不管大家用Google也好,百度也好,或者其他MSN都非常类似,上面搜索框做搜索结果,右侧是广告。因为淘宝搜索页大概有3到4屏,这页主要是搜索相关一些筛选功能,比如上面看到有不同的筛选区,下面有不同结果,只不过大家没有特别留意。上面那个区我们叫做产品搜索区域,中间这个区域叫做商品搜索区域,在往下是其他一些文字链之类,最下面是翻页。
有些细节大家可能不太好理解,打个比方。大家去Google搜索的时候,当你搜索北京天气的时候,或者搜索北京奥运会的时候,搜索结果页里面有非常多的内容,比如有新闻的,有网页,甚至还有论坛的。不同的来源,其实有不同的后端服务提供的,怎么样在搜索结果页里面把它展现出来,这其实就是一个问题,是我们问题和挑战。
这里面有两个核心问题,第一个来讲,对于查询应该展示哪些模块,并不是每次搜索的时候都要出产品搜索结果。第二个问题,如果你要查询多个模块的时候,怎么样保证高性能,让用户看到快速的搜索结果。试想一下,我们这个结果我们回到上一页,这个页面里面其实是要查非常多服务,中间智能导航就是有很多服务,下面有一个相关搜索模块,包括右侧广告,和下一页产品搜索结果,商品搜索结果,这样算下来这个页面要查5到6个业务模块。
所以,怎么样查询多个模块的时候,能够保持高的性能,让用户快速看到搜索结果。带着这些问题,我们来看一下它的架构。这张架构其实也是非常简单图,首先用户可以进入我们一些入口程序,相当于搜索一个非常简单的教研程序看看是不是合法和编码。这些工作做完之后,会把用户搜索词,用户搜索诺基亚,搜索凉鞋等等词分配到解析,对于搜索来说理解用户意图非常重要,可以知道用户想要找什么,要找的这个东西,应该在哪个内幕下,或者有哪些属性。
所以,我们会去调来这个模块获取用户相关信息,查取相关内容。我们知道核心一个问题,应该展示哪些模块,同时对这个结果,应该怎么去展示。在这个时候,我们会去请求缓存模块,因为像我们刚才讲的一样,他其实有5、6个后台请求模块,我们会去看看缓存有没有命中,如果命中缓存问题就非常简单,直接把这个数据从缓存拿出来一组装,通过这个模板来做一切展示。
如果没有命中缓存的话,我们会有一个专门检索模块,会根据你需要的数据,必须你需要六个模块,根据六个模块去请求后台一些服务,在这里面是并发来做的,如何实现会在接下来讲。所以,通过这样一个架构,能够实现查询内容,以及能够并发去获取相关数据。接下来,讲一下性能优化,因为对搜索来讲,性能方面是非常关注。
这张图是09年Google合并的一些相关研究人员,他们通过一些实验对比来发现,性能对于搜索影响。当这个网站速度下降几秒之后,他们会发现用户点击,用户收入,相关广告收入,用户的满意度都会有非常明显下降。其实,性能来讲,这个话题这几年也变的逐渐非常热门起来,不管是从06年雅虎提出一些相关APP Store,或者前端优化十几条军规,一直到去年这里面领军人物史蒂夫提出一个WTO概念,做性能优化已经可以做成一个产业。
所以,更好性能意味着更低的成本,更高收入,以及更好的用户体验。所以,我们在性能优化方面也做了非常多的工作。这些工作整理起来,我们可以把它归纳为性能规划CPP的原则,第一条就是Cache,缓存。做这种网站缓存非常重要,甚至有时候是非常关键一点。缓存我们通常使用两个方式,第一就是APC,如果大家做PHP可能对APC都比较了解。第二点就是Memcached,我们使用了一些缓存。
再下面一点就是并发,PHP并没有多线程概念。这里面我们利用一些技术,可以并发去访问后台一些接口。第三点就是预期,其实做性能也好,类似于优化也好,有时候你不能达到足够快,至少也要让这个网站看上去比较快,我们把它叫做预期。其实简单做法,让这个网站能够支持这种类似于分化输出,当用户搜索完了之后,你可以让你的网站,搜索框先出来,再去查后台模块,最后在展示最下面的内容。
这张图就是关于Cache一个介绍,比如APC。提供一些APC类似于Opcode的软件也好,我们选择的是APC。从这张图上可以看到,使用APC以后,能够大幅优化PHP代码解释时间,我们之前也做过一些性能对比,用过APC之后能够把性能提升25%-40%左右。对于APC还有很深入话题,比如APC里面有一些参数,有兴趣的同学可以上网查一下,也可以跟我交流。
这张图是一个Memcached的事例,基本原理就是Check,Miss,Store,Check是第一步,当你最开始访问这个模块是没有,如果开始没有,就会去到后台计算相关数据,比如去查数据库,去请求远程接口。当拿到结果之后,会把这个数据存储到Cache里面去,并且把这个结果反映给输出,你第二次来的时候就命中Cache,所以Cache直接输出结果了。
对于Memcached来讲是一个非常成熟技术,我们用Memcached大概有几十台机器,每台机器开了几个G来做,大概有几百个G,是一个独立的Cache集群。因为我们是多个模块,当你去请求Cache,可以查一下有没有命中,如果没有命中可以请求后台,你可以一次性向Memcached发请求,一次性把请求发过去看有没有命中,他会告诉你有几个模块命中有几个模块没有命中,我们在去查后端,可以减少Memcached的请求。
下面和大家分享一下并发,PHP其实不支持多线程。如果说要串行访问多个后台缺口会非常严重影响性能,做一个简单计算,刚才所讲一样,如果有5个后台模块。每个模块访问需要50毫秒,5×5就是250毫秒,对做搜索来讲其实是非常慢了。所以,如果串行访问后台接口会非常慢。我们解决方案是使用CURL和Multi功能,下面列了一些相关函数,大家可以在下面去查查手册可以看一下,这里面还有更详细的一个文章来介绍。
基本原理利用提供封装功能一次性把请求发出去,等着响应拿到结果进行处理。按照优化原则,80%优化都集中在前端。前端我们做了一些尝试,比如我们了CDN Combo,合并HTTP请求。比如我们这个页面需要用5个页面表,我们可以对请求进行合并,减少请求优化性能。同时,按照最常规做法就是压缩CSS/JS文件,压缩完之后尺寸可以大大减少,提高加载速度。
还有一些做法,我们在首页预先加载结果页所需部分文件,用户要做的事情通常是搜索。在首页可以预先加载所需要的CSS和JS文件,在首页进行一个平衡,据我了解Google很多网站都是这么做的。还有图片的Lazy-Load,相当于业界一个标准做法,像搜索结果页大概有40张图片,大多数情况下来讲,用户可能只会看前面几张图片,如果满意就点走了,如果不满意会做一些搜索和其他筛选。接下来你屏幕以下非常多的图片就有点浪费了,如果用户不看的话,所以我们就采用Lazy-Load,当用户滚屏的时候可以大幅度提高性能,降低带宽。
接下来给大家讲一下监控报警,每天几百台机器监控报警也是非常重要的。这张图是截取在我们公司里面一个哈勃监控系统,我们通常统计了命中率,统计了一些数据在这里面进行分析,具体实现大概是这样的。我们的程序是有日志,比如有统计PV,超时数据,如果一旦访问后台结果超时的时候会在日志里面做记录。还有Latency,如果发现一些问题,我们定一些规则,比如超时时数达到多少,或者PV变化,就会发短信进行报警。
同时,我们刚才讲了我们有非常多的memcached-top来作为缓存,所以我们使用memcached脚本监控memcached集群运行情况。我们使用xhprof采样获得线上程序运行情况,有点类似与PHP。由于时间关系,今天我要讲的内容基本上就这些,其实淘宝搜索他的内容非常多,刚才也只是讲到一些点,感兴趣的同学可以会后跟我联系。我们也在招一些PHP工程师,我们也非常希望大家能够加入我们,和我们一起来做下一代的淘宝搜索。我的联系方式是jiansu@taobao.com,还可以访问我们的微博,感谢大家。
作者:21aspnet 发表于2011-12-16 1:22:17 原文链接
页: [1]
查看完整版本: 淘宝李晓拴:淘宝网电子商务应用中的PHP架构与性能优化