Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/laravel/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 缓存结果列表的优化方法?_Php_Laravel_Caching_Optimization_Redis - Fatal编程技术网

Php 缓存结果列表的优化方法?

Php 缓存结果列表的优化方法?,php,laravel,caching,optimization,redis,Php,Laravel,Caching,Optimization,Redis,这是PHP/Laravel+Redis的一个问题,但我相信它可以推广到其他语言/框架 我正在开发一个显示结果的应用程序(来自用户发起的搜索或类别列表)。默认情况下,我们每页分页30个结果 我使用Redis缓存所有结果,但在优化时遇到了几个问题。首先,我缓存了整个结果集,其中对象(产品)完全存储在结果集中(因此基本上每个结果列表都是一个包含30个数据对象的巨大缓存条目)。这很好,但是由于对象存储在多个不同的缓存对象中(一个产品可以出现在多个搜索结果和类别中,然后默认情况下每个对象都会被单独缓存),

这是PHP/Laravel+Redis的一个问题,但我相信它可以推广到其他语言/框架

我正在开发一个显示结果的应用程序(来自用户发起的搜索或类别列表)。默认情况下,我们每页分页30个结果

我使用Redis缓存所有结果,但在优化时遇到了几个问题。首先,我缓存了整个结果集,其中对象(产品)完全存储在结果集中(因此基本上每个结果列表都是一个包含30个数据对象的巨大缓存条目)。这很好,但是由于对象存储在多个不同的缓存对象中(一个产品可以出现在多个搜索结果和类别中,然后默认情况下每个对象都会被单独缓存),内存使用会急剧增加

另外,另一个问题是,由于我们允许在不同计数时进行不同的分页,因此我们也必须在其他对象计数时进行缓存

所以我接下来尝试的是缓存每个页面的对象ID列表。这大大减少了内存使用,但是每次加载一个页面时,我们都必须遍历30个对象,从缓存中检索它们,然后重新创建它们。在每个对象大约50毫秒的情况下(这似乎很高),页面加载时间最多可增加1.5秒。即使我们进一步优化对象创建,添加到页面加载/呈现中的时间仍然是一个具体的时间量

我们的下一次尝试是HTML缓存(Cloudflare/Varnish等),这将要求我们重新设计应用程序的某些方面,这很好。然而,对我来说,我想知道没有HTML缓存的情况下,他们是如何对此进行优化的(或者说,做我们正在尝试做的事情的最佳方法是什么?)。另外,我遇到的另一个问题是,虽然我知道每次请求都会执行PHP脚本,但为什么我们不能将执行之间的对象维护为POPO(普通的旧PHP对象)?在这一点上,我觉得很傻,2017年我们仍然在序列化和反序列化对象。我希望有一个后台PHP应用程序来维护所需的对象,并能够根据需要将它们传递给每个脚本

例如,一个产品在页面加载和页面加载之间变化不大。为什么一分钟要重新创建数百次相同的产品对象?即使它来自缓存

我希望有一个后台PHP应用程序来维护所需的对象,并能够根据需要将它们传递给每个脚本

您不能这样做,因为单独的应用程序不共享作用域(它们甚至不共享内存)。因此,您的后台应用程序需要以某种中间形式传递对象。是的,你猜对了。序列化

您可以做的是分离一些服务或HTML生成的部分,以便它们仅与特定对象完全关联。此时,您可能会有一个运行对象代理的后台应用程序。通过使用对象ID调用代理并请求其HTML来呈现对象,代理可以缓存对象或呈现的HTML,具体取决于最佳的缓存方式

HTML不需要序列化,这种方法应该非常有效

您甚至可以通过AJAX实现这一点:对象被“预渲染”为具有适当大小和“请稍候”动画的AJAX占位符

<div class="Placeholder Product"></div>

然后,一系列并行jQuery调用为对象设置动画


我这样做了(为了一个分页的东西,go figure),并通过一个疯狂的动画获得了非常好的结果,该动画一开始是一个非常不集中的搜索结果,逐渐成为焦点(当然没有循环)。这种情况发生得非常缓慢,同时AJAX调用得到了解决,真正的对象被融入其中。这些对象非常相似,以至于你很少发现未聚焦的图像和最终的对象实际上没有关联,用户平均没有注意到前两个或前三个对象还没有渲染-他看到整个结果页面立即出现,并认为所有结果都在那里。对象也在本地缓存,因此来回分页不会对服务器造成多次压力。

愚蠢的问题提醒,但在您的第二次尝试中,为什么要在对象之间循环,而不是一次获取所有对象?从你的描述听起来,这会节省你很多时间。另一个值得一提的解决方案是将数据转换为您实际需要的数据,并仅将其存储在缓存中,而不是存储在整个对象中。你可以很容易地做到这一点,例如分形。