Wednesday, June 9, 2021

Migrating all regions in a multi-region Cosmos DB account to be each availability-zone redundant.

 

Introduction: 

Azure is the public cloud that offers CosmosDB as a resource for storing documents. This service is the equivalent of a global database for organizations that want to store semi-structured data. When the CosmosDB is provisioned as a singleton instance, it is hosted in a single region with read-and-write capabilities. This is made zone –redundant when there are multiple instances of the CosmosDB server each in separate zones so that if one fails, another can take over. All the instances from these zones behave the same way and there is no data loss between failovers. When the CosmosDB is provisioned in multiple regions, some instances can participate to be read-only while others can be provisioned to be write-only. It is possible to write to any one of the regions capable of taking writes and be able to read it from a read-only region. Provisioning such a multiple region accounts to be zone-redundant requires each of the regions to be zone-redundant. This article explains the steps to do so and the considerations to be made. 

Description: 

The difference between migrating a single region account to a zone redundant formation and a multiple region account that is migrating to its zone-redundancy is that those other regions may not all behave the same way. They may work in read-only or read-write modes and the account may display them in a list of regions corresponding to each of the sections titled Locations, Read Locations, and Write Locations in the summary information of its account.  

Powershell is a scripting language suitable for automation although it is not the only way for automating the migration of accounts from zonal to zone-redundant configurations. This example is described with the help of Powershell. The Powershell command to specify zone redundancy to the account takes only the LocationObject parameter for this purpose. The LocationObject can enumerate all the regions that the CosmosDB is hosted on, but it does not differentiate between read-and-write regions. There are no other parameters or options to specify separate lists for read-locations and write-locations so it may come across as difficult to differentiate between the regions in the consolidated list. 

The List of regions to migrate could come from the account users but if the automation were to automatically migrate the account in place, it needs to make a few decisions itself. Certainly, all regions can be enabled for zone-redundancy. There is a cost aspect but without the information for the user, let us see what the tradeoffs are in converting more regions than the primary to be zone redundant.  

If the write regions are more than one, this means the account allows database access directly to those regions for read-and-write and distribute the traffic geographically. Each such region appears as its own instance to its users. Syncing data across regions is costly, so converting the write-regions to do sync over low latency networks reduces the cost while improving the redundancy. Enabling the redundancy on each write-region increases billing as a matter of policy but technically it reduces cost in comparison to cross-region replication.  The read regions anyways rely on replication so the choice of converting them to zone–redundant regions rely exclusively on the customers' acceptance of the billing increase. The priority for automation has always been to secure the additional write regions with the read regions following next. 

The steps to convert the regions involve the use of the Locations list and the Write-Locations List to determine the difference that can be treated as read-regions. We start with a locations list that has just the primary and toggle the boolean option to convert all regions in the account to be write-only. Then we incrementally add each region with the zone-redundancy flag set to true. As each of the write-regions are added, they are all set with zone-redundancy and to support writes. Then the primary region is removed and added back with the zone-redundancy set. This converts all the write-regions including the primary to be zone-redundant. The adding and removing of a region is a requirement to turning on the zone-redundancy for that region. The priority order of the write regions can be fixed to be in the same order as the original configuration.  Then the flag for specifying all regions to be write-only can be disabled. This makes subsequent region additions to be read regions. The list of regions that need to be read regions is already known at this point. So, they are iteratively added back to the new configuration one by one and enabling the zone redundancy.  

This makes the automation to migrate an account to zone redundancy easy by starting with a Location Object that has only one region as write-only even if it not zone-redundant, adding it back between write regions and read regions, and taking all the other regions incrementally with the redundant zone option specified. Testing for this fix is just as easy as the automation because we have either all the cases covered under three categories - single, mixed, and all regions as write. CosmosDB is never provisioned without at least one write-region so we start out with at least one. Lastly, it must be called out that specifying zone redundant option on regions may throw an error it does not support availability zone redundancy. Older regions are known to be so. Therefore, the flag to set the redundancy must be specified as true only when the region supports it and false otherwise.  The net effect of all these steps is that the older configuration of separate read and write regions are maintained but each of them now has cheap and cost-effective availability zone-redundancy set to true. 



