简体   繁体   English

如何针对存储帐户运行多个子运行本

[英]How to run multiple child runbooks against storage account

I have a powershell azure runbook that iterates through a large storage account and enforces file age policies on the blobs within the account. 我有一个Powershell蔚蓝Runbook,它通过一个大的存储帐户进行迭代,并在该帐户内的Blob上强制执行文件年龄策略。 This runs fine but runs up against the Fair Share policy of 3 hours. 这可以正常运行,但会违反3个小时的公平份额政策。 I can use hybrid workers but I would prefer to run multiple child runbooks in parallel each handling a different portion of the blob account using the first letter prefix. 我可以使用混合工作程序,但我希望并行运行多个子运行手册,每个运行手册使用首字母前缀处理blob帐户的不同部分。

Example: 例:

First child runbook runs AM Second: NZ Third: am Fourth: mz 第一个子手册运行AM第二:NZ第三:AM第四:mz

I'm thinking of using a prefix variable within a loop that will iterate between letters. 我正在考虑在循环中使用前缀变量,该循环将在字母之间进行迭代。

## Declaring the variables
$number_of_days_bak_threshold = 15
$number_of_days_trn_threshold = 2
$current_date = get-date
$date_before_blobs_to_be_deleted_bak = $current_date.AddDays(-$number_of_days_bak_threshold)
$date_before_blobs_to_be_deleted_trn = $current_date.AddDays(-$number_of_days_trn_threshold)

# Number of blobs deleted
$blob_count_deleted = 0

# Storage account details
$storage_account_name = <Account Name> 
$storage_account_key = <Account Key>
$container = <Container>

## Creating Storage context for Source, destination and log storage accounts
$context = New-AzureStorageContext -StorageAccountName $storage_account_name -StorageAccountKey $storage_account_key
$blob_list = Get-AzureStorageBlob -Context $context -Container $container

## Creating log file
$log_file = "log-"+(get-date).ToString().Replace('/','-').Replace(' ','-').Replace(':','-') + ".txt"
$local_log_file_path = $env:temp + "\" + "log-"+(get-date).ToString().Replace('/','-').Replace(' ','-').Replace(':','-') + ".txt"

write-host "Log file saved as: " $local_log_file_path -ForegroundColor Green

## Iterate through each blob
foreach($blob_iterator in $blob_list){

    $blob_date = [datetime]$blob_iterator.LastModified.UtcDateTime 

    # Check if the blob's last modified date is less than the threshold date for deletion for trn files:        
    if($blob_iterator.Name -Match ".trn") {
        if($blob_date -le $date_before_blobs_to_be_deleted_trn) {

        Write-Output "-----------------------------------" | Out-File $local_log_file_path -Append
        write-output "Purging blob from Storage: " $blob_iterator.name | Out-File $local_log_file_path -Append
        write-output " " | Out-File $local_log_file_path -Append
        write-output "Last Modified Date of the Blob: " $blob_date | Out-File $local_log_file_path -Append
        Write-Output "-----------------------------------" | Out-File $local_log_file_path -Append

        # Cmdle to delete the blob
        Remove-AzureStorageBlob -Container $container -Blob $blob_iterator.Name -Context $context

        $blob_count_deleted += 1
        Write-Output "Deleted "$extn
        }  
    }
    Elseif($blob_iterator.Name -Match ".bak") {
        if($blob_date -le $date_before_blobs_to_be_deleted_bak) {

        Write-Output "-----------------------------------" | Out-File $local_log_file_path -Append
        write-output "Purging blob from Storage: " $blob_iterator.name | Out-File $local_log_file_path -Append
        write-output " " | Out-File $local_log_file_path -Append
        write-output "Last Modified Date of the Blob: " $blob_date | Out-File $local_log_file_path -Append
        Write-Output "-----------------------------------" | Out-File $local_log_file_path -Append

        # Cmdle to delete the blob
        Remove-AzureStorageBlob -Container $container -Blob $blob_iterator.Name -Context $context

        $blob_count_deleted += 1
        Write-Output "Deleted "$extn
        }  
    }
    Else{
        Write-Error "Unable to determine file type." $blob_iterator.Name
    }
}
Write-Output "Blobs deleted: " $blob_count_deleted | Out-File $local_log_file_path -Append

