Распараллеливание выполнения сценария powershell - PullRequest
1 голос
/ 03 февраля 2012

У меня 8 сценариев PowerShell. Немногие из них имеют зависимости. Это означает, что они не могут быть выполнены параллельно. Они должны быть выполнены за другим.

Некоторые сценарии Powershell не имеют зависимости и могут выполняться параллельно.

Ниже подробно описана зависимость

    Powershell scripts 1, 2, and 3 depend on nothing else
    Powershell script 4 depends on Powershell script 1
    Powershell script 5 depends on Powershell scripts 1, 2, and 3
    Powershell script 6 depends on Powershell scripts 3 and 4
    Powershell script 7 depends on Powershell scripts 5 and 6
    Powershell script 8 depends on Powershell script 5

Я знал, что при ручном жестком кодировании зависимость возможна. Но можно добавить еще 10 сценариев PowerShell и зависимость между ними.

Кто-нибудь достиг параллелизма, найдя зависимость? Если да, пожалуйста, поделитесь со мной, как действовать.

Ответы [ 3 ]

5 голосов
/ 03 февраля 2012

Вам нужно взглянуть на рабочие процессы PowerShell 3.0.Он предлагает функции, необходимые для вашего требования.Как то так:

workflow Install-myApp {
    param ([string[]]$computername)
    foreach -parallel($computer in $computername) {
        "Installing MyApp on $computer"
        #Code for invoking installer here
        #This can take as long as 30mins and may reboot a couple of times
    }
}

workflow Install-MyApp2{
    param ([string[]]$computername)
    foreach -parallel($computer in $computername) {
        "Installing MyApp2 on $computer"
        #Code for invoking installer here
        #This can take as long as 30mins!
    }
}

WorkFlow New-SPFarm {
    Sequence {
        Parallel {
            Install-MyApp2 -computername "Server2","Server3"
            Install-MyApp -computername "Server1","Server4","Server5"
        }
        Sequence {
            #This activity can happen only after the set of activities in the above parallel block are complete"
            "Configuring First Server in the Farm [Server1]"

            #The following foreach should take place only after the above activity is complete and that is why we have it in a sequence
            foreach -parallel($computer in $computername) {
                "Configuring SharePoint on $computer"
            }
        }
    }
} 
2 голосов
/ 03 февраля 2012

Насколько вы знакомы с параллельным программированием в целом? Вы слышали и использовали концепцию взаимного исключения ? В целом, концепция заключается в использовании какого-либо механизма обмена сообщениями / блокировки для защиты общего ресурса между различными параллельными потоками.

В вашем случае вы делаете разделительные линии самими сценариями - что, я думаю, может сделать это намного проще, чем большинство методов, описанных в этой статье в Википедии. Будет ли этот простой шаблон работать на то, что вы ищете?

  1. Определить папку в локальной файловой системе. Это местоположение будет известно всем сценариям (параметр по умолчанию).
  2. Перед запуском любого из сценариев убедитесь, что все файлы в этом каталоге удалены.
  3. Для каждого скрипта, как самого последнего шага их выполнения, они должны записать файл в общий каталог с именем своего скрипта в качестве имени файла. Таким образом, script1.ps1 создаст файл script1, например.
  4. Любой скрипт, имеющий зависимость от другого скрипта, будет определять эти зависимости в терминах имен файлов скриптов. Если script3 зависит от script1 и script2, это будет определено как параметр зависимости в script3.
  5. Все сценарии с зависимостями будут запускать функцию, которая проверяет, существуют ли файлы для сценариев, от которых она зависит. Если они есть, он продолжает выполнение сценария, в противном случае он приостанавливается, пока они не будут завершены.
  6. Все сценарии запускаются одновременно основным сценарием / командным файлом. Все сценарии выполняются как задания PowerShell, поэтому ОС будет выполнять их выполнение параллельно. Большинство сценариев запустятся, увидят, что они имеют зависимости, и затем терпеливо ждут их разрешения, прежде чем продолжать фактическое выполнение тела сценария.

Хорошая новость заключается в том, что это позволит гибко изменять зависимости. Каждый сценарий записывает файл, не делая предположений о том, ждет ли их кто-то еще или нет. Изменение зависимости конкретного сценария будет простым однострочным изменением или изменением входного параметра.

Хотя это определенно не идеальное решение. Например, что произойдет в случае сбоя сценария (или ваш сценарий может завершиться несколькими путями кода, но вы забыли записать файл в один из них)? Это может привести к тупиковой ситуации, когда никакие зависимые сценарии не будут запущены. Другая плохая вещь - это занятое ожидание сна или вращения в ожидании создания нужных файлов - это можно исправить, применив Основанный на событиях подход, при котором ОС следит за изменением каталога.

Надеюсь, это поможет, а не весь мусор.

1 голос
/ 03 февраля 2012

Вам просто нужно правильно заказать звонки.Там нет ничего встроенного, что будет обрабатывать зависимости для вас.

Запустите 1,2,3 одновременно Start-Job.

Подождите, пока они будут выполнены Get-Job -State Running | Wait-Job

Запускать 4,5 одновременно Start-Job

Дождаться их завершения Get-Job -State Running | Wait-Job

Выполнить 6 и дождаться его.7, 8 одновременно Start-Job

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...