所以我有一些代码试图在HDFS上找到一个资源......如果它不在那里它会计算该文件的内容,然后写它。下次访问时,阅读器可以查看文件。这是为了防止昂贵的重新计算某些功能
但是......我在同一个集群上的不同机器上同时运行多个进程。我怀疑他们正在尝试访问相同的资源而且我遇到了一个竞争条件导致了很多错误我无法打开文件或文件存在但无法读取。
希望这个时间表能够证明我认为我的问题是什么
显然,我希望进程B等待进程A完成资源X,并在A完成时简单地读取它。
出现了类似信号量的信息,但我不知道如何在不同的python进程中使用这些信息来查看相同的HDFS位置。任何帮助将不胜感激
UPDATE:要清除..进程A和进程B将最终计算完全相同的输出(即相同的文件名,具有相同的内容,到同一位置)。理想情况下,B不应该计算它。 B将等待A计算它,然后在A完成后读取输出。从本质上讲,整个过程就像使用HDFS的“长期缓存”一样。给定函数将具有输出签名的位置。任何想要输出函数的进程都将首先确定输出签名(这基本上是一些函数参数,输入等的散列)。然后它将检查HDFS以查看它是否存在。如果不是......它会写入计算并将其写入HDFS,以便其他进程也可以读取它。
答案 0 :(得分:2)
(撇开它听起来像HDFS可能不是你的用例的正确解决方案,我会假设你不能切换到别的东西。如果可以的话,看看Redis,或memcached。)< / p>
似乎这就是你应该有一个服务负责计算/缓存这些结果的东西。这样,您的所有进程都必须要求创建资源(如果尚未创建)。如果尚未计算,则服务将计算它;一旦计算完(或者已经计算过),要么资源可用,或者甚至只是资源本身,都会返回到您的流程。
如果由于某种原因你不能这样做,你可以尝试使用HDFS进行同步。例如,您可以尝试使用sentinel值创建资源,其中进程A的信号当前正在构建此文件。同时,进程A可以计算该值并将其写入临时资源;一旦完成,它可以将临时资源移动到标记资源上。它很笨拙和hackish,你应该尽量避免它,但这是一个选择。
你说你想避免昂贵的重新计算,但是如果进程B正在等待进程A来计算资源,那么为什么不能处理B(以及C和D)为自己/他们自己计算它?如果这对您没问题,那么在资源尚不存在的情况下,您可以让每个进程开始计算并写入临时文件,然后将文件移动到资源位置。希望移动是原子的,所以其中一个会干净利落;如果它们完全相同则无关紧要。一旦它在那里,它将来可用。这确实涉及多个进程同时向HDFS集群发送相同数据的可能性,因此它不是最有效的,但它有多糟糕取决于您的用例。您可以通过以下方式减少效率,例如,在计算之后和上传到HDFS之前检查是否有其他人在您上次查看后创建了资源;如果是这样,甚至不需要创建临时资源。
TLDR:你可以用HDFS做到这一点,但最好有一个为你管理它的服务,而且最好不要使用HDFS(尽管您仍然可能希望服务为您处理它,即使您使用的是Redis或memcached;它又取决于您的特定用例)。