聚合PHP中的数据集以获得最大性能


Aggregating data sets in PHP for maximum performance

我们有一个高交易量的PHP网站,总体表现良好,但薄弱环节是搜索结果缓慢。原因是我们汇总了来自多个来源的数据。例如:

用户点击搜索>从本机数据库获取结果1>从API 2获取结果2>从API 3获取结果3>从API 4获取结果4>聚合和排序>输出到浏览器。

数据来自各种来源,有些来自我们自己的PostgreSQL数据库,但其余来自各种外部API。

正如您所看到的,这种顺序访问是一个真正的杀手。我一直在研究使用线程的各种方法,这样我就可以将每个请求分配给它自己的线程,并执行最终聚合。

到目前为止,我倾向于编写一个专门用于搜索的基于Java的层。我的想法是向Java服务发送一条消息,它处理线程池和聚合。我曾想过使用node.js,但我认为可能很难实现最终结果。

有人有什么想法或建议吗?我愿意使用任何语言或技术。

即使您使所有子请求同时以异步模式运行,您的请求执行时间也不能小于API请求的最小执行时间。若您需要将聚合函数应用于所有API和DB数据,那个么这是正确的。但如果您不需要它,请尝试将请求分成小部分。您也可以尝试使用像Gearman这样的任务队列。

已编辑您也可以在此处考虑任何类型的异步调用。尝试在Gearman中为每个api调用异步启动任务,然后在主请求过程中从您的数据库中获取数据,并开始检查异步任务执行结果(您可以在memcache或redis中共享,即)。这样您就可以并行化聚合工作的一部分。

这只是一个尚未提及的替代选项。

您可以坚持使用纯php——只需编写4个新进程,这些进程作为侦听本地套接字连接的守护进程运行。您的搜索脚本可以与每个守护进程建立套接字连接,并将搜索参数发送给它们,然后等待结果。您可以使用select()有效地等待套接字上的结果,但即使是在所有4个套接字上按顺序使用阻塞fgets()调用的天真解决方案,只要您在尝试读取任何一个套接字的结果之前将消息发送到所有4个守护进程,也会给您带来良好的并发性。

但是,当10个不同的用户同时执行搜索时,这并不能自动提供良好的并发性。守护进程可能能够同时有效地为多个套接字连接提供服务。对于本机数据库查询,您的驱动程序需要支持异步查询。这些api调用可能使用sockets/http。sockets/http请求很容易通过使用select()进行并行化,或者可以考虑使用curl_multi

但是。。。使用好的语言支持的线程最终可能会更简单。