首页 文章

如何使用谷歌 Cloud 存储在多个谷歌 Cloud 实例之间同步数字?

提问于
浏览
0

我正在尝试在Google Cloud 中的多个实例之间同步操作 .

在我创建新实例的图像的主文件夹中,我有几个文件名如下: 1.txt2.txt3.txt ,... 50000.txt .

我在谷歌 Cloud 存储桶中有另一个名为 gs://bucket/current_file.txt 的文件,其中包含一行中的数字,表示所有正在运行的谷歌 Cloud 实例正在处理的最新文件 . 最初这个文件看起来像这样:

0

现在我逐个创建多个谷歌实例 . 这些实例有一个像这样的启动脚本:

gsutil cp gs://bucket/current_file.txt /home/ubuntu/;
past_file=`tail /home/ubuntu/current_file.txt`;
current_file=$((past_file+1));
echo $current_file > /home/ubuntu/current_file.txt;
gsutil cp /home/ubuntu/current_file.txt gs://bucket/;
process.py /home.ubuntu/$current_file.txt;

因此,此脚本会下载另一个实例正在处理的当前文件的值,然后将其递增1,并开始处理递增的文件 . 此外, gs://bucket/current_file.txt 也会更新,以便其他实例知道他们可以开始处理的下一个文件的名称 . 当我只运行一个实例时, gs://bucket/current_file.txt 会正确更新,但是当我运行多个实例时,有时 gs://bucket/current_file.txt 中的值会上升到一个值,然后不规律地会回落到一个减小的值 .

我的假设是两个不同的实例在某种程度上试图同时上传同一个文件并弄乱文本文件中的整数值 .

无论如何都可以锁定文件,以便其他实例在一个实例可以覆盖 gs://bucket/currrent_file.txt 之前等待?

如果没有,有人可以建议任何其他机制,通过该机制,我可以在一个实例处理current_file编号后更新current_file编号,然后可以将其传递给其他实例,以便他们可以在完成处理文件时开始处理以下文件手?

1 回答

  • 2

    你是对的 . 在您的体系结构中,您需要一些机制来锁定 current-file 计数器,以便一次只有一个进程能够更改其值 . 您希望能够将一个互斥锁或锁应用于该文件,当一个进程打开它以使其递增时,以便另一个进程无法同时递增它 .

    我建议你考虑其他方法 .

    即使您能够锁定计数器,您的“工作人员”也会阻止,等待他们应该能够继续处理文件时增加此变量 . 您还可以一次将处理限制为一个文件,这样您的进程一次可以更有效地获取批量文件 .

    您可以考虑各种方法 .

    如果您的文件集是预先确定的,即您总是有50k . 当你开始时,你可以决定你想要使用多少 Worker ,然后给他们每个人解决问题的一部分 . 如果您选择了1000个工作程序,则可以为第1个分配1.txt..50.txt,第2个51.txt..99.txt等 . 如果文件中存在间隙,则工作人员将跳过丢失的文件 .

    在更复杂的情况下,当文件在桶中随机创建并且正在进行时,通常的做法是对处理进行排队 . 看看Task QueuesCloud Pub/Sub . 在此方法中,您可以在文件到达时跟踪它们 . 对于每个文件,您将作业排入队列以进行处理 . 使用任务队列和发布/订阅,您可以创建推送或拉取队列 . 在任何一种方法中,您都可以编写一个工作程序来接受队列中的作业(文件),处理它们并对处理过的文件执行某些操作 . 与简单的情况相比,这种方法有两个优点:第一,您可以根据队列深度(要处理的文件数)动态增加工作量 . 第二个是,如果一个worker失败,它将不会从队列中取出该作业,因此另一个worker可以替换它并完成文件处理 .

    您可以将已处理的文件移动到“已处理”的存储桶以跟踪完成情况 . 这样,如果您的作业失败,则只需重新启动尚未处理的文件 .

    最后,不是逐个创建实例,而是使用Managed Instance Groups查看自动缩放,或者考虑使用Kubernetes . 这两种技术都可以帮助您从单个模板中克隆许多类似的流程 . 虽然这些解决方案都不能解决您的协调问题,但它们都可以帮助您管理所有工作人员 .

    希望有所帮助!

相关问题