草庐IT

php - 缓存结果列表的优化方式?

coder 2023-11-08 原文

这是一个针对 PHP/Laravel + Redis 的问题,但我确信它可以外推到其他语言/框架。

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

我使用 Redis 来缓存所有结果,但我遇到了一些优化问题。起初,我缓存了整个结果集,对象(产品)完全存储在结果集中(因此基本上每个结果列表都是一个包含 30 个数据对象的巨大缓存条目)。这很好,但是随着对象存储在多个不同的缓存对象中,内存使用量激增(一个产品可能出现在多个搜索结果和类别中——然后默认情况下每个对象都会被单独缓存)。

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

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

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

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

最佳答案

I'd love to have a background PHP app that maintains the objects required and is able to pass them to each script as required.

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

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

不需要序列化的HTML,这个方法应该很高效。

您甚至可以通过 AJAX 执行此操作:将对象“预呈现”为具有适当大小的 AJAX 占位符和“请稍候”动画

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

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

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

关于php - 缓存结果列表的优化方式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42284929/

有关php - 缓存结果列表的优化方式?的更多相关文章

  1. ruby - 如何以所有可能的方式将字符串拆分为长度最多为 3 的连续子字符串? - 2

    我试图获取一个长度在1到10之间的字符串,并输出将字符串分解为大小为1、2或3的连续子字符串的所有可能方式。例如:输入:123456将整数分割成单个字符,然后继续查找组合。该代码将返回以下所有数组。[1,2,3,4,5,6][12,3,4,5,6][1,23,4,5,6][1,2,34,5,6][1,2,3,45,6][1,2,3,4,56][12,34,5,6][12,3,45,6][12,3,4,56][1,23,45,6][1,2,34,56][1,23,4,56][12,34,56][123,4,5,6][1,234,5,6][1,2,345,6][1,2,3,456][123

  2. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  3. ruby - RVM 使用列表[0] - 2

    是否有类似“RVMuse1”或“RVMuselist[0]”之类的内容而不是键入整个版本号。在任何时候,我们都会看到一个可能包含5个或更多ruby的列表,我们可以轻松地键入一个数字而不是X.X.X。这也有助于rvmgemset。 最佳答案 这在RVM2.0中是可能的=>https://docs.google.com/document/d/1xW9GeEpLOWPcddDg_hOPvK4oeLxJmU3Q5FiCNT7nTAc/edit?usp=sharing-知道链接的任何人都可以发表评论

  4. ruby - 如何在 Ubuntu 中清除 Ruby Phusion Passenger 的缓存? - 2

    我试过重新启动apache,缓存的页面仍然出现,所以一定有一个文件夹在某个地方。我没有“公共(public)/缓存”,那么我还应该查看哪些其他地方?是否有一个URL标志也可以触发此效果? 最佳答案 您需要触摸一个文件才能清除phusion,例如:touch/webapps/mycook/tmp/restart.txt参见docs 关于ruby-如何在Ubuntu中清除RubyPhusionPassenger的缓存?,我们在StackOverflow上找到一个类似的问题:

  5. ruby-on-rails - 正确的 Rails 2.1 做事方式 - 2

    question的一些答案关于redirect_to让我想到了其他一些问题。基本上,我正在使用Rails2.1编写博客应用程序。我一直在尝试自己完成大部分工作(因为我对Rails有所了解),但在需要时会引用Internet上的教程和引用资料。我设法让一个简单的博客正常运行,然后我尝试添加评论。靠我自己,我设法让它进入了可以从script/console添加评论的阶段,但我无法让表单正常工作。我遵循的其中一个教程建议在帖子Controller中创建一个“评论”操作,以添加评论。我的问题是:这是“标准”方式吗?我的另一个问题的答案之一似乎暗示应该有一个CommentsController参

  6. ruby-on-rails - Ruby on Rails 计数器缓存错误 - 2

    尝试在我的RoR应用程序中实现计数器缓存列时出现错误Unknownkey(s):counter_cache。我在这个问题中实现了模型关联:Modelassociationquestion这是我的迁移:classAddVideoVotesCountToVideos0Video.reset_column_informationVideo.find(:all).eachdo|p|p.update_attributes:videos_votes_count,p.video_votes.lengthendenddefself.downremove_column:videos,:video_vot

  7. 报告回顾丨模型进化狂飙,DetectGPT能否识别最新模型生成结果? - 2

    导读语言模型给我们的生产生活带来了极大便利,但同时不少人也利用他们从事作弊工作。如何规避这些难辨真伪的文字所产生的负面影响也成为一大难题。在3月9日智源Live第33期活动「DetectGPT:判断文本是否为机器生成的工具」中,主讲人Eric为我们讲解了DetectGPT工作背后的思路——一种基于概率曲率检测的用于检测模型生成文本的工具,它可以帮助我们更好地分辨文章的来源和可信度,对保护信息真实、防止欺诈等方面具有重要意义。本次报告主要围绕其功能,实现和效果等展开。(文末点击“阅读原文”,查看活动回放。)Ericmitchell斯坦福大学计算机系四年级博士生,由ChelseaFinn和Chri

  8. 【鸿蒙应用开发系列】- 获取系统设备信息以及版本API兼容调用方式 - 2

    在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList​()Obt

  9. ruby - 鸭子输入字符串、符号和数组的优雅方式? - 2

    这是针对我无法破坏的现有公共(public)API,但我确实希望对其进行扩展。目前,该方法采用字符串或符号或任何其他在作为第一个参数传递给send时有意义的内容我想添加发送字符串、符号等列表的功能。我可以只使用is_a吗?数组,但还有其他发送列表的方法,这不是很像ruby​​。我将调用列表中的map,所以第一个倾向是使用respond_to?:map。但是字符串也会响应:map,所以这行不通。 最佳答案 如何将它们全部视为数组?String的行为与仅包含String的Array相同:deffoo(obj,arg)[*arg].eac

  10. Ruby on Rails regexp equals-tilde 与 array include 用于检查选项列表 - 2

    我正在使用Rails3.2.3和Ruby1.9.3p0。我发现我经常需要确定某个字符串是否出现在选项列表中。看来我可以使用Ruby数组.includemethod:或正则表达式equals-tildematchshorthand用竖线分隔选项:就性能而言,一个比另一个好吗?还有更好的方法吗? 最佳答案 总结:Array#include?包含String元素,在接受和拒绝输入时均胜出,对于您的示例只有三个可接受的值。对于要检查的更大的集合,看起来Set#include?和String元素可能会获胜。如何测试我们应该根据经验对此进行测试

随机推荐