您好,欢迎访问一九零五行业门户网

为Symfony2和Redis正名,基于PHP的10亿请求/周网站打造

【编者按】如果你还在symfony2和redis使用中存在这样的错误观念——不能使用redis作为主要存储;symfony2的功能很多,以至于它的运行很慢,那么不妨看向octivi的高请求网站打造。虽然没有底层细节,但详细展示基于两者应用的宏观特性,以及开发时的symfony2
【编者按】如果你还在symfony2和redis使用中存在这样的错误观念——不能使用redis作为主要存储;symfony2的功能很多,以至于它的运行很慢,那么不妨看向octivi的高请求网站打造。虽然没有底层细节,但详细展示基于两者应用的宏观特性,以及开发时的symfony2特征。
免费订阅“csdn大数据”微信公众号,实时了解最新的大数据进展!
csdn大数据,专注大数据资讯、技术和经验的分享和讨论,提供hadoop、spark、imapala、storm、hbase、mongodb、solr、机器学习、智能算法等相关大数据观点,大数据技术,大数据平台,大数据实践,大数据产业资讯等服务。
以下为译文:
有人说symfony2像其它的复杂框架一样,很慢,但是我们认为这一切都取决用户的本身。本文将介绍基于symfony2,每周执行10亿多个请求的应用的软件架构细节。
下面将展示tweeting之后的社交反馈:
本文将介绍基于symfony2和redis的应用。在此不会有过多的细节描述,相反我们将给你展示这些应用的宏观特性,以及开发时的symfony2特征。
对于低层次的symfony2性能优化实践,我们写了专门的文章——掌握symfony2性能系列——internals 和doctrine首先是关于所描述应用的一些数据。
来自单个程序节点的性能统计:
symfony2实例每秒处理700个请求,每个请求平均响应时间30毫秒varnish每秒处理12000多个请求(通过压力测试获得)注意,如下面所描述的,整个平台包括许多这种节点
redis度量:
1.6亿多个键(其中98%是永久存储);89% hits—也就是说,只有11%的交易到达mysql服务器。栈结构应用
所有的流量都会流入haproxy,haproxy将流量分配给应用服务器。
应用实例前是varnish reverse proxy。
我们保持varnish在每个应用的服务器都保持高度可用性——没有单点故障。单个varnish分配流量可能导致风险。分离的varnish实例可能降低缓存hit,不过我们可以接受这个。我们对可用性的需求高于对性能的需要,不过你可以从这些数字中看到,性能也不是什么问题。
应用的服务器配置:
xeon e5-1620@3.60ghz, 64gb ram, sataapache2 (我们甚至不用nginx)php5.4.x以php-fpm运作,伴随apc数据存储
我们使用redis和mysql存储数据,它们的数字还挺大的:
redis:1.5万次撞击/秒1.6亿个键mysql:多于400 gb的数据3亿份记录我们即使用redis作为永久存储(用的最多的资源),又使用redis作为mysql上的缓存层。与典型的缓存相比,redis存储数据的比率很高——我们存储1.55亿多个永久类型键和仅500万个缓冲键。实际上,我们可以使用redis作为主要的数据存储。
redis配有主从设置。通过这种方式我们获得ha——如果发生运行中断我们可以很快的将主节点切换到某一个从节点。一些管理任务如升级也需要这些配置。在升级节点时,我们可以选择新的主节点,然后升级先前的主节点,最后交换两个节点。
我们仍在等待生产就绪的redis集群,这些集群可以提供类似自动故障恢复(升级节点时即使是手动故障恢复也会方便的多)的功能。不过目前还没有任何关于官方发布日期的消息。
mysql通常用作非耗尽资源的第三层缓存层(varnish > redis > mysql)。所有的表都是innodb,最多的查询是简单的
select ... where 'id'={id}
这个查询返回单个结果。我们还没有发现这么设置会有什么性能问题。与redis设置不同,mysql运行在主配置上,除高可用性外,这还提供了更好的写性能(在redis中这不是什么问题,因为我们不会耗尽性能特性。)
application’s architecture
symfony2功能symfony有一些很棒的功能,这些功能使开发过程变得更容易,下面我们绍开发者最喜欢的一些功能:
注释
我们使用带注释的symfony2标准分布:
路由选择——路由定义了应用的url—我们也测试了apache的愚蠢的路由规则,但它没有任何的主要优化。服务容器——我们使用jmsdiextrabundle的服务注释定义我们的di容器—这加速了开发,允许我们用php代码处理服务定义,我们发现php代码更可读。因为应用用作rest api,所以我们主要不使用模板(例如twig)。我们保留模板主要是为了一些内部的仪表盘面板。
我们还没有发现不同的配置类型(yaml/xml)带来的性能影响。因为所有的注释都很好的存储下来了,所以没有什么令人费解的地方—最后所有的东西都是纯php代码。
下面是我们使用jmsdiextrabundle获得的服务配置样例:
/** * constructor uses jmsdiextrabundle for dependencies injection. * * @injectparams({ * em = @inject(doctrine.orm.entity_manager), * security = @inject(security.context) * }) */function __construct(entitymanager $em, securitycontext $security) { $this->em = $em; $this->security = $security;}
通过这种方式,改变类依赖项只需要改变代码。
symfony2监控—monolog和stopwatch
应用使用monolog记录意料之外的行为,捕获错误信息。我们使用多个信道获取不同应用模块的分离的日志。
因为fingerscrossed handler使用较多内存(可能导致内存泄漏),所以我们不再使用它。我们选用适当的streamhandler。使用这种方式时我们需要在单行日志信息添加冗余和额外的内容。
我们也在很多地方使用stopwatch组件以控制一些典型的应用方法。通过这种方式我们可以发现客制化逻辑一些大块中的弱点。
例如,我们追踪一些外部网络服务的请求次数:
if (null !== $this->stopwatch) { $this->stopwatch->start('my_webservice', 'request');}// makes a curl request to some my_webservice$response = $this->request($args);if (null !== $this->stopwatch) { $this->stopwatch->stop('my_webservice');}
控制台组件
开发和维护时,我们特别喜欢symfony控制台组件,这个组件为创建cli工具提供了很好的面向对象接口。应用大概添加了50%的新功能,这些新功能基于cli指令,主要用作管理或分析应用内部构件。
控制台组件妥善的处理命令语句或选项—你可以设置默认值,可选值或所需的值。好的实践总是将这些恰当的记录为代码—你可以给命令和选项设置主要描述。命令通常是自我文档的,因为添加--help选项便能生成格式化的指令描述。
$ php app/console octivi:test-command --helpusage: octivi:test-command [-l|--limit[=...]] [-o|--offset[=...]] tablearguments: table database table to processoptions: --limit (-l) limit per sql query. (default: 10) --offset (-o) offset for the first statement(default: 0)
我们必须牢记在准确设置的环境下运行指令。默认的dev可能会导致一些问题,如内存泄漏(因为更多冗长的日志存储和保存调试信息)。
$ php app/console octivi:test-command --env=prod
想要更好的信息显示,添加-v选项。
$ php app/console octivi:test-command --env=prod -vvv
进度条是一个很好的帮手。进度条甚至考虑了信息显示详细程度,当程度比较低时,只显示基本信息,程度比较高时,还可以显示运行时间,内存消耗等信息。
此外,我们还有一些耗时大约两天的迁移过程—0内存泄漏—没有进度条,监控它们将是灾难。
数据层
对于redis,数据层我们使用predisbundle。
我们拒绝doctrine orm,因为它将添加额外费用,而且我们不需要任何高级的面向对象操作。我们使用doctrine dbal代替,doctrine dbal特征如下:
查询生成器预处理语句使用predisbundle和doctrine bundle也允许我们在大量使用分析工具的时候监控弱查询。
总结多亏symfony2,这种设置在保持高性能和高可用性的同时保持了友善的开发环境——可维持,稳定。实际上这是用作电商网站的关键子系统的关键业务需求。
因此本文的最后我们可以纠正一些错误观点:
不能使用redis作为主要存储——如我们先前所说的,当然是可以的!redis是一项很稳定的技术,有一些持续性机制,你不会丢失关键数据。symfony2功能很多以至于它很慢——当你不使用例如orm的一些耗时/内存的工具时,你可以获得和silex(是的,我们测试过它)微框架类似的性能。handling 1 billion requests a week with symfony2
其它类似信息

推荐信息