I expect to be able to run through the account in parallel. 我希望能够并行运行该帐户。

So, I agree with @4c74356b41 that breaking the workload down is the best approach . 因此, 我同意@ 4c74356b41的观点,认为分解工作负载是最好的方法 However, that is itself, not always as simple as it might sound. 但是,这本身并不总是听起来那么简单。 Below I describe the various workarounds for fairshare and the potential issues I can think of off the top of my head. 下面,我描述了公平共享的各种变通方法以及我可以想到的潜在问题。 It as quite a lot of information, so here are the highlights: 它提供了大量信息,因此重点介绍:

  • Create jobs that do part of the work and then start the next job in the sequence. 创建完成部分工作的作业,然后按顺序开始下一个作业。
  • Create jobs that all run on part of the sequence in parallel. 创建全部在部分序列上并行运行的作业。
  • Create a runbook that does the work in parallel but also in a single job. 创建一个既可以并行执行又可以单项工作的运行手册。
  • Use PowerShell Workflow with checkpoints so that your job is not subjected to fairshare. 将PowerShell Workflow与检查点一起使用,以免您的工作受到公平对待。
  • Migrate the workload to use Azure Functions, eg Azure PowerShell functions . 迁移工作负载以使用Azure函数,例如Azure PowerShell函数

TL;DR TL; DR

No matter what, there are ways to breakup a sequential workload into sequentially executed jobs, eg each job works on a segment and then starts the next job as it's last operation. 无论如何,有多种方法可以将顺序的工作负载分解为顺序执行的作业,例如,每个作业都在段上工作,然后在下一个作业作为上一个操作开始。 ( Like a kind of recursion. ) However, managing a sequential approach to correctly handle intermittent failures can add a lot of complexity. 就像一种递归。 )但是,管理顺序方法以正确处理间歇性故障会增加很多复杂性。

If the workload can be broken down into smaller jobs that do not use a lot of resources, then you could do the work in parallel. 如果可以将工作负载分解为不占用大量资源的较小的工作,则可以并行进行工作。 In other words, if the amount of memory and socket resources required by each segment is low, and as long as there is no overlap or contention, this approach should run in parallel much faster. 换句话说,如果每个段所需的内存和套接字资源量很低,并且只要没有重叠或争用,则此方法应并行运行得更快。 I also suspect that in parallel, the combined job minutes will still be less than the minutes necessary for a sequential approach. 我还怀疑,与此并行,合并的工作时间仍将少于顺序方法所需的时间。

There is one gotcha with processing the segments in parallel... 有一个并行处理段的陷阱 ...

When a bunch of AA jobs belonging to the same account are started together, the tendency that they will all run within the same sandbox instance increases significantly. 当一堆属于同一帐户的AA作业一起启动时,它们将全部在同一沙箱实例中运行的趋势大大增加。 Sandboxes are never shared with un-related accounts, but because of improvements in job start performance, there is a preference to share sandboxes for jobs within the same account. 沙盒永远不会与不相关的帐户共享,但是由于作业启动性能得到了改善,因此偏爱为同一帐户中的作业共享沙盒。 When these jobs all run at the same time, there is an increased likelihood that the overall sandbox resource quota will be hit and then the sandbox will perform a hard exit immediately. 当这些作业全部同时运行时,总沙箱资源配额将被达到,然后沙箱将立即执行硬退出的可能性增加。

Because of this gotcha , if your workload is memory or socket intensive, you may want to have a parent runbook that controls the lifecycle (ie start rate) of the child runbooks. 由于这种疑难杂症 ,如果你的工作量是内存或插座密集,你可能需要有控制生命周期父运行手册(即启动速度)儿童运行手册的。 This has the twisted effect that the parent runbook could now hit the fairshare limit. 这产生了一种扭曲效果,即父级运行手册现在可以达到公平份额的限制。

