Delimita l'allocazione dei volumi in Spazi di archiviazione diretta

Si applica a: Windows Server 2022, Windows Server 2019

Windows Server 2019 introduce un'opzione per delimitare manualmente l'allocazione dei volumi in Spazi di archiviazione diretta. In questo modo è possibile aumentare significativamente la tolleranza di errore in determinate condizioni, ma impone alcune considerazioni di gestione e complessità aggiunte. Questo argomento illustra il funzionamento e fornisce esempi in PowerShell.

Importante

Questa funzionalità è una novità di Windows Server 2019. Non è disponibile in Windows Server 2016.

Prerequisiti

Green checkmark icon. Prendere in considerazione l'uso di questa opzione se:

Red X icon. Non usare questa opzione se:

Informazioni generali

Revisione: allocazione regolare

Con il mirroring a tre vie regolare, il volume è suddiviso in molte piccole "lastre" copiate tre volte e distribuite uniformemente in ogni unità in ogni server del cluster. Per altri dettagli, leggere questo blog di approfondimento.

Diagram showing the volume being divided into three stacks of slabs and distributed evenly across every server.

Questa allocazione predefinita ottimizza le letture e le scritture parallele, causando prestazioni migliori ed è interessante nella sua semplicità: ogni server è ugualmente occupato, ogni unità è ugualmente piena e tutti i volumi rimangono online o vanno offline insieme. Ogni volume è garantito di sopravvivere fino a due errori simultanei, come illustrato in questi esempi .

Tuttavia, con questa allocazione, i volumi non possono sopravvivere a tre errori simultanei. Se tre server hanno esito negativo contemporaneamente o se le unità in tre server hanno esito negativo contemporaneamente, i volumi diventano inaccessibili perché almeno alcune lastre erano (con probabilità molto elevata) allocate alle tre unità o ai server che hanno avuto esito negativo.

Nell'esempio seguente i server 1, 3 e 5 hanno esito negativo contemporaneamente. Anche se molte lastre hanno copie sopravvissute, alcune non:

Diagram showing three of six servers highlighted in red, and the overall volume is red.

Il volume diventa offline e diventa inaccessibile fino a quando i server non vengono ripristinati.

Nuovo: allocazione delimitata

Con l'allocazione delimitata, si specifica un subset di server da usare (almeno quattro). Il volume è suddiviso in lastre copiate tre volte, come prima, ma invece di allocare in ogni server, le lastre vengono allocate solo al subset di server specificato.

Ad esempio, se si dispone di un cluster a 8 nodi (nodi da 1 a 8), è possibile specificare un volume da individuare solo su dischi nei nodi 1, 2, 3, 4.

Vantaggi

Con l'allocazione di esempio, è probabile che il volume superi tre errori simultanei. Se i nodi 1, 2 e 6 si arrestano, solo 2 dei nodi che contengono le 3 copie di dati per il volume sono inattivo e il volume rimarrà online.

La probabilità di sopravvivenza dipende dal numero di server e da altri fattori. Per informazioni dettagliate, vedere Analisi .

Svantaggi

L'allocazione delimitata impone alcune considerazioni e complessità aggiuntive per la gestione:

  1. L'amministratore è responsabile della delimitazione dell'allocazione di ogni volume per bilanciare l'utilizzo dello spazio di archiviazione tra server e mantenere alta probabilità di sopravvivenza, come descritto nella sezione Procedure consigliate.

  2. Con l'allocazione delimitata, riservare l'equivalente di un'unità di capacità per ogni server (senza limite massimo). Si tratta di più della raccomandazione pubblicata per l'allocazione regolare, che supera il totale di quattro unità di capacità.

  3. Se un server ha esito negativo e deve essere sostituito, come descritto in Rimuovere un server e le relative unità, l'amministratore è responsabile dell'aggiornamento del delimitazione dei volumi interessati aggiungendo il nuovo server e rimuovendo quello non riuscito, ad esempio riportato di seguito.

Utilizzo in PowerShell

È possibile usare il New-Volume cmdlet per creare volumi in Spazi di archiviazione diretta.

Ad esempio, per creare un normale volume mirror a tre vie:

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

Creare un volume e delimitarne l'allocazione

Per creare un volume mirror a tre vie e delimitarne l'allocazione:

  1. Assegnare prima di tutto i server nel cluster alla variabile $Servers:

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

    Suggerimento

    In Spazi di archiviazione diretta, il termine "unità di scala Archiviazione" si riferisce a tutte le risorse di archiviazione non elaborate collegate a un server, incluse le unità collegate direttamente e le enclosure esterne collegate direttamente con unità. In questo contesto è uguale a "server".

  2. Specificare i server da usare con il nuovo -StorageFaultDomainsToUse parametro e indicizzandoli in $Servers. Ad esempio, per delimitare l'allocazione al primo, secondo, terzo e quarto server (indici 0, 1, 2 e 3):

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

Visualizzare un'allocazione delimitata

Per informazioni sull'allocazione di MyVolume, usare lo script nell'AppendiceGet-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

Si noti che solo Server1, Server2, Server3 e Server4 contengono lastre di MyVolume.

Modificare un'allocazione delimitata

Usare i cmdlet e nuovi Add-StorageFaultDomainRemove-StorageFaultDomain per modificare la modalità di delimitazione dell'allocazione.

Ad esempio, per spostare MyVolume su un server:

  1. Specificare che il quinto server può archiviare le lastre di MyVolume:

    Get-VirtualDisk MyVolume | Add-StorageFaultDomain -StorageFaultDomains $Servers[4]
    
  2. Specificare che il primo server non può archiviare le lastre di MyVolume:

    Get-VirtualDisk MyVolume | Remove-StorageFaultDomain -StorageFaultDomains $Servers[0]
    
  3. Ribilanciare il pool di archiviazione per rendere effettiva la modifica:

    Get-StoragePool S2D* | Optimize-StoragePool
    

È possibile monitorare lo stato di avanzamento del ribilanciamento con Get-StorageJob.

Al termine, verificare che MyVolume sia stato spostato di nuovo eseguendo Get-VirtualDiskFootprintBySSU.ps1 di nuovo.

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

Si noti che Server1 non contiene più lastre di MyVolume , ma Server5.

Procedure consigliate

Di seguito sono riportate le procedure consigliate da seguire quando si usa l'allocazione di volumi delimitati:

Scegliere quattro server

Delimitare ogni volume mirror a tre vie su quattro server, non più.

Bilanciare l'archiviazione

Bilanciare la quantità di spazio di archiviazione allocato a ogni server, tenendo conto delle dimensioni del volume.

Sfalsa volumi di allocazione delimitati

Per ottimizzare la tolleranza di errore, rendere univoca l'allocazione di ogni volume, ovvero non condivide tutti i server con un altro volume (alcune sovrapposizioni sono ok).

Ad esempio, in un sistema a otto nodi: Volume 1: Server 1, 2, 3, 4 Volume 2: Server 5, 6, 7, 8 Volume 3: Server 3, 4, 5, 6 Volume 4: Server 1, 2, 7, 8

Analisi

Questa sezione deriva la probabilità matematica che un volume rimanga online e accessibile (o in modo equivalente, la frazione prevista di archiviazione complessiva che rimane online e accessibile) come funzione del numero di errori e delle dimensioni del cluster.

Nota

Questa sezione è la lettura facoltativa. Se sei interessato a vedere la matematica, leggi! In caso contrario, non preoccuparti: l'utilizzo in PowerShell e le procedure consigliate è sufficiente implementare correttamente l'allocazione delimitata.

Fino a due errori è sempre ok

Ogni volume mirror a tre vie può sopravvivere fino a due errori contemporaneamente, indipendentemente dall'allocazione. Se due unità hanno esito negativo o due server hanno esito negativo o uno di ognuno, ogni volume mirror a tre vie rimane online e accessibile, anche con allocazione regolare.

Oltre la metà del cluster che ha esito negativo non va mai bene

Viceversa, nel caso estremo in cui più della metà dei server o delle unità del cluster non riescano contemporaneamente, il quorum viene perso e ogni volume mirror a tre vie diventa offline e diventa inaccessibile, indipendentemente dall'allocazione.

Che ne dici tra?

Se si verificano tre o più errori contemporaneamente, ma almeno la metà dei server e le unità sono ancora inattivi, i volumi con allocazione delimitata possono rimanere online e accessibili, a seconda dei server in cui si verificano errori.

Domande frequenti

È possibile delimitare alcuni volumi, ma non altri?

Sì. È possibile scegliere per volume se delimitare o meno l'allocazione.

L'allocazione delimitata cambia il funzionamento della sostituzione delle unità?

No, è identico a quello dell'allocazione regolare.

Riferimenti aggiuntivi

Appendice

Questo script consente di vedere come vengono allocati i volumi.

Per usarlo come descritto in precedenza, copiare/incollare e salvare come 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