作为基于 Laravel 的应用程序的一部分,我正在尝试编写 PHP 脚本,该脚本从不断更新获取某些数据在网络上关于某些产品,准确的书籍。
书籍由ISBN(10位数字标识符)标识。前9位可以是0-9,而最后一位可以是0-9或X.但是,最后一位是校验位,它是根据前9位数计算的,因此实际上只有1位数最后一个地方。
在这种情况下,我们到达:
10*10*10*10*10*10*10*10*10*1 = 1,000,000,000
数字正确的ISBN。如果我将搜索限制在英语书籍中,我可以做得更好,因为它们只包含0或1作为第一个数字。因此,我会得到:
2*10*10*10*10*10*10*10*10*1 = 200,000,000
数字正确的ISBN。
现在,对于每个ISBN,我有3个 http 请求获取数据,每个请求大约需要3秒钟才能完成。因此:
3seconds*3requests*200,000,000ISBNs = 1,800,000,000 seconds
1,800,000,000seconds/60seconds/60minutes/24hours/365days = ~57 years
希望在57年的时间里,不再有书这样的东西了,这个算法就会过时了。
实际上,由于我所关注的数据不断变化,为了使这个算法有用,它必须在几天内完成每次通过(理想的是2-7天)。
因此问题是如何优化此算法以将其运行时间从57年缩短到仅一周?
1)你会注意到的第一件事是虽然有200,000,000个可能的ISBN,但是没有真正的ISBN存在的地方,这意味着多数这个算法< strong>花费时间在虚假ISBN上发出 http请求(我可以在第一次失败的http请求之后移动到下一个ISBN,但仅此一点不会显着降低时间)。因此,解决方案1 将获取/购买/下载已包含正在使用的ISBN列表的数据库,从而显着降低要搜索的ISBN数量。
我的问题 解决方案1 是新书不断发布,我希望在算法再次运行时能够获得新书。使用现有书籍的数据库只对最新创建数据库的书籍有用。 (一个潜在的解决方案是不断更新数据库的服务,让我每周下载一次,但这似乎不太可能,而且我真的希望通过编程来解决这个问题!)
2)虽然这个算法需要永远运行,但大部分时间它实际上只是坐着等待来获取 http响应。因此,一种选择似乎是使用主题。
如果我们进行数学运算,我认为这个等式看起来像这样:
(numISBNs/numThreads)*secondsPerISBN = totalSecondsToComplete
如果我们隔离numThreads:
numThreads = (numISBNs * secondsPerISBN) / totalSecondsToComplete
如果我们的门槛是一周,那么:
totalSecondsToComplete = 7days * 24hrs * 60min * 60sec = 604,800seconds
numISBNs = 200,000,000
secondsPerISBN = 3
numThreads = (200,000,000 * 3) / 604,800
numThreads = ~992
所以 992 线程必须同时运行才能生效。比如说 DigitalOcean 服务器上运行的线程是否合理?我的mac现在说它运行超过2000个线程,所以可能这个数字实际上是可管理的。
1) 992 在 DigitalOcean 服务器上运行合理数量的主题?
2)是否有更有效的异步执行此算法的方法,因为每个 http 请求完全独立于其他任何一个?在等待所有 http 请求返回时保持CPU忙的最佳方法是什么?
3)我是否应该为此寻找特定的服务,以帮助实现我的目标?
答案 0 :(得分:0)
保留数据库的ISBN并继续抓取以保持更新,类似于谷歌与所有网页
分析ISBN生成逻辑并尝试避免获取不可能的ISBN
在抓取级别,您不仅可以拆分各种线程,而且还可以通过多个服务器进行拆分,每个服务器都可以访问数据库服务器,专用于数据库而不会被爬行覆盖
如果它可以提高性能,你可以使用某种网络缓存,例如谷歌缓存或网络存档
对于Web服务来说,3秒钟很多,你确定没有服务可以在较短的时间内回复你吗?搜索它,也许
如果您设法在特定日期列出所有已发布的图书,您可以尝试仅抓取该日期的新图书,只查找其中一些来源,此次刷新将比搜索任何图书快得多