【发布时间】:2017-07-06 05:05:46
【问题描述】:
这是 PHP/Laravel + Redis 的问题,但我确信它可以外推到其他语言/框架。
我正在开发一个显示结果的应用程序(来自用户发起的搜索或类别列表)。默认情况下,我们每页分页 30 个结果。
我使用 Redis 来缓存所有结果,但我遇到了一些优化问题。起初,我使用完全存储在结果集中的对象(产品)来缓存整个结果集(所以基本上每个结果列表都是一个包含 30 个数据对象的巨大缓存条目)。这很好,但是随着对象存储在多个不同的缓存对象中(一个产品可能出现在多个搜索结果和类别中——然后每个对象默认单独缓存),内存使用量激增。
另外,另一个问题是,由于我们允许以不同的计数进行不同的分页,因此我们也必须在其他对象计数时进行缓存。
那么我接下来尝试的只是缓存每个页面的对象 ID 列表。这显着减少了内存使用量,但是每次加载页面时,我们都必须遍历 30 个对象并从缓存中检索它们,然后重新创建它们。每个对象大约 50 毫秒(这似乎很高),它最多可以增加 1.5 秒来加载页面。即使我们进一步优化对象的创建,仍然会增加页面加载/渲染的具体时间。
我们的下一个尝试是 HTML 缓存(Cloudflare/Varnish 等),这将要求我们重新设计应用程序的某些方面,这很好。但是,对我来说,我想知道没有 HTML 缓存是他们优化这一点的方法(或者什么是我们正在尝试做的最佳方法?)。此外,我遇到的另一个问题是,虽然我知道 PHP 脚本在每个请求时都会执行,但为什么我们不能在执行之间将对象维护为 POPO(普通旧 PHP 对象)?在这一点上,我觉得在 2017 年我们仍在序列化和反序列化对象似乎很愚蠢。我希望有一个后台 PHP 应用程序来维护所需的对象并能够根据需要将它们传递给每个脚本。
例如,产品从页面加载到页面加载不会有太大变化。为什么每分钟重新创建数百次相同的 Product 对象——即使它来自缓存?
【问题讨论】:
-
愚蠢的问题警报,但是在您的第二次尝试中,您为什么要遍历对象而不是一次获取所有对象?从你的描述来看,这样可以为你节省很多时间。另一个值得一提的解决方案是将数据转换为您实际需要的数据,并将其仅存储在缓存中,而不是整个对象。您可以通过例如轻松实现这一目标分形。
标签: php laravel caching optimization redis