The next workaround is to implement runbooks that kick off the job for the next processing segment when they are completed. 下一个解决方法是实现运行手册,这些手册在完成后将启动下一个处理段的作业。 The best approach for this is to store the next segment somewhere the job can retrieve it, eg variable or blob. 最好的方法是将下一个段存储在作业可以检索到的位置,例如变量或Blob。 This way, if a job fails with its segment, as long as there is some way of making sure the jobs run until the entire workload finishes, everything will eventually finish. 这样,如果作业在其段中失败,只要有某种方法可以确保作业在整个工作负载完成之前一直运行,则所有工作最终都会完成。 You might want to use a watcher task to verify eventual completion and handle retries. 您可能要使用观察程序任务来验证最终完成并处理重试。 Once you get to this level of complexity, you can experiment to discover how much parallelism you can introduce without hitting resource limits. 一旦达到了这种复杂性水平,您就可以尝试发现可以引入多少并行性而又不会达到资源限制。

  • There is no way for a job to monitor the available resource and throttle itself. 作业无法监视可用资源并限制自身。
  • There is no way to force each job to run in its own sandbox. 无法强迫每个作业在其自己的沙箱中运行。
  • Whether jobs run in the same sandbox is very non-deterministic, which can cause problems with hard to trace intermittent failures. 作业是否在同一沙箱中运行是不确定的,这可能导致难以跟踪间歇性故障的问题。

If you have no worry for hitting resource limits , you could consider using the ThreadJob module on the PowerShell Gallery . 如果您不必担心达到资源限制 ,可以考虑使用PowerShell画廊上的ThreadJob模块 With this approach, you would still have a single runbook, but know you would be able to parallelize the workload within that runbook and complete the workload before hitting the fairshare limit. 使用这种方法,您仍将只有一个Runbook,但知道您将能够并行化该Runbook中的工作负载并在达到公平份额限制之前完成工作负载。 This can be very effective if the individual tasks are fast and lightweight. 如果单个任务既快速又轻便,这将非常有效。 Otherwise, this approach may work for a little while but begin to fail if the workload increases in either the time or resources required. 否则,此方法可能会工作一会儿,但如果工作量增加了所需的时间或资源,则会开始失败。

Do not use PowerShell Jobs within an AA Job to achieve parallelism . 不要在AA Job中使用PowerShell Jobs来实现并行性 This includes not using commands like Parallel-ForEach . 这包括使用Parallel-ForEach类的命令。 There are a lot of examples for VM-Start/Stop runbooks that use PowerShell Jobs; 有很多使用PowerShell Jobs的VM-Start/Stop手册示例。 this is not a recommend approach . 这不是推荐的方法 PowerShell Jobs require a lot of resources to execute, so using PowerShell Jobs will significantly increase the resources used by you AA Job and the chance of hitting the memory quota. PowerShell作业需要大量资源才能执行,因此使用PowerShell作业将显着增加AA作业使用的资源以及达到内存配额的机会。

You can get around the fairshare limitation by re-implementing you code as a Power Shell Workflow and performing frequent checkpoints. 通过将代码重新实现为Power Shell工作流并执行频繁的检查点,可以避免公平份额的限制。 When a workflow job hits the fairshare limit, if it has been performing checkpoints, it will be restarted on another sandbox, resuming from the last checkpoint. 当工作流作业达到公平共享限制时,如果它一直在执行检查点,则它将在另一个沙箱中重新启动,从上一个检查点恢复。

My recollection is your jobs need to perform a checkpoint at least once every 30 minutes. 我的回忆是您的工作需要每30分钟至少执行一次检查点。 If they do this, that will resume from the fairshare without any penalty, forever . 如果他们这样做,它将从公平份额中永久恢复,而不会受到任何惩罚。 (At the cost of a tremendous number of job minutes.) (以大量的工作时间为代价。)

Even without a checkpoint, a workflow will get re-tried 2 times after hitting the checkpoint. 即使没有检查点,工作流也将在到达检查点后重试2次。 Because of this, if your workflow code is idempotent, and quickly will skip previously completed work, by using a workflow, your job may complete (in 9 hours) even without checkpoints. 因此,如果您的工作流程代码是幂等的,并且通过使用工作流程,它会迅速跳过以前完成的工作,即使没有检查点,您的工作也可能会完成(9小时内)。

However, workflow are not just Power Shell script wrapped inside a workflow {} script block: 但是,工作流不仅仅是包装在workflow {}脚本块中的Power Shell脚本:

  • There are a lot of subtle differences in the way workflow function compared to scripts. 与脚本相比,工作流的功能有许多细微的差异。 Mastering these subtleties is difficult at best. 最好地掌握这些细微之处。
  • Workflow will not checkpoint all state during job execution. 在作业执行期间,工作流不会检查点所有状态。 For example, the big one is that you need to write your workflow so that it will re-authenticate with Azure after each checkpoint, because credentials are not captured by the checkpoint. 例如,最大的问题是您需要编写工作流,以便在每个检查点之后都可以使用Azure重新进行身份验证,因为检查点无法捕获凭据。
  • I don't think anyone is going to claim debugging an AA job is an easy task. 我认为没有人会宣称调试AA作业是一件容易的事。 For workflow this task is even harder. 对于工作流程,此任务更加艰巨。 Even with all the correct dependencies, how a workflow runs when executed locally is different from how it executes in the cloud. 即使具有所有正确的依存关系,工作流在本地执行时的运行方式也与在云中执行的方式不同。
  • Script run measurably faster than workflow. 脚本的运行速度明显快于工作流程。

Migrate the work into Azure Functions . 将工作迁移到Azure Functions中 With the recent release of PowerShell function, this might be relatively easy. 在最近发布的PowerShell函数中,这可能相对容易。 Functions will have different limitations than those in Automation. 功能将具有与自动化中不同的限制。 This difference might suit your workload well, or be worse. 这种差异可能很好地适合您的工作量,或更糟。 I have not yet tried the Functions approach, so I can't really say. 我还没有尝试过“函数”方法,所以我不能说真的。

The most obvious difference you will notice right away is that Functions is a lot more of a raw, DevOps oriented service than Automation. 您将立即注意到的最明显的区别是,Functions是更多的原始的,面向DevOps的服务,而不是Automation。 This is partly because Automation is a more mature product. 部分原因是自动化是一种更成熟的产品。 (Automation was probably the first widely available serverless service, having launched roughly a year before Lambda.) Automation was purpose built for automating the management of cloud resources, and automation is the driving factor in the feature selection. (自动化可能是第一个广泛可用的无服务器服务,大约在Lambda之前一年就推出了。)自动化是专为自动化云资源管理而构建的,自动化是功能选择的驱动因素。 Whereas Functions is a much more general purpose serverless operations approach. 而功能是一种更为通用的无服务器操作方法。 Anyway, one obvious difference at the moment is Functions does not have any built-in support for things like the RunAs account or Variables. 无论如何,目前有一个明显的区别是,Functions不对诸如RunAs帐户或Variables之类的东西提供任何内置支持。 I expect Functions will improve in this specific aspect over time, but right now it is pretty basic for automation tasks. 我希望功能会随着时间的推移在此特定方面有所改进,但是现在对于自动化任务来说这是非常基本的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 多个 Runbook 能否在一个 azure 自动化帐户中同时运行? - Can multiple runbooks run simultaneously in an azure automation account? 对特定的存储帐户运行azure cli - run azure cli against a specific storage account 如何使用 Runbook 将文件保存到 Azure 存储 - How to save files to azure storage using runbooks 如何在运行手册中运行 Azure CLI 命令? - How to run Azure CLI command in runbooks? 如何在Azure RunBooks中将参数从子级传递到父级 - How do I pass parameters from Child to Parent in Azure RunBooks 部署 Azure 自动化帐户 Runbook 的最佳做法 - Best practice to deploy Azure Automation Account Runbooks 如何将多个 Blob 容器从一个存储帐户复制到另一个存储帐户(不同订阅) - How to copy multiple blob containers from one storage account to another storage account(different subscriptions) 如何检查 Azure blob 是否存在于多个容器的存储帐户中的任何位置? - How to check if Azure blob exists anywhere in storage account in multiple containers? Azure Runbook-缺少PowerShell Cmdlet或未针对VM执行 - Azure Runbooks - Missing PowerShell Cmdlets Or Not Executing Against a VM 如何在 Azure Runbooks 中使用 ZA7F5F35426B9637411FCZ3231B 验证 REST API - How to authenticate REST API in Azure Runbooks with Python?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM