设为首页收藏本站

LUPA开源社区

 找回密码
 注册
文章 帖子 博客
LUPA开源社区 首页 业界资讯 技术文摘 查看内容

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

2014-8-5 11:01| 发布者: joejoe0332| 查看: 6203| 评论: 0|原作者: 蔡仁君|来自: CSDN

摘要: 如果你还在Symfony2和Redis使用中存在这样的错误观念——不能使用Redis作为主要存储;Symfony2的功能很多,以至于它的运行很 慢,那么不妨看向Octivi的高请求网站打造。虽然没有底层细节,但详细展示基于两者应用的 ...


栈结构

应用

  所有的流量都会流入HAProxy,HAProxy将流量分配给应用服务器。

  应用实例前是Varnish Reverse Proxy。

  我们保持Varnish在每个应用的服务器都保持高度可用性——没有单点故障。单个Varnish分配流量可能导致风险。分离的Varnish实例可能降低缓存hit,不过我们可以接受这个。我们对可用性的需求高于对性能的需要,不过你可以从这些数字中看到,性能也不是什么问题。

  应用的服务器配置:

  • Xeon E5-1620@3.60GHz, 64GB RAM, SATA
  • Apache2 (我们甚至不用nginx)
  • PHP 5.4.X以PHP-FPM运作,伴随APC


数据存储

  我们使用Redis和MySQL存储数据,它们的数字还挺大的:

  • Redis
  1. 1.5万次撞击/秒
  2. 1.6亿个键
  • MySQL:
  1. 多于400 GB的数据
  2. 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');
}



酷毙

雷人

鲜花

鸡蛋

漂亮
  • 快毕业了,没工作经验,
    找份工作好难啊?
    赶紧去人才芯片公司磨练吧!!

最新评论

关于LUPA|人才芯片工程|人才招聘|LUPA认证|LUPA教育|LUPA开源社区 ( 浙B2-20090187 浙公网安备 33010602006705号   

返回顶部