繁体   English   中英

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

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

我有一个Powershell蔚蓝Runbook,它通过一个大的存储帐户进行迭代,并在该帐户内的Blob上强制执行文件年龄策略。 这可以正常运行,但会违反3个小时的公平份额政策。 我可以使用混合工作程序,但我希望并行运行多个子运行手册,每个运行手册使用首字母前缀处理blob帐户的不同部分。

例:

第一个子手册运行AM第二:NZ第三:AM第四:mz

我正在考虑在循环中使用前缀变量,该循环将在字母之间进行迭代。

## 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

我希望能够并行运行该帐户。

因此, 我同意@ 4c74356b41的观点,认为分解工作负载是最好的方法 但是,这本身并不总是听起来那么简单。 下面,我描述了公平共享的各种变通方法以及我可以想到的潜在问题。 它提供了大量信息,因此重点介绍:

  • 创建完成部分工作的作业,然后按顺序开始下一个作业。
  • 创建全部在部分序列上并行运行的作业。
  • 创建一个既可以并行执行又可以单项工作的运行手册。
  • 将PowerShell Workflow与检查点一起使用,以免您的工作受到公平对待。
  • 迁移工作负载以使用Azure函数,例如Azure PowerShell函数

TL; DR

无论如何,有多种方法可以将顺序的工作负载分解为顺序执行的作业,例如,每个作业都在段上工作,然后在下一个作业作为上一个操作开始。 就像一种递归。 )但是,管理顺序方法以正确处理间歇性故障会增加很多复杂性。

如果可以将工作负载分解为不占用大量资源的较小的工作,则可以并行进行工作。 换句话说,如果每个段所需的内存和套接字资源量很低,并且只要没有重叠或争用,则此方法应并行运行得更快。 我还怀疑,与此并行,合并的工作时间仍将少于顺序方法所需的时间。

有一个并行处理段的陷阱 ...

当一堆属于同一帐户的AA作业一起启动时,它们将全部在同一沙箱实例中运行的趋势大大增加。 沙盒永远不会与不相关的帐户共享,但是由于作业启动性能得到了改善,因此偏爱为同一帐户中的作业共享沙盒。 当这些作业全部同时运行时,总沙箱资源配额将被达到,然后沙箱将立即执行硬退出的可能性增加。

由于这种疑难杂症 ,如果你的工作量是内存或插座密集,你可能需要有控制生命周期父运行手册(即启动速度)儿童运行手册的。 这产生了一种扭曲效果,即父级运行手册现在可以达到公平份额的限制。

下一个解决方法是实现运行手册,这些手册在完成后将启动下一个处理段的作业。 最好的方法是将下一个段存储在作业可以检索到的位置,例如变量或Blob。 这样,如果作业在其段中失败,只要有某种方法可以确保作业在整个工作负载完成之前一直运行,则所有工作最终都会完成。 您可能要使用观察程序任务来验证最终完成并处理重试。 一旦达到了这种复杂性水平,您就可以尝试发现可以引入多少并行性而又不会达到资源限制。

  • 作业无法监视可用资源并限制自身。
  • 无法强迫每个作业在其自己的沙箱中运行。
  • 作业是否在同一沙箱中运行是不确定的,这可能导致难以跟踪间歇性故障的问题。

如果您不必担心达到资源限制 ,可以考虑使用PowerShell画廊上的ThreadJob模块 使用这种方法,您仍将只有一个Runbook,但知道您将能够并行化该Runbook中的工作负载并在达到公平份额限制之前完成工作负载。 如果单个任务既快速又轻便,这将非常有效。 否则,此方法可能会工作一会儿,但如果工作量增加了所需的时间或资源,则会开始失败。

不要在AA Job中使用PowerShell Jobs来实现并行性 这包括使用Parallel-ForEach类的命令。 有很多使用PowerShell Jobs的VM-Start/Stop手册示例。 这不是推荐的方法 PowerShell作业需要大量资源才能执行,因此使用PowerShell作业将显着增加AA作业使用的资源以及达到内存配额的机会。

通过将代码重新实现为Power Shell工作流并执行频繁的检查点,可以避免公平份额的限制。 当工作流作业达到公平共享限制时,如果它一直在执行检查点,则它将在另一个沙箱中重新启动,从上一个检查点恢复。

我的回忆是您的工作需要每30分钟至少执行一次检查点。 如果他们这样做,它将从公平份额中永久恢复,而不会受到任何惩罚。 (以大量的工作时间为代价。)

即使没有检查点,工作流也将在到达检查点后重试2次。 因此,如果您的工作流程代码是幂等的,并且通过使用工作流程,它会迅速跳过以前完成的工作,即使没有检查点,您的工作也可能会完成(9小时内)。

但是,工作流不仅仅是包装在workflow {}脚本块中的Power Shell脚本:

  • 与脚本相比,工作流的功能有许多细微的差异。 最好地掌握这些细微之处。
  • 在作业执行期间,工作流不会检查点所有状态。 例如,最大的问题是您需要编写工作流,以便在每个检查点之后都可以使用Azure重新进行身份验证,因为检查点无法捕获凭据。
  • 我认为没有人会宣称调试AA作业是一件容易的事。 对于工作流程,此任务更加艰巨。 即使具有所有正确的依存关系,工作流在本地执行时的运行方式也与在云中执行的方式不同。
  • 脚本的运行速度明显快于工作流程。

将工作迁移到Azure Functions中 在最近发布的PowerShell函数中,这可能相对容易。 功能将具有与自动化中不同的限制。 这种差异可能很好地适合您的工作量,或更糟。 我还没有尝试过“函数”方法,所以我不能说真的。

您将立即注意到的最明显的区别是,Functions是更多的原始的,面向DevOps的服务,而不是Automation。 部分原因是自动化是一种更成熟的产品。 (自动化可能是第一个广泛可用的无服务器服务,大约在Lambda之前一年就推出了。)自动化是专为自动化云资源管理而构建的,自动化是功能选择的驱动因素。 而功能是一种更为通用的无服务器操作方法。 无论如何,目前有一个明显的区别是,Functions不对诸如RunAs帐户或Variables之类的东西提供任何内置支持。 我希望功能会随着时间的推移在此特定方面有所改进,但是现在对于自动化任务来说这是非常基本的。

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM