【问题标题】:Python script to write(+lock) / read a file in Azure在 Azure 中写入(+锁定)/读取文件的 Python 脚本
【发布时间】:2019-05-18 19:09:13
【问题描述】:

我是 python 编程和 Azure 的新手。

我需要编写一个由 2 个进程执行的脚本。

这 2 个进程将运行相同的 python 脚本。 我知道 Azure 有 storageAccounts 可以在其中放置一些文件,我发现了这个: https://docs.microsoft.com/en-us/python/api/azure-storage-file/azure.storage.file.fileservice.fileservice?view=azure-python

和: https://github.com/Azure/azure-storage-python

这是一些伪代码来说明我需要实现的目标:

function useStorageFile
   if(fileFromStorage == null)
      createFileInStorage lockFileInStorage;
      executeDockerCommand;
      writeResultOFCommandInStorageFile;
   else
      if(fileFromStorage != null)
        X:if(fileFromStorage.status !== 'locked')
           readResultFromFile
        else
           wait 1s;
           continue X;

是否可以在 Azure 中锁定/解锁文件?例如,我如何在 python 中实现这一点?谢谢。

编辑 我已经设法使用 python 脚本在 Blob Storage 中编写了一个文件。现在的问题是:如何在第一个进程将命令结果写入文件时锁定文件,并在 Blob 存储锁(如果存在该选项......)被释放后立即由第二个进程读取它第一个过程?这是我使用的python脚本:

import os, uuid, sys
from azure.storage.blob import BlockBlobService, PublicAccess

def run_sample():
    try:
        # Create the BlockBlockService that is used to call the Blob service for the storage account
        block_blob_service = BlockBlobService(account_name='xxxxxx', account_key='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx')

        # Create a container called 'quickstartblobs'.
        container_name ='quickstartblobs'
        block_blob_service.create_container(container_name)

        # Set the permission so the blobs are public.
        block_blob_service.set_container_acl(container_name, public_access=PublicAccess.Container)

        # Create a file in Documents to test the upload and download.
        local_path=os.path.abspath(os.path.curdir)
        local_file_name ='youss.txt'
        full_path_to_file =os.path.join(local_path, local_file_name)

        # Write text to the file.
        file = open(full_path_to_file,  'w')
        file.write("Hello, World!")
        file.close()

        print("Temp file = " + full_path_to_file)
        print("\nUploading to Blob storage as blob" + local_file_name)

        # Upload the created file, use local_file_name for the blob name
        block_blob_service.create_blob_from_path(container_name, local_file_name, full_path_to_file)

        # List the blobs in the container
        print("\nList blobs in the container")
        generator = block_blob_service.list_blobs(container_name)
        for blob in generator:
            print("\t Blob name: " + blob.name)

        # Download the blob(s).
        # Add '_DOWNLOADED' as prefix to '.txt' so you can see both files in Documents.
        full_path_to_file2 = os.path.join(local_path, str.replace(local_file_name ,'.txt', '_DOWNLOADED.txt'))
        print("\nDownloading blob to " + full_path_to_file2)
        block_blob_service.get_blob_to_path(container_name, local_file_name, full_path_to_file2)

        sys.stdout.write("Sample finished running. When you hit <any key>, the sample will be deleted and the sample "
                         "application will exit.")
        sys.stdout.flush()
        input()

        # Clean up resources. This includes the container and the temp files
        block_blob_service.delete_container(container_name)
        os.remove(full_path_to_file)
        os.remove(full_path_to_file2)
    except Exception as e:
        print(e)


# Main method.
if __name__ == '__main__':
    run_sample()

【问题讨论】:

  • 必须使用 Azure 文件存储吗?你可以改用 Azure Blob 存储吗?
  • @GauravMantri 不,我说 Azure 文件存储是因为我是 Azure 的新手,它是我发现的第一个。 Blob 存储更好吗?有可能解决我的问题吗?谢谢
  • 谢谢!还有一个问题:您要锁定文件以进行写入或读取吗?
  • @GauravMantri 我使用了 Blob 存储并设法编写了一个 python 脚本来创建一个文件。我的问题实际上是确保只有 2 个进程(实际上是 2 个虚拟机)中的一个会写入其中,而第二个进程会在锁定释放后立即读取此文件。我将编辑我的问题以编写在 Blob 存储中创建文件的代码
  • 我不认为你可以锁定文件本身。如何通过在同一个文件夹中使用另一个名称创建第二个“锁定”文件来模拟锁定?打开实际文件之前的过程会检查文件夹中是否有锁定文件,如果没有 - 推送锁定文件,然后打开实际阅读,完成工作后删除锁定文件。显然,可能存在竞争条件的情况,理论上可以通过使用具有更小延迟的系统(如 RabbitMQ/Kafka 队列或基于信号量技术的东西)来解决。

标签: python python-3.x azure azure-storage-account


【解决方案1】:

如何在将命令结果写入文件时锁定文件 第一个进程,并使其被第二个进程读取 Blob 存储锁(如果存在该选项...)由第一个释放 过程?

Azure Blob 存储有一个名为 Lease 的功能,您可以使用它。本质上,Leasing 进程获取资源(在您的情况下为 blob)的排他锁,并且只有一个进程可以获取 blob 的租约。在 blob 上获取租约后,任何其他进程都无法修改或删除 blob。

因此,您需要做的是在写入之前尝试获取 blob 的租约。如果 blob 已被租用,您将收到错误消息(HTTP 状态代码 412,PreConditionFailed 错误)。假设您没有收到错误,您可以继续更新文件。文件更新后,您可以手动释放锁(中断租约或释放租约)或让租约自动到期。假设您收到错误,您应该等待并定期(例如每 5 秒)获取 blob 的租用状态。一旦您发现该 blob 不再被租用,您就可以读取该 blob 的内容。

【讨论】:

  • 谢谢伙计,它真的看起来像我需要的,我会尝试你的解决方案,因为它听起来像 ONE :),你认为它在 python 中是可行的吗?非常感谢
  • Storage SDK for python 中应该提供租赁 blob。尝试在 blob_service 中寻找函数 lease_blob 或类似的东西。
  • 我已经为 python 实现找到了这个github.com/Azure-Samples/storage-blob-python-getting-started/… 你如何建议定期实现对 blob 租约的获取?我想可能有一个while循环(我是python编程的新手,抱歉)
  • How do you recommend to implement the fetch of the blob's lease periodically ? - 我要做的是定期获取 blob 的属性并检查租约状态。我对 python 也不是很熟悉,但是是的,你需要做一个 while 循环。
  • 另外,请确保您没有在 blob 上设置 infinite 租约。将其设置为更短的持续时间(15 - 60 秒之间),以便在写入 blob 的进程出现问题时,租约会在该持续时间后自动清除。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多