【问题标题】:Tweaking magento for performance调整 magento 以提高性能
【发布时间】:2012-02-09 18:38:26
【问题描述】:

我正在查看 magento 站点的性能(服务器加载时间),并且正在尝试调整搜索结果页面。我意识到,当我禁用所有繁重的东西,如顶部导航、lev 分层导航和产品列表并清除所有缓存后,这个 magento 核心确实对数据库执行了 60 个 SQL 查询。有没有人有任何程序如何摆脱它们或如何将它们减少到可接受的数量?

我还能以某种方式减少创建块的时间吗?

非常感谢, 加罗。

【问题讨论】:

  • 缓存不是办法,我需要优化代码本身,然后我们才能缓存昂贵部分的代码
  • 然后继续并重新编程:) 但我将从缓存@第 1 天开始,我启动了一个基于 Magento 的网站
  • 也许有办法重做这部分。我认为大量的 magento 站点必须处理此类问题,并且具有超快速空操作是当务之急。我不知道缓存在页面渲染的这个阶段有多少帮助。我看不出空操作会产生 60 个查询的原因。
  • 关于缓存,关于 redis (redis.io) 缓存后端和会话存储的真正有用用法,对于 github 中可用的两个现有模块,它们都可以完美运行,请参阅 github.com/colinmollenhour/Cm_Cache_Backend_Redisgithub.com/colinmollenhour/Cm_RedisSession 它还有更多比 memcache 存储更好。

标签: performance magento


【解决方案1】:

Magento 是一个极其灵活的电子商务框架,但这种灵活性是有代价的:性能。这个答案是指针的集合和一些关于缓存的细节(特别是对于块)。

要考虑的一件事是 Magento 环境,例如调整 php、web 服务器(更喜欢 nginx 而不是 Apache)和 MySQL。另外,为 Magento 设置一个好的缓存后端。所有这些都包括在内,例如在同样适用于 CE 的Magento Performance Whitepaper 中。

环境搭建好之后,另一面就是代码了。
通过启用平面表目录(系统 > 配置 > 目录 > 前端)可以减少某些页面的查询数量,但您将始终有大量查询。

除了调整环境(APC、内存、CPU)之外,您也无法真正减少创建块所花费的时间。因此,正如其他评论者所说,您最好的选择是利用 Magento 内置的缓存功能。

Magento 块缓存

因为您在问题中特别提到了块,所以我将详细说明块缓存。块缓存受三个属性控制:

  1. cache_lifetime
  2. cache_key
  3. 缓存标签

所有这些属性都可以在块的_construct() 方法中使用 setData() 或魔法设置器设置,或者通过实现相关的 getter 方法(getCacheLifetime()getCacheKey()getCacheTags())来设置。

cache_lifetime 以(整数)秒为单位。如果将其设置为false(boolean),则该块将被永久缓存(不会过期)。如果设置为null,则不会缓存块(这是Mage_Core_Block_Abstract中的默认值)。

cache_key 是用于标识缓存池中的缓存记录的唯一字符串。默认情况下,它由getCacheKeyInfo() 方法返回的数组构成。

// Mage_Core_Block_Abstract
public function getCacheKeyInfo()
{
    return array(
        $this->getNameInLayout()
    );
}

public function getCacheKey()
{
    if ($this->hasData('cache_key')) {
        return $this->getData('cache_key');
    }
    /**
     * don't prevent recalculation by saving generated cache key
     * because of ability to render single block instance with different data
     */
    $key = $this->getCacheKeyInfo();
    //ksort($key);  // ignore order
    $key = array_values($key);  // ignore array keys
    $key = implode('|', $key);
    $key = sha1($key);
    return $key;
}

在自定义块中自定义缓存键的最佳方式是覆盖getCacheKeyInfo()方法,并根据需要添加唯一标识缓存块所需的数据。

例如,为了根据客户组缓存不同版本的块,您可以执行以下操作:

public function getCacheKeyInfo()
{
    $info = parent::getCacheKeyInfo();
    $info[] = Mage::getSingleton('customer/session')->getCustomerGroupId()
    return $info;
}

cache_tags 是一个启用缓存分段的数组。您只能删除与一个或多个标签匹配的缓存部分。
System > Cache Management 下的管理界面中,您可以看到几个可用的默认缓存标记(例如 BLOCK_HTML、CONFIG、...)。您也可以使用自定义缓存标签,只需指定它们即可。
这是Zend_Cache 实现的一部分,与cache_lifetimecache_key 相比,需要定制的频率要低得多。

其他缓存

除了块 Magento 缓存了许多其他的东西(收集数据,配置,...)。
您可以使用Mage::app()->saveCache()Mage::app()->loadCache()Mage::app()->cleanCache()Mage::app()->removeCache() 缓存您自己的数据。有关这些方法的详细信息,请查看Mage_Core_Model_App,它们相当简单。

您还需要使用整页缓存模块。如果您使用的是 Magento EE,那么您已经拥有一个。否则搜索 Magento Connect - 有很多选项(商业)。
除了整页缓存方面,其中一些模块还为您调整 Magento 的各个部分,例如Nitrogento(商业)。

使用像Varnish 这样的反向代理也是非常有益的。

有很多关于这个主题的博客文章。这是 Nitrogento 扩展的出版商的one post
如果您在更小规模的环境中运行 Magento,请查看我在 magebase.com 上the optimization of the file cache backend 上的帖子。

【讨论】:

  • 提醒您有大量时间和知识来解释这一切
  • 如果产品数据每 5 分钟更新一次,块缓存将无济于事。我们需要尽可能多地展示新鲜的内容。在这种情况下,SQL 查询的数量非常重要。所以我试图找出一种方法如何将它们减少到最低限度。假设类别或搜索结果页面上的 20-30 个查询是我的目标。
  • 如果您使用 Magento,您将不得不借助巧妙的缓存失效或自定义目录实现来进行缓存。默认的 Mage_Catalog 模块更注重灵活性而不是性能。
【解决方案2】:

这个帖子很旧但非常有用。 我正在添加额外的 cmets 以提高速度:

  1. 不要使用 Apache,而是使用 nginx 或 litespeed。
  2. 确保使用平面目录。
  3. 如果可能,请使用 FPC。
  4. 要设置的编译器模式。
  5. 合并css和js(Fooman Speedster)。
  6. 使用图像精灵来减少请求数量。
  7. 使用查询缓存但避免大小超过 64 MB。
  8. 通过删除 xml 来删除所有未使用的模块。只是禁用是不行的。
  9. 会话在 Ram 上。
  10. 建议使用 APC。
  11. 您的 cron 应该在非高峰时间运行。
  12. 如果不使用,请删除其他商店。
  13. 如果不使用,请删除购物车规则。
  14. 针对大小优化图片。
  15. 尽可能使用 Ajax。
  16. CMS 块比 magento 块花费更多时间,因此除非您想要修改块,否则不要使用 CMS 块。
  17. 不要使用集合计数,使用集合 getSize 来获取集合大小。
  18. 尽量减少可搜索属性的数量,因为这些会导致平面目录表中的列,并会减慢您的搜索速度。
  19. 建议使用 Solr 搜索。它带有 EE 版本,但它也可以与 CE 一起安装。
  20. 按照评论中的建议最小化客户群。
  21. 在 .htaccess 中启用压缩(对于 Apache 1.3 是 mod_gzip,对于 Apache 2 是 mod_deflate)
  22. 如果在 EE 上,则删除临时存储。
  23. 使用 Apache mod_expires 并确保设置文件应缓存多长时间。如果您在 Apache 服务器上。
  24. 使用内容交付网络 (CDN)。
  25. 启用 Apache KeepAlives。
  26. 使您的输出符合 W3C 标准
  27. 建议使用 getChildHtml('childName'),因为这将缓存块以防止在 .phtml 文件中直接使用块代码。
  28. 确保运行 cron 以便清理存储在数据库中的日志。
  29. 应根据要求将日志天数减至最少。
  30. 如果内存允许,将缓存加载到 RAM 中。
  31. 减少硬盘文件读取并尝试从 ram 读取,因为这样更快。
  32. 将PHP版本升级到5.3以上
  33. 如果在 EE 上确保大多数页面在没有应用程序初始化的情况下交付。即使一个容器需要应用程序初始化,它也会影响执行速度,因为除了表单 URL 重写之外,大多数其他代码都会被执行。
  34. 检查 XML 中放置在默认句柄中的块,如果这些块不在特定页面上,则将这些 XML 值从默认句柄移动到特定句柄。据观察,执行了许多未显示的块。
  35. 如果使用 FPC,请确保您的容器已缓存,并通过缓存传递对容器的重复请求。不正确的占位符定义会导致不使用容器缓存,但每次都会生成新的容器内容。
  36. 分析页面块和变量,如果可能,将这些变量/块添加到缓存中。
  37. 关闭在 Magento 中写入的日志。
  38. 删除管理员通知模块。
  39. 图像精灵的使用。
  40. 使用一些网络测试工具来分析请求数和其他负责下载时间的 html 相关参数并采取相应措施。
  41. 如果不需要,删除属性。如果不使用,我们甚至可以删除系统属性。 42:如果在企业中,请确保有效使用部分索引。
  42. 编写您自己的 solr 搜索填充以绕过 Magento 搜索索引。
  43. 清理 _cl 表或减少 _cl 表行。
  44. 我会添加到列表中:尽可能避免文件缓存,将其替换为 apc / redis / memcache(如 Jaro 所建议)
  45. 删除未使用的系统属性(小心,删除前彻底检查)。
  46. 有些 cron 选项卡作业并不适用于所有商店,因此可以根据您的商店功能删除这些作业。
  47. 通过适当的属性管理进行优化,例如将所需属性设置为“是”或可搜索或列表中的必需属性等。
  48. 并非所有商店都需要某些观察者,因此如果这些观察者不适用于特定的 Magento 站点,则应将其删除。
  49. 确保 FPC 适用于大多数网站页面。特别是当您添加一些新控制器来交付页面时。
  50. Magento 有很多功能。为此,它有很多事件和相关的观察者。商店不使用的功能很少,因此应删除与该功能相关的任何观察者。例如:如果您检查企业版,则有类别权限概念,如果不使用,则建议在保存事件后删除与权限相关的观察者。
  51. 如果要为产品保存特定属性,则不要调用 $product->save,而是调用将保存特定属性的函数。
  52. 在具有部分索引和触发器的 EE 版本中,修改触发器以避免多个条目 to_cl 表。
  53. No.phtml 文件绕过块并直接使用模块或资源。因为这将导致没有缓存,这反过来意味着 Magento 需要做更多的工作。
  54. 根据使用的设备传送图像。
  55. 为社区推荐的一些 FPC:Lesti(截至日期免费)、Amasty(商业)、extender(商业)和 Bolt(商业)。
  56. 预热缓存。
  57. 在高峰时段通过 .htaccess 控制机器人。
  58. 通过每天由 cron 执行的自定义脚本在自定义表格中为分层导航预填充值。
  59. 确保避免使用不需要的密钥以减少缓存大小。
  60. 使用更高版本的 PHP 5.4+
  61. 使用更高版本的Mysql(5.5+)
  62. 减少 Dom 元素的数量。
  63. 将所有 js 从 html 页面中移出。
  64. 删除评论的 html。
  65. 在企业版(1.13 或更高版本)上修改触发器以减少 _cl 表条目。由于这些条目会导致缓存刷新,进而导致缓存命中率降低,因此 TTFB 时间更长。
  66. 使用 Magmi 导入产品。
  67. 一些重要的链接: --http://www.oscprofessionals.com/blog/understanding-full-page-cache-concept-magento/ 和 --http://dionbeetson.blogspot.com.au/2014/11/magento-performance-tips-for-scalability.html

【讨论】:

  • 我会添加“最小化客户群数量”,当您拥有大量产品时,这一点非常重要。
  • 我会添加到列表中:尽量避免文件缓存,用 apc / redis / memcache 替换它
  • 关于 Jaros 的建议会说 Redis 是最稳定的选择
  • 迁移到 Magento 2.3.x 应该是提高速度的最重要的活动。有了这个和正确的 JS 处理,如果需要使用 AMP 和 CDN,一个人可以获得 90 分以上的分数和网页将保证在不到 1.5 秒内加载。如果一切正常且托管环境支持。
【解决方案3】:

正如 Vinai 所说,Magento 完全是关于可扩展性,原始性能是次要的,但可以通过索引和缓存等东西来弥补。在没有缓存的情况下显着提高性能将非常困难。缺少整页缓存,启用块缓存是提高性能的好方法,但适当的缓存失效是关键。许多块是可缓存的,但尚未配置为默认缓存,因此使用分析使用 Vinai 的启用缓存指南来识别最慢的块。以下是有关块缓存的一些额外注意事项:

  • 任何列出产品信息的块都应该有产品标签'catalog_product_'.$productId。同样,将'catalog_category_'.$categoryId 用于类别。这将确保在保存产品或类别时缓存无效(在后端编辑)。不要在构造函数中设置它们,将它们设置在覆盖的 getCacheTags() 中,以便它们仅在保存块时收集,而不是在从缓存加载时收集(因为这会破坏缓存它的目的)。李>
  • 如果您使用 https 并且该块可以出现在 https 页面上并包含静态资源,请确保缓存键包含 Mage::app()->getRequest()->isSecure() 否则您最终会在 https 页面上使用 http url,反之亦然。
  • 确保您的缓存后端有足够的容量并避免不必要的缓存刷新。
  • 不要缓存本身已缓存的块的子块,除非父块的更改比子块更频繁,否则您只会弄乱您的缓存后端。
  • 如果您正确执行缓存标记,您应该能够安全地使用非常长的默认缓存生命周期。我相信将“false”设置为生命周期实际上使用默认值,而不是无限。默认为 7200 秒,但可以在 local.xml 中配置。
  • 在大多数情况下使用redis backend 将为您提供最佳和最一致的性能。使用 Redis 时,您可以使用 munin plugin 监控已使用的内存大小。

【讨论】:

  • 感谢您提供有关 redis 后端的提示。我不知道它似乎更好地替代了 memcached 后端,因为它会执行 memcached 不支持的密钥失效。
  • 其他可能导致密钥失效的问题是您在流量高峰期间保存类别/产品时。它可能会导致糟糕的用户体验,或者在最坏的情况下导致网站不可用。为了避免这种情况,您需要更强大的服务器,这是非常必要的。如何摆脱这种情况的方法是刷新缓存键而不是失效,但这确实具有挑战性:-) 有没有人分享任何想法/想法/解决方案?
  • 我尝试了 Redis,它非常完美。谢谢
【解决方案4】:

从 Mark 开始…… Magento 数据库中的大多数表都是 InnoDB。虽然查询缓存可以在一些特定的地方使用,但以下更直接相关...

innodb_buffer_pool_size
innodb_thread_concurrency
innodb_flush_method
innodb_flush_log_at_trx_commit

我也用过

innodb_file_per_table

因为这有助于重新组织特定的表格。

如果您为数据库提供足够的资源,(在合理范围内)流量实际上根本不会加载服务器,因为大多数查询无论如何都是重复的,并且从数据库缓存中传递出来。

换句话说,你可能什么都不担心......

【讨论】:

  • 更新 innodb_thread_concurrency 时,您还应该增加 innodb_concurrency_tickets。这默认为 500。使用执行许多 count() sum() av​​g() 查询的 magento 设置,这太低了。我们将其设置为 10.000.000。尽管这会将查询锁定到线程以进行 10M 行读取,但它会阻止许多上下文切换
【解决方案5】:

确保 mysql 查询缓存已打开。并在 mysql 中设置这些变量(可能需要根据您的设置进行调整)。

query_cache_type=1
query_cache_size=64M

【讨论】:

    【解决方案6】:

    我发现了一篇关于 Magento 性能优化的非常有趣的博客文章,其中有许多针对您的服务器和您的 magento 商店的配置设置,对我很有帮助。

    http://www.mgt-commerce.com/blog/magento-on-steroids-best-practice-for-highest-performance/

    【讨论】:

    • 欢迎来到 Stack Overflow,约翰!感谢您发布您的答案!请务必仔细阅读FAQ on Self-Promotion。另请注意,每次链接到自己的网站/产品时都需要发布免责声明。
    【解决方案7】:

    首先,您需要审核和优化首字节时间 (TTFB)。

    Magento 内置分析器,可帮助您识别未优化的代码块。

    检查您的模板文件并确保您没有在循环中加载产品模型(常见的性能消耗):

    foreach($collection as $_product){
       $_product = Mage::getModel('catalog/product')->load($_product->getId()
    

    我经常在 product/list.phtml 中看到这段代码

    我在how to optimize TTFB上写了一篇分步文章

    免责声明:链接指向我自己的网站

    【讨论】:

      猜你喜欢
      • 2023-02-26
      • 2012-10-17
      • 1970-01-01
      • 2015-09-16
      • 2017-02-28
      • 2014-07-01
      • 1970-01-01
      • 2015-02-26
      • 2013-09-21
      相关资源
      最近更新 更多