Разделите выделение томов в Локальные дисковые пространства

Windows Server 2019 предоставляет возможность вручную разделять выделение томов в Локальные дисковые пространства. Это может значительно увеличить отказоустойчивость в определенных условиях, но накладывает некоторые дополнительные рекомендации по управлению и сложность. В этом разделе объясняется, как она работает и содержит примеры в PowerShell.

Внимание

Эта функция новая в Windows Server 2019. Он недоступен в Windows Server 2016.

Необходимые компоненты

Значок зеленой галочки. Рекомендуется использовать этот параметр, если:

Красный значок X. Не используйте этот параметр, если:

Общие сведения

Проверка: регулярное выделение

При регулярном трехмерном зеркальном отображении том делится на множество небольших "плит", которые копируются три раза и равномерно распределяются по каждому диску на каждом сервере в кластере. Дополнительные сведения см . в этом блоге глубокого погружения.

Схема, показывающая том, разделенный на три стека плит и распределенные равномерно по каждому серверу.

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

Однако при этом выделении тома не могут выжить три параллельных сбоя. Если три сервера завершаются сбоем, или если диски на трех серверах одновременно завершаются ошибкой, тома становятся недоступными, так как по крайней мере некоторые плиты были (с очень высокой вероятностью) выделены точным трем дискам или серверам, которые завершились сбоем.

В приведенном ниже примере серверы 1, 3 и 5 завершаются сбоем одновременно. Хотя многие плиты имеют выжившие копии, некоторые из них не:

Схема, показывающая три из шести серверов, выделенных красным цветом, и общий том имеет красный цвет.

Том переходит в автономный режим и становится недоступным, пока серверы не будут восстановлены.

Новое: выделение с разделителями

При выделении разделителя вы указываете подмножество серверов для использования (минимум четыре). Том делится на плиты, которые копируются три раза, как и раньше, но вместо выделения по каждому серверу плиты выделяются только подмножеством указанных серверов.

Например, если у вас есть кластер узлов 8 (узлы 1–8), можно указать том, который должен находиться только на дисках в узлах 1, 2, 3, 4.

Достоинства

При использовании примера выделения том, скорее всего, будет выжить три параллельных сбоя. Если узлы 1, 2 и 6 идут вниз, только 2 узла, в которых хранятся 3 копии данных для тома, будут отключены, и том останется в сети.

Вероятность выживания зависит от количества серверов и других факторов. Дополнительные сведения см. в разделе "Анализ ".

Недостатки

Выделение с разделителями накладывает некоторые добавленные рекомендации по управлению и сложность:

  1. Администратор отвечает за разделение распределения каждого тома для балансировки использования хранилища между серверами и обеспечения высокой вероятности выживания, как описано в разделе "Рекомендации ".

  2. При выделении разделителя зарезервировать эквивалент одного диска емкости на сервер (без максимального значения). Это больше, чем опубликованная рекомендация по регулярному выделению , которая максимально превышает четыре диска емкости.

  3. Если сервер завершается ошибкой и его необходимо заменить, как описано в разделе "Удаление сервера и его дисков", администратор отвечает за обновление разделителя затронутых томов, добавив новый сервер и удалив неудачный сервер, пример ниже.

Использование в PowerShell

Командлет можно использовать New-Volume для создания томов в Локальные дисковые пространства.

Например, чтобы создать регулярный трехмерный зеркальный том:

New-Volume -FriendlyName "MyRegularVolume" -Size 100GB

Создание тома и разделителя его выделения

Чтобы создать трехсторонняя зеркальная тома и разделителя его выделения:

  1. Сначала назначьте серверы в кластере переменной $Servers:

    $Servers = Get-StorageFaultDomain -Type StorageScaleUnit | Sort FriendlyName
    

    Совет

    В Локальные дисковые пространства термин "Единица масштабирования хранилища" относится ко всему необработанному хранилищу, подключенному к одному серверу, включая прямые подключенные диски и внешние корпуса с дисками. В этом контексте это то же самое, что и сервер.

  2. Укажите, какие серверы следует использовать с новым -StorageFaultDomainsToUse параметром и индексированием $Serversв . Например, чтобы разделить выделение на первый, второй, третий и четвертый серверы (индексы 0, 1, 2 и 3):

    New-Volume -FriendlyName "MyVolume" -Size 100GB -StorageFaultDomainsToUse $Servers[0,1,2,3]
    

См. разделители

Чтобы узнать, как выделяется MyVolume , используйте Get-VirtualDiskFootprintBySSU.ps1 сценарий в приложении:

PS C:\> .\Get-VirtualDiskFootprintBySSU.ps1

VirtualDiskFriendlyName TotalFootprint Server1 Server2 Server3 Server4 Server5 Server6
----------------------- -------------- ------- ------- ------- ------- ------- -------
MyVolume                300 GB         100 GB  100 GB  100 GB  100 GB  0       0

Обратите внимание, что только Сервер1, Server2, Server3 и Server4 содержат плиты MyVolume.

Изменение выделения с разделителями

Используйте новые Add-StorageFaultDomain и Remove-StorageFaultDomain командлеты, чтобы изменить способ разделения выделения.

Например, чтобы переместить MyVolume по одному серверу:

  1. Укажите, что пятый сервер может хранить плиты MyVolume:

    Get-VirtualDisk MyVolume | Add-StorageFaultDomain -StorageFaultDomains $Servers[4]
    
  2. Укажите, что первый сервер не может хранить плиты MyVolume:

    Get-VirtualDisk MyVolume | Remove-StorageFaultDomain -StorageFaultDomains $Servers[0]
    
  3. Перебалансировать пул носителей, чтобы изменения вступают в силу:

    Get-StoragePool S2D* | Optimize-StoragePool
    

Вы можете отслеживать ход выполнения перебалансирования с Get-StorageJobпомощью .

После завершения убедитесь, что MyVolume перемещен Get-VirtualDiskFootprintBySSU.ps1 снова.

PS C:\> .\Get-VirtualDiskFootprintBySSU.ps1

VirtualDiskFriendlyName TotalFootprint Server1 Server2 Server3 Server4 Server5 Server6
----------------------- -------------- ------- ------- ------- ------- ------- -------
MyVolume                300 GB         0       100 GB  100 GB  100 GB  100 GB  0

Обратите внимание, что Server1 больше не содержит плиты MyVolume , а сервер5 делает.

Рекомендации

Ниже приведены рекомендации по использованию распределения томов с разделителями:

Выбор четырех серверов

Разделите каждый трехсторонняя зеркальная громкость на четыре сервера, а не больше.

Баланс хранилища

Сбалансируйте объем хранилища для каждого сервера, учитывая размер тома.

Тома выделения с разделителями-разделителями

Чтобы максимально повысить отказоустойчивость, сделайте выделение каждого тома уникальным, что означает, что он не делится всеми своими серверами с другим томом (некоторые перекрываются нормально).

Например, в системе с восемью узлами: том 1: серверы 1, 2, 3, 4 тома 2: серверы 5, 6, 7, 8 том 3: серверы 3, 4, 5, 6 том 4: серверы 1, 2, 7, 8

Анализ

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

Примечание.

Этот раздел является необязательным чтением. Если вы хотите увидеть математику, читайте дальше! Но если нет, не беспокойтесь: использование в PowerShell и рекомендации — это все, что вам нужно успешно реализовать распределение с разделителями.

До двух сбоев всегда нормально

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

Более половины сбоя кластера никогда не будут в порядке

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

Что насчет между ними?

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

Часто задаваемые вопросы

Можно ли разделять некоторые тома, но не другие?

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

Изменяет ли распределение разделителя, как работает замена диска?

Нет, это то же самое, что и при регулярном выделении.

Дополнительные справочники

Приложение

Этот скрипт поможет вам узнать, как выделяются тома.

Чтобы использовать его, как описано выше, скопируйте и вставьте и сохраните как Get-VirtualDiskFootprintBySSU.ps1.

Function ConvertTo-PrettyCapacity {
    Param (
        [Parameter(
            Mandatory = $True,
            ValueFromPipeline = $True
            )
        ]
    [Int64]$Bytes,
    [Int64]$RoundTo = 0
    )
    If ($Bytes -Gt 0) {
        $Base = 1024
        $Labels = ("bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB")
        $Order = [Math]::Floor( [Math]::Log($Bytes, $Base) )
        $Rounded = [Math]::Round($Bytes/( [Math]::Pow($Base, $Order) ), $RoundTo)
        [String]($Rounded) + " " + $Labels[$Order]
    }
    Else {
        "0"
    }
    Return
}

Function Get-VirtualDiskFootprintByStorageFaultDomain {

    ################################################
    ### Step 1: Gather Configuration Information ###
    ################################################

    Write-Progress -Activity "Get-VirtualDiskFootprintByStorageFaultDomain" -CurrentOperation "Gathering configuration information..." -Status "Step 1/4" -PercentComplete 00

    $ErrorCannotGetCluster = "Cannot proceed because 'Get-Cluster' failed."
    $ErrorNotS2DEnabled = "Cannot proceed because the cluster is not running Storage Spaces Direct."
    $ErrorCannotGetClusterNode = "Cannot proceed because 'Get-ClusterNode' failed."
    $ErrorClusterNodeDown = "Cannot proceed because one or more cluster nodes is not Up."
    $ErrorCannotGetStoragePool = "Cannot proceed because 'Get-StoragePool' failed."
    $ErrorPhysicalDiskFaultDomainAwareness = "Cannot proceed because the storage pool is set to 'PhysicalDisk' fault domain awareness. This cmdlet only supports 'StorageScaleUnit', 'StorageChassis', or 'StorageRack' fault domain awareness."

    Try  {
        $GetCluster = Get-Cluster -ErrorAction Stop
    }
    Catch {
        throw $ErrorCannotGetCluster
    }

    If ($GetCluster.S2DEnabled -Ne 1) {
        throw $ErrorNotS2DEnabled
    }

    Try  {
        $GetClusterNode = Get-ClusterNode -ErrorAction Stop
    }
    Catch {
        throw $ErrorCannotGetClusterNode
    }

    If ($GetClusterNode | Where State -Ne Up) {
        throw $ErrorClusterNodeDown
    }

    Try {
        $GetStoragePool = Get-StoragePool -IsPrimordial $False -ErrorAction Stop
    }
    Catch {
        throw $ErrorCannotGetStoragePool
    }

    If ($GetStoragePool.FaultDomainAwarenessDefault -Eq "PhysicalDisk") {
        throw $ErrorPhysicalDiskFaultDomainAwareness
    }

    ###########################################################
    ### Step 2: Create SfdList[] and PhysicalDiskToSfdMap{} ###
    ###########################################################

    Write-Progress -Activity "Get-VirtualDiskFootprintByStorageFaultDomain" -CurrentOperation "Analyzing physical disk information..." -Status "Step 2/4" -PercentComplete 25

    $SfdList = Get-StorageFaultDomain -Type ($GetStoragePool.FaultDomainAwarenessDefault) | Sort FriendlyName # StorageScaleUnit, StorageChassis, or StorageRack

    $PhysicalDiskToSfdMap = @{} # Map of PhysicalDisk.UniqueId -> StorageFaultDomain.FriendlyName
    $SfdList | ForEach {
        $StorageFaultDomain = $_
        $_ | Get-StorageFaultDomain -Type PhysicalDisk | ForEach {
            $PhysicalDiskToSfdMap[$_.UniqueId] = $StorageFaultDomain.FriendlyName
        }
    }

    ##################################################################################################
    ### Step 3: Create VirtualDisk.FriendlyName -> { StorageFaultDomain.FriendlyName -> Size } Map ###
    ##################################################################################################

    Write-Progress -Activity "Get-VirtualDiskFootprintByStorageFaultDomain" -CurrentOperation "Analyzing virtual disk information..." -Status "Step 3/4" -PercentComplete 50

    $GetVirtualDisk = Get-VirtualDisk | Sort FriendlyName

    $VirtualDiskMap = @{}

    $GetVirtualDisk | ForEach {
        # Map of PhysicalDisk.UniqueId -> Size for THIS virtual disk
        $PhysicalDiskToSizeMap = @{}
        $_ | Get-PhysicalExtent | ForEach {
            $PhysicalDiskToSizeMap[$_.PhysicalDiskUniqueId] += $_.Size
        }
        # Map of StorageFaultDomain.FriendlyName -> Size for THIS virtual disk
        $SfdToSizeMap = @{}
        $PhysicalDiskToSizeMap.keys | ForEach {
            $SfdToSizeMap[$PhysicalDiskToSfdMap[$_]] += $PhysicalDiskToSizeMap[$_]
        }
        # Store
        $VirtualDiskMap[$_.FriendlyName] = $SfdToSizeMap
    }

    #########################
    ### Step 4: Write-Out ###
    #########################

    Write-Progress -Activity "Get-VirtualDiskFootprintByStorageFaultDomain" -CurrentOperation "Formatting output..." -Status "Step 4/4" -PercentComplete 75

    $Output = $GetVirtualDisk | ForEach {
        $Row = [PsCustomObject]@{}

        $VirtualDiskFriendlyName = $_.FriendlyName
        $Row | Add-Member -MemberType NoteProperty "VirtualDiskFriendlyName" $VirtualDiskFriendlyName

        $TotalFootprint = $_.FootprintOnPool | ConvertTo-PrettyCapacity
        $Row | Add-Member -MemberType NoteProperty "TotalFootprint" $TotalFootprint

        $SfdList | ForEach {
            $Size = $VirtualDiskMap[$VirtualDiskFriendlyName][$_.FriendlyName] | ConvertTo-PrettyCapacity
            $Row | Add-Member -MemberType NoteProperty $_.FriendlyName $Size
        }

        $Row
    }

    # Calculate width, in characters, required to Format-Table
    $RequiredWindowWidth = ("TotalFootprint").length + 1 + ("VirtualDiskFriendlyName").length + 1
    $SfdList | ForEach {
        $RequiredWindowWidth += $_.FriendlyName.Length + 1
    }

    $ActualWindowWidth = (Get-Host).UI.RawUI.WindowSize.Width

    If (!($ActualWindowWidth)) {
        # Cannot get window width, probably ISE, Format-List
        Write-Warning "Could not determine window width. For the best experience, use a Powershell window instead of ISE"
        $Output | Format-Table
    }
    ElseIf ($ActualWindowWidth -Lt $RequiredWindowWidth) {
        # Narrower window, Format-List
        Write-Warning "For the best experience, try making your PowerShell window at least $RequiredWindowWidth characters wide. Current width is $ActualWindowWidth characters."
        $Output | Format-List
    }
    Else {
        # Wider window, Format-Table
        $Output | Format-Table
    }
}

Get-VirtualDiskFootprintByStorageFaultDomain