Condividi tramite


Delimitare l'allocazione dei volumi in Spazi di archiviazione diretta

Windows Server 2019 introduce un'opzione per delimitare manualmente l'allocazione dei volumi in Spazi di archiviazione diretta. Questo approccio consente di aumentare significativamente la tolleranza di errore in determinate condizioni, ma impone alcune considerazioni aggiuntive sulla gestione e la complessità. 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

Icona segno di spunta verde. Prendere in considerazione l'uso di questa opzione se:

  • Il cluster include sei o più server e
  • Il cluster usa solo la resilienza con mirroring a tre vie

Icona X rossa. Non usare questa opzione se:

Informazioni generali

Revisione: allocazione regolare

Con il mirroring a tre vie regolare, il volume è suddiviso in molte piccole "allocazioni memoria" copiate tre volte e distribuite uniformemente in ogni unità in ogni server del cluster. Per altre informazioni, vedere questo blog di approfondimento.

Diagramma che mostra il volume diviso in tre stack di lastre e distribuito uniformemente in ogni server.

Questa allocazione predefinita ottimizza le letture e le scritture parallele offrendo quindi 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. È garantita la sopravvivenza di ogni volume per un massimo di due errori simultanei, come illustrato in questi esempi.

Con questa allocazione i volumi non possono tuttavia sopravvivere a tre errori simultanei. Se si verificano errori contemporaneamente in tre server o nelle unità in tre server, i volumi diventano inaccessibili perché almeno alcune allocazioni memoria erano molto probabilmente allocate esattamente alle tre unità o ai server in cui si sono verificati gli errori.

Nell'esempio seguente si verificano contemporaneamente errori nei server 1, 3 e 5. Anche se sono presenti copie sopravvissute per molte allocazioni, tali copie non sono disponibili per altre:

Diagramma che mostra tre server evidenziati in rosso e il volume complessivo è rosso.

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

Novità: allocazione delimitata

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

Se ad esempio è presente un cluster a 8 nodi (nodi da 1 a 8), è possibile specificare un volume da posizionare 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 inattivi 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 un'alta probabilità di sopravvivenza, come descritto nella sezione Procedure consigliate.

  2. Con l'allocazione delimitata, riservare l'equivalente di un'unità di capacità per server (senza limite massimo). Questo valore è superiore alla raccomandazione pubblicata per l'allocazione regolare, che consente al massimo un totale di quattro unità di capacità.

  3. Se si verifica un errore in un server ed è necessario sostituirlo, come descritto in Rimuovere un server e le relative unità, l'amministratore è responsabile dell'aggiornamento del delimitazione dei volumi interessati mediante l'aggiunta del nuovo server e la rimozione del server con errori, come illustrato nell'esempio seguente.

Utilizzo in PowerShell

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

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

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

Creare un volume e delimitarne l'allocazione

Per creare un volume con mirroring 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 di archiviazione" si riferisce a tutte le risorse di archiviazione non elaborate collegate a un server, incluse le unità collegate direttamente e gli alloggiamenti esterni collegati direttamente con le unità. In questo contesto è uguale a "server".

  2. Specificare i server da usare con il nuovo parametro -StorageFaultDomainsToUse 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 vedere come viene allocato MyVolume, usare lo script Get-VirtualDiskFootprintBySSU.ps1 nell'Appendice:

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 allocazioni memoria di MyVolume.

Modificare un'allocazione delimitata

Usare i nuovi cmdlet Add-StorageFaultDomain e Remove-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 allocazioni memoria di MyVolume:

    Get-VirtualDisk MyVolume | Add-StorageFaultDomain -StorageFaultDomains $Servers[4]
    
  2. Specificare che il primo server non può archiviare le allocazioni memoria 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 eseguendo di nuovo 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

Si noti che Server1 non contiene più allocazioni memoria di MyVolume, che si trovano invece in Server5.

Procedure consigliate

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

Scegliere quattro server

Delimitare ogni volume con mirroring a tre vie a un massimo di quattro server.

Bilanciare l'archiviazione

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

Sfalsare i volumi con allocazione delimitata

Per ottimizzare la tolleranza di errore, rendere univoca l'allocazione di ogni volume, in modo che non condivida tutti i server con un altro volume (qualche sovrapposizione è accettabile).

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 è una lettura facoltativa. Leggerla se si è interessati a esaminare il processo matematico. In caso contrario, non occorre preoccuparsi: tutte le informazioni necessarie per l'implementazione dell'allocazione delimitata sono disponibili in Utilizzo in PowerShell e Procedure consigliate.

Sono sempre consentiti fino a due errori

Ogni volume con mirroring a tre vie può sopravvivere a un massimo di due errori contemporaneamente, indipendentemente dall'allocazione. Se si verificano errori in due unità o in due server o in un'unità e un server, ogni volume con mirroring a tre vie rimane online e accessibile, anche con allocazione regolare.

Non è mai accettabile che si verifichino errori in più della metà del cluster

Viceversa, nel caso estremo in cui si verificano errori in più della metà dei server o delle unità nel cluster contemporaneamente, il quorum viene perso e ogni volume con mirroring a tre vie risulta offline e diventa inaccessibile, indipendentemente dall'allocazione.

Informazioni su scenari intermedi

Se si verificano tre o più errori contemporaneamente, ma almeno la metà dei server e delle unità rimane ancora attiva, 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 ogni 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