Tuesday, June 8, 2021

 Introduction: This is a continuation of the article on the Azure Redis Cache which is available here. The option of improving the zone redundancy requires replicas to be placed in different availability zones. A region supports three availability zones, and it is possible to spread the replicas over the availability zone when creating a new instance. This article delves into the options available to transfer the cache entries from an existing non-redundant AZ-server to the AZ-server. 

Solution: The standard configuration of a Redis server comes with a primary and a secondary server even if they are placed in the same datacenter. A geographical region consists of multiple zones and a zone consists of multiple datacenters, and the standard configuration does not have geo-redundancy.  It has replication built-in so that technique is applicable across any scope and between Redis instances as well.  When two Redis servers make use of the replication this way, they are said to be linked. When the servers are linked, only one can take writes, which is the source of the link and not the target. When a manual failover occurs, the link must be broken before the target can be made the primary. The writes are always in one place even if there is connection forwarding. We don’t discuss clustered options in linking because the shard count can vary between the source and the target of the link, which prevents replication.

The other option requires the import and export of data, and this has the added benefit of not being governed by configurations and topology of the data import and export. This option requires a storage account for the data to be exported and imported. The data is usually in the format of RDB and the manner of the import is the same as new entries being set in the cache. Each export is a full backup of the data in RDB format which means that there are no incremental changes, unlike AOF-based persistence.  Although data can be periodically exported, the export-import is usually one time and at the beginning of the use of the new server. When the data is imported more than once, the old entries from the previous import are not overwritten and the new entries are added.  Time to the expiry of the objects is not reset in the new server.

 

Comparisions of these two options can be summarized as follows:

Feature

Linking based replication

Export-Import based replication

Works for standalone non-AZ server to non-AZ server

yes

yes

Works for standalone non-AZ server to non-AZ server with RDB persistence

yes

yes

Works for non-AZ to AZ-redundant data transfer

no

yes

Works for server with persistence

no

yes

Works for server with AOF persistence

no

yes

Works for server with clustered option

no

yes

Has no dataloss

yes

no (upto 15 mins depending on the size of the cache)

Requires premium subscription

yes

yes

 

 

Monday, June 7, 2021

 One of the advantages of the method discussed on June  4th is that it converts all regions to write-regions if there were more than one of them to begin with. The justification is that the earlier configuration continues to operate in the same manner as new regions serve in write mode also. 

If the original configuration needs to be the same as the old one, then we do have the option of incrementally adding all the write regions first while the flag for EnableMultipleWriteLocations is set to true. Then, when adding the read regions, the flag can be set to false. This allows all the remaining regions of the old configuration to be correctly added back as the read region. The net effect is that we move the toggling of the EnableMultipleWriteLocations switch earlier than the last step.

The new script looks something like this:

param (

    [Parameter(Mandatory=$true)][string]$resourceGroupName,

    [Parameter(Mandatory=$true)][string]$accountName,

    [Parameter(Mandatory=$true)][string]$subscriptionId,

    [string]$environment = "AzureCloud"

)

 

function supportsZoneRedundancy {

    param (

        $regionName

    )

    $zonalRegions = @("West Central US", "Switzerland North", "UAE North", "UK West", "Norway East", "Korea Central", "East Asia", "Australia Central", "Australia Southeast", "Japan West", "Korea South", "West US", "Jio India West", "Central US EUAP", "Central US")

    $zoneRedundantRegions = @("East US", "East US 2", "North Europe", "Southeast Asia", "Japan East", "East US 2 EUAP", "Brazil South", "Canada Central", "West US 2", "France Central", "Korea Central", "Central India", "South Africa North", "West Europe", "Germany West Central", "UK South", "South Central US", "West US 3")

    $setZoneRedundancy = $False

    if ($zoneRedundantRegions.Where({$_ -eq $regionName}).Count -eq 1) {

        $setZoneRedundancy = $True

    } else {

        Write-Host $regionName does not support zone redundancy

    }

    return $setZoneRedundancy

}

 

Write-Host Multi-region account migration to AZ-Readiness begin

Connect-AzAccount -Environment "$environment"

Set-AzContext -SubscriptionId "$subscriptionId"

 

$dbs = Get-AzCosmosDBAccount -ResourceGroupName $resourceGroupName -Name $accountName -ErrorAction Stop

 

foreach ($db in $dbs) {

 

if ($db.Locations.Count -eq 1) {

   Write-Host This script cannot be used for single-region account.

   exit

}

 

$oldWriteAll = $db.EnableMultipleWriteLocations

if ($db.EnableMultipleWriteLocations -eq $True) {

    Update-AzCosmosDBAccount `

      -ResourceGroupName $resourceGroupName `

      -Name $accountName `

      -EnableMultipleWriteLocations $False `

      -ErrorAction Stop

}

 

$locations = @()

$oldLocations = @()

$oldPriority = 0

$priority = 0

Write-Host Processing Write regions first for AZ readiness

Update-AzCosmosDBAccount `

  -ResourceGroupName $resourceGroupName `

  -Name $accountName `

  -EnableMultipleWriteLocations $True `

  -ErrorAction Stop

 

for ($i = 0; $i -lt $db.WriteLocations.Count; $i = $i + 1) {

    if ($i -eq 0) {

        $locations += New-AzCosmosDBLocationObject -LocationName $db.Locations[$i].LocationName -FailOverPriority $db.Locations[$i].FailoverPriority -IsZoneRedundant $db.Locations[$i].IsZoneRedundant

        $oldPriority = $db.Locations[$i].FailoverPriority

    }

    $oldLocations += New-AzCosmosDBLocationObject -LocationName $db.Locations[$i].LocationName -FailOverPriority $db.Locations[$i].FailoverPriority -IsZoneRedundant $db.Locations[$i].IsZoneRedundant

}

 

Write-Host before doing anything

Write-Host Incrementally adding back each region with AZ readiness on

Update-AzCosmosDBAccountRegion `

    -ResourceGroupName $resourceGroupName `

    -Name $accountName `

    -LocationObject $locations `

    -ErrorAction Stop

 

for ($i = 1; $i -lt $oldLocations.Count; $i = $i + 1) {

$setZoneRedundancy = supportsZoneRedundancy $oldLocations[$i].LocationName

$locations += New-AzCosmosDBLocationObject -LocationName $oldLocations[$i].LocationName -FailOverPriority $oldLocations[$i].FailoverPriority -IsZoneRedundant $setZoneRedundancy

Update-AzCosmosDBAccountRegion `

    -ResourceGroupName $resourceGroupName `

    -Name $accountName `

    -LocationObject $locations `

    -ErrorAction Stop

}

 

$failoverlocations = @()

$priority = 0

for ($i = 1; $i -lt $oldLocations.Count; $i = $i + 1) {

$priority = $i - 1

$setZoneRedundancy = supportsZoneRedundancy $oldLocations[$i].LocationName

$failoverlocations += New-AzCosmosDBLocationObject -LocationName $oldLocations[$i].LocationName -FailOverPriority $priority -IsZoneRedundant $setZoneRedundancy

}

 

Update-AzCosmosDBAccountRegion `

    -ResourceGroupName $resourceGroupName `

    -Name $accountName `

    -LocationObject $failoverlocations `

    -ErrorAction Stop

 

Write-Host Converting the default region to have AZ readiness

$setZoneRedundancy = supportsZoneRedundancy $oldLocations[0].LocationName

$priority = $failoverlocations.Count

$failoverlocations += New-AzCosmosDBLocationObject -LocationName $oldLocations[0].LocationName -FailOverPriority $priority -IsZoneRedundant $setZoneRedundancy

Update-AzCosmosDBAccountRegion `

    -ResourceGroupName $resourceGroupName `

    -Name $accountName `

    -LocationObject $failoverlocations `

    -ErrorAction Stop

 

Update-AzCosmosDBAccount `

  -ResourceGroupName $resourceGroupName `

  -Name $accountName `

  -EnableMultipleWriteLocations $False `

  -ErrorAction Stop

 

Write-Host Processing Read Regions next for AZ readiness

$oldLocations = @()

for ($i = $locations.Count; $i -lt $db.Locations.Count; $i = $i + 1) {

    $oldLocations += New-AzCosmosDBLocationObject -LocationName $db.Locations[$i].LocationName -FailOverPriority $db.Locations[$i].FailoverPriority -IsZoneRedundant $db.Locations[$i].IsZoneRedundant

}

$priority = $locations.Count

for ($i = 0; $i -lt $oldLocations.Count; $i = $i + 1) {

$setZoneRedundancy = supportsZoneRedundancy $oldLocations[$i].LocationName

$locations += New-AzCosmosDBLocationObject -LocationName $oldLocations[$i].LocationName -FailOverPriority $priority -IsZoneRedundant $setZoneRedundancy

$priority = $priority + 1

}

 

Write-Host all regions as per old configuration added

Write-Host retaining order of failover priority as per original configuration next

$oldLocations = @()

for ($i = 0; $i -lt $db.Locations.Count; $i = $i + 1) {

    $oldLocations += New-AzCosmosDBLocationObject -LocationName $db.Locations[$i].LocationName -FailOverPriority $db.Locations[$i].FailoverPriority -IsZoneRedundant $db.Locations[$i].IsZoneRedundant

}

 

$regions = @()

foreach ($l in $oldLocations){$regions += $l.LocationName}

Update-AzCosmosDBAccountFailoverPriority  `

    -ResourceGroupName $resourceGroupName `

    -Name $accountName `

    -FailoverPolicy $regions `

    -ErrorAction Stop

 

Write-Host Ensuring EnableMultipleWriteLocations Setting remains so

Update-AzCosmosDBAccount `

  -ResourceGroupName $resourceGroupName `

  -Name $accountName `

  -EnableMultipleWriteLocations $oldWriteAll `

  -ErrorAction Stop

 

}

Write-Host CosmosDB multi-region account is now AZ-Ready


/* Testing:

Multi-region account migration to AZ-Readiness begin

 

 

Id                : ravirajamani-test-zone-down-eastus2

LocationName      : East US 2

DocumentEndpoint  : https://ravirajamani-test-zone-down-eastus2.documents.azure.com:443/

ProvisioningState : Succeeded

FailoverPriority  : 0

IsZoneRedundant   : True

 

Id                : ravirajamani-test-zone-down-eastus

LocationName      : East US

DocumentEndpoint  : https://ravirajamani-test-zone-down-eastus.documents.azure.com:443/

ProvisioningState : Succeeded

FailoverPriority  : 1

IsZoneRedundant   : False

 

Processing Write regions first for AZ readiness

Update-AzCosmosDBAccount -ResourceGroupName ravirajamani_test_rg -Name ravirajamani-test-zone-down -EnableMultipleWriteLocations True

LocationName     : East US 2

FailoverPriority : 0

IsZoneRedundant  : True

 

before doing anything

Incrementally adding back each region with AZ readiness on

Update-AzCosmosDBAccountRegion -ResourceGroupName ravirajamani_test_rg -Name ravirajamani-test-zone-down -LocationObject Microsoft.Azure.Commands.CosmosDB.Models.PSLocation

Update-AzCosmosDBAccountRegion -ResourceGroupName ravirajamani_test_rg -Name ravirajamani-test-zone-down -LocationObject

Converting the default region to have AZ readiness

Update-AzCosmosDBAccountRegion -ResourceGroupName ravirajamani_test_rg -Name ravirajamani-test-zone-down -LocationObject Microsoft.Azure.Commands.CosmosDB.Models.PSLocation

Update-AzCosmosDBAccount -ResourceGroupName ravirajamani_test_rg -Name ravirajamani-test-zone-down -EnableMultipleWriteLocations False

LocationName     : East US 2

FailoverPriority : 0

IsZoneRedundant  : True

 

Processing Read Regions next for AZ readiness

LocationName     : East US 2

FailoverPriority : 0

IsZoneRedundant  : True

 

LocationName     : East US

FailoverPriority : 1

IsZoneRedundant  : True

 

all regions as per old configuration added

retaining order of failover priority as per original configuration next

LocationName     : East US 2

FailoverPriority : 0

IsZoneRedundant  : True

 

LocationName     : East US

FailoverPriority : 1

IsZoneRedundant  : False

 

Update-AzCosmosDBAccountFailoverPriority -ResourceGroupName ravirajamani_test_rg -Name ravirajamani-test-zone-down -FailoverPolicy East US 2 East US

Ensuring EnableMultipleWriteLocations Setting remains so

Update-AzCosmosDBAccount -ResourceGroupName ravirajamani_test_rg -Name ravirajamani-test-zone-down -EnableMultipleWriteLocations False

CosmosDB multi-region account is now AZ-Ready

*/


Sunday, June 6, 2021

 A cluster cache implementation: 

A cluster mode implementation comes with the primary benefit of horizontally scaling up or down the Redis cluster with little or no impact to performance. A single Redis server is usually constrained by the size of the memory on the host. Since it is an in-memory key-value store, it requires memory to determine the provisioning of its store. If the memory is not adequate, the server can be over-provisioned and if it too large it can be under-provisioned. Writing to more than one server is always possible but a cluster mode allows us to write once and scale horizontally without requiring the application to iterate through distinct servers each time. 

This cluster mode involves 0-5 replicas per primary server for each shard. It requires both data partitioning and replication as opposed to a configuration with a single shard, one primary server, and its replicas. Adding and removing shards and node rebalance occur during horizontal scaling. There can be up to 90 shards in the cluster. One of the advantages of the cluster is that it can deploy over multiple availability zones. A Cluster-Mode can scale to enormous amounts of storage (potentially 100s of terabytes) across up to 90 shards. 

Cluster Mode also allows for more flexibility when designing new workloads with unknown storage requirements or heavy write activity. In a read-heavy workload, we can scale a single shard by adding read replicas, up to five, but a write-heavy workload can benefit from additional write endpoints when cluster mode is enabled. 

Redis leverages a form of sharding in which every cache key is mapped to a “hash slot.” Within the cluster, there are 16,384 hash slots available. Those slots are divided amongst the total number of shards in the cluster. By default, all the shards are equally distributedalthough this could also be customized with a distribution scheme if required. 

When writing or reading data to the cluster, the client will calculate which hash slot to use via a simple algorithm: CRC16(key) mod 16384. In the case of clustering over Redis servers, the client could itself determine which shard to use based on the keyspace. The cluster avoids becoming a single point of failure and the client is allowed to reach any shard in the cluster. When an initial connection is made to the Redis cluster, the client could resolve and manage a keyspace mapping that can be used to identify on which node a particular hash key can be found. 

The clusters can be spread across multiple Availability-Zones (multi-AZs) which improves their handling of fault and update zones. When the cluster is set up, it could be defined to have auto-failover with Multiple Availability zone redundancy. The allocation of nodes by the cluster spans availability zones when the cluster is aware of the zones to deploy. This could be round-robin or user-specified.  

 

Saturday, June 5, 2021

 Improving resiliency and predictability of Powershell automation scripts.

PowerShell is a convenient scripting language for interactive use and automations. There are several features available to use with the automation. These include the following:

- The use of common parameters called –ErrorAction and –ErrorVariables

- The use of try-catch-finally 

- The use of staged or pipelined operations

- The use of state persistence for rollback and recovery

As we discuss these options, it may be opportune to call out the requirements first. Scripts generally have more than one cmdlet invocations and they need to be able to revert to the original starting state if any of the steps fail. Certain exceptions might be tolerated others might be fatal and these would need to be aligned with the overall starting and end states for the script. The use case for evaluating the options above remains one where we can revert to the starting state before the execution of the script.

The ErrorAction is a common parameter across all cmdlets. It can have one of four values - Stop, Continue, SilentlyContinue and Inquire. The error variable stores errors from the command during processing. This is atleast helpful to halt the processing when a step cannot be completed but the changes may have already occurred that need to be undone. Testing for the error variable and taking the appropriate steps would be one option to address the case.

The try-catch-finally is a useful construct across both programming as well as scripting. The catch handler allows the appropriate handling of the rollback. Additionally, more than one catch can be used based on the type of the exception that is handled. 

The staged or the pipelined operations involves leaving more than one intermediate results so the reversals can be worked out from one known result to another. This is easily determined because the path between the stages is like an automata. It is easy to go back and forth between stages or progressively cycle through the stages.

The last option does not involve the interim results of execution but relies on states because they are smaller and easier to store in the form of variables rather than have all the information of the starting, ending or intermediate results or processing actions. Testing for a state variable alone is sufficient to determine the corrective action. For example, a work item can transition from initialized, in progress, completed or error and the next retry can be triggered via reverting to the initialized.

All these options can be tried out for the cheapest and most convenient one  to use in the application and they can perform deterministically each time.


Friday, June 4, 2021

 Automating multi region cosmos db account to be availability zone redundnant.

Introduction: Azure is the public cloud that offers CosmosDB as a resource for storing documents. This service is the equivalent of a global database for organizations that want to store semi-structured data. When the CosmosDB is provisioned as a singleton instance, it is hosted in a single region with read and write capabilities. This is made zone –redundant when there are multiple instances of the CosmosDB server each in separate zones so that if one fails, another can take over. All the instances from these zones behave the same way and there is no data loss between failovers. When the CosmosDB is provisioned in multiple regions, some instance can participate to be read-only while others can be provisioned to be write-only. It is possible to write to any one of the regions capable of taking writes and be able to read it from a read only region. Provisioning such a multiple region account to be zone-redundant requires each of the regions to be zone-redundant. This article explains the steps to do so and the considerations to be made.

Description: The difference between migrating a single region account to a zone redundant formation and a multiple region account that is migrating to its zone-redundancy is that those other regions may not all behave the same way. They may work in read only or read-write modes and the account may display them in a list of regions corresponding to each of the sections titled Locations, Read Locations, and Write Locations in the summary information of its account. 

Powershell is a scripting language suitable for automations although it is not the only way for automating the migration of accounts from zonal to zone-redundant configurations. This example is described with the help of Powershell. The Powershell command to specify zone redundancy to the account takes only the LocationObject parameter for this purpose. The LocationObject can enumerate all the regions that the CosmosDB is hosted on but it does not differentiate between read and write regions. There are no other parameters or options to specify separate lists for read locations and write locations so it may come across as difficult to differentiate between the regions in the consolidated list.

Fortunately, the configuration is usually none or all for writes. This means that a single region will take write requests from the clients, or all the regions can be configured to take write requests. The latter is specified with the help of a boolean variable for the whole account and is represented at the same level as the Locations Object on the account. Specifying this flag implies that there are no read-only regions and if it is absent, there is only one region that is write while all the others are read only. It is possible to have any write regions as well as many read regions. 

This makes the automation to migrate an account to zone redundancy easy by starting with a Location Object that has only one region as write-only even if it not zone-redundant and taking all the other regions incrementally with the redundant zone option specified. Finally, the conversion of the single write-region can be migrated to zone-redundant formation in the same way as for a single region account. If the boolean option for all regions to be write based was originally specified, it can be added back to the account.

Testing for this fix is just as easy as the automation because we have either all the cases covered under three categories -  single, mixed and all regions. Ensuring that there are no regions that are read-only is guaranteed because a CosmosDB is never provisioned without one write region. Lastly, it must be called out that specifying zone redundant option on regions may throw an error if the region is not removed and added back.  This fits in nicely with the steps that have been taken.


Thursday, June 3, 2021

Using Azure cache for Redis continued ...

 Introduction: This article describes the two approaches to transfering data between redis servers.

param (

    [Parameter(Mandatory=$true)][string]$environment,

    [Parameter(Mandatory=$true)][string]$subscriptionId,

    [Parameter(Mandatory=$true)][string]$resourceGroupName,

    [Parameter(Mandatory=$true)][string]$storageAccount

)

Write-Host Script begin

Write-Host Connecting to Azure

Connect-AzAccount -Environment $environment -ErrorAction Stop

Write-Host Connected to Azure

 

Write-Host Setting context to Subscription: $subscriptionId

Set-AzContext -subscriptionId $subscriptionId -ErrorAction Stop

Write-Host Context switched to Subscription: $subscriptionId

 

$caches = Get-AzRedisCache -ResourceGroupName $resourceGroupName

foreach ($cache in $caches) {

   if ($cache.Zone -eq $null) {

       Write-Host Migrating $cache.Name to be Az ready

       $zones = @()

       $zones += "1"

       $zones += "2"

       $zones += "3"

 

       if ($cache.RedisConfiguration -eq $null) {

           $cache.RedisConfiguration = @{}

       }

 

       $cache.RedisConfiguration["rdb-backup-enabled"] = $False

       $newCacheName = $cache.Name+"-AzReady"

       $sku = "Premium"

 

       New-AzRedisCache `

          -ResourceGroupName $resourceGroupName `

          -Name $newCacheName `

          -Location $cache.Location `

          -Size $cache.Size   `

          -Sku $sku   `

          -Zone $zones  `

          -RedisConfiguration $cache.RedisConfiguration `

          -ErrorAction Stop

 

        $newCache = Get-AzRedisCache -ResourceGroupName $resourceGroupName -Name $newCacheName

        while (-not ($newCache.ProvisioningState -eq "Succeeded")) {

            Write-Host "Sleeping 5 seconds for new cache to be provisioned."

            Start-Sleep -Seconds 5

            $newCache = Get-AzRedisCache -ResourceGroupName $resourceGroupName -Name $newCacheName

        }

 

        <# We have an AZ redundant server now, it does not have the same data yet.

        # The link based replication would be fast but it does not work with AZ redundant Redis server.

        New-AzRedisCacheLink `

          -PrimaryServerName $cache.Name  `

                    -SecondaryServerName $newCacheName  `

          -ErrorAction Stop

      

        Remove-AzRedisCacheLink `

          -PrimaryServerName $cache.Name `

          -SecondaryServerName $newCacheName `

          -ErrorAction Stop

        #>

 

        <#

         # Instead we import and export data

         #>

         Export-AzRedisCache `

         -ResourceGroupName $resourceGroupName `

         -Name $oldCache.Name -Prefix "export-" `

         -Container $storageAccount

 

         Import-AzRedisCache `

         -ResourceGroupName $resourceGroupName `

         -Name $newCacheName -Files @($storageAccount) -Force

 

         Write-Host New cache $newCacheName is AZ-Ready and replicated from existing.

   }

}

Write-Host Script end