使用大量线程优化PHP算法?

使用大量线程优化PHP算法?,php,multithreading,algorithm,laravel,curl-multi,Php,Multithreading,Algorithm,Laravel,Curl Multi,作为基于Laravel的应用程序的一部分,我正在尝试编写一个PHP脚本,用于获取特定数据,即不断更新的,确切地说,是关于特定产品和书籍的 问题是: 书籍由ISBN标识,ISBN是一个10位的标识符。前9位数字可以是0-9,而最后一位数字可以是0-9或X。但是,最后一位数字是根据前9位数字计算的校验位,因此最后一位实际上只有一个可能的数字 在这种情况下,我们得出: 10*10*10*10*10*10*10*10*10*1 = 1,000,000,000 数字校正ISBN。如果我把搜索范围限制在英

作为基于Laravel的应用程序的一部分,我正在尝试编写一个PHP脚本,用于获取特定数据,即不断更新的,确切地说,是关于特定产品和书籍的

问题是: 书籍由ISBN标识,ISBN是一个10位的标识符。前9位数字可以是0-9,而最后一位数字可以是0-9或X。但是,最后一位数字是根据前9位数字计算的校验位,因此最后一位实际上只有一个可能的数字

在这种情况下,我们得出:

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) 你会注意到的第一件事是,虽然有20000000个可能的ISBN,但没有一个地方比实际存在的ISBN更接近,这意味着该算法的大部分将花费时间在错误的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) 992DigitalOcean服务器上运行的线程数是否合理?
2) 由于每个http请求完全独立于其他请求,是否有更有效的方法异步执行此算法?在等待所有http请求返回时,让CPU保持忙碌的最佳方法是什么?

3) 是否有一个特定的服务可以帮助我实现我的目标?保持ISBN数据库并继续爬网以保持更新,类似于谷歌的所有网页

分析ISBN生成逻辑,尽量避免获取不可能的ISBN

在爬网级别,不仅可以在不同的线程中进行拆分,还可以由多个服务器进行拆分,每个服务器都可以访问DB服务器,该服务器专用于DB,不会因爬网而产生开销

此外,如果可以提高性能,您还可以使用某种web缓存,例如google缓存或web archive

3秒对于一个web服务来说是很重要的,你确定没有一个服务能在更短的时间内回答你吗?也许是找吧


如果您设法列出某个日期内所有已出版的书籍,您可以尝试从该日期开始只抓取新书,只需查找其中的某些来源,此刷新将比搜索任何书籍都要快

好问题。。。但可能被问到了错误的地方。我建议您与DigitalOcean联系并听取他们的意见!是否无法一次请求多个isbn?解决方案1中提到的数据库中有多少isbn?即使这个数字是所有可能的ISBN置换的50%,根据您的估计,解决方案1仍然需要28.5年。除非Ryan Vincent提到的启发式方法大大减少了搜索空间,否则解决方案2似乎是您的最佳选择。@RyanVincent根据维基百科ISBN不是随机生成的,它有一定的逻辑。这就是为什么我能够假设所有英文书的第一个数字都是0或1。问题是ISBN的其他部分不容易理解,甚至可能包含可变的位数。例如,ISBN的一部分是出版商代码,维基百科说,你可以花几千美元购买一份包含900000个有效出版商代码的当前列表。。。你知道为什么这不那么容易。@Svea我同意解决方案2似乎是最好的选择。我的问题是,如何实现这一目标?我应该使用线程吗?大量的过程?有别的方法吗?