# Data Replication Patterns for AI Systems

**Last updated:** 2026-02
**Status:** GA
**Category:** Business Continuity & Disaster Recovery

---

## Introduksjon

Datareplikering er fundamentet for Business Continuity i AI-systemer. AI-arbeidsbelastninger har spesielle krav til datakonsistens, latens og tilgjengelighet som gjør valg av replikasjonsmekanisme særlig viktig. En RAG-løsning må for eksempel replikere både search-indekser, embedding-vektorer, kildedokumenter og konversasjonshistorikk — hver med ulike konsistens- og latensbehov.

Azure tilbyr flere replikasjonsmønstre: synkron replikering innenfor tilgjengelighetssoner (Availability Zones), asynkron geo-replikering til sekundærregioner, og applikasjonsbasert replikering for tjenester som ikke har innebygd DR. Valget mellom disse mønstrene påvirker direkte RPO, ytelse og kostnad.

For norsk offentlig sektor er det spesielt viktig å forstå data residency-implikasjoner av geo-replikering. Replikering til en sekundærregion må skje innenfor godkjente geografiske grenser (EU/EØS), og organisasjonen må dokumentere dataflyter i sine behandlingsprotokoll iht. GDPR artikkel 30.

## Synkron vs. asynkron replikering

### Synkron replikering

Ved synkron replikering bekreftes ikke en skriveoperasjon som fullført før dataene er skrevet til alle replikaer. Dette gir null datatap (RPO = 0), men øker skrivelatens.

| Egenskap | Synkron | Asynkron |
|----------|---------|----------|
| RPO | 0 | > 0 (sekunder til minutter) |
| Skrivelatens | Høyere (avhenger av avstand) | Lavere |
| Leseytelse | Kan lese fra replikaer | Kan lese fra replikaer (eventual consistency) |
| Kostnad | Høyere (alltid aktive replikaer) | Lavere |
| Typisk bruk | Intra-region (AZ), mission critical | Cross-region DR |

### Azure Storage replikeringsalternativer

```
LRS  → 3 kopier i samme datasenter
ZRS  → 3 kopier på tvers av Availability Zones (synkron)
GRS  → LRS + asynkron til sekundær region (LRS der)
GZRS → ZRS + asynkron til sekundær region (LRS der)
RA-GRS/RA-GZRS → Tillegg: lesetilgang til sekundær region
```

### Replikeringsvalg per AI-komponent

| AI-komponent | Anbefalt replikering | Begrunnelse |
|--------------|---------------------|-------------|
| Azure Blob Storage (dokumenter) | GZRS / RA-GZRS | Best balance mellom tilgjengelighet og DR |
| Azure Cosmos DB (state/session) | Multi-region writes | Automatisk geo-replikering med ~0 RPO |
| Azure SQL Database | Active geo-replication | Asynkron med ~5 sek RPO |
| Azure AI Search indekser | Manuell dual-indexing | Ingen innebygd replikering |
| Azure OpenAI (modell-config) | IaC-basert redeploy | Stateless tjeneste |
| Azure Key Vault | Automatisk failover | Microsoft-managed geo-replikering |

## Active-Active og Active-Passive mønstre

### Active-Active pattern

I et Active-Active oppsett er begge regioner aktive og mottar trafikk. Dette krever:
- Identisk infrastruktur i begge regioner
- Load balancer for trafikk-distribusjon
- Konflikthåndtering for samtidige skrivinger

```
┌──────────────┐     ┌────────────────┐     ┌──────────────┐
│   Brukere    │────▶│  Azure Front   │────▶│ Region A     │
│              │     │  Door / TM     │     │ (Active)     │
│              │     │  Latency-based │────▶│ Region B     │
│              │     │  routing       │     │ (Active)     │
└──────────────┘     └────────────────┘     └──────────────┘
```

**Azure Cosmos DB Active-Active eksempel:**

```bash
# Opprett Cosmos DB konto med multi-region writes
az cosmosdb create \
  --name "cosmos-ai-state" \
  --resource-group "rg-ai-prod" \
  --locations regionName="norwayeast" failoverPriority=0 isZoneRedundant=true \
  --locations regionName="swedencentral" failoverPriority=1 isZoneRedundant=true \
  --enable-multiple-write-locations true \
  --default-consistency-level "Session"

# Verifiser replikering
az cosmosdb show \
  --name "cosmos-ai-state" \
  --resource-group "rg-ai-prod" \
  --query "writeLocations[].{Region:locationName, Status:failoverPriority}"
```

### Active-Passive pattern

Active-Passive er mer kostnadseffektivt og enklere å implementere. Primærregionen håndterer all trafikk; sekundærregionen overtar kun ved failover.

**Warm Standby varianter:**

| Variant | Sekundær region | RTO | Kostnad |
|---------|----------------|-----|---------|
| Hot Standby | Full kapasitet, mottar replikert data | Sekunder | Høyest |
| Warm Standby | Minimal kapasitet, auto-scales ved failover | Minutter | Middels |
| Cold Standby | Kun IaC-templates, ingen kjørende ressurser | Timer | Lavest |

```python
# Active-Passive med Azure Traffic Manager health probes
# Bicep template for Traffic Manager profil
"""
resource trafficManagerProfile 'Microsoft.Network/trafficmanagerprofiles@2022-04-01' = {
  name: 'tm-ai-service'
  location: 'global'
  properties: {
    profileStatus: 'Enabled'
    trafficRoutingMethod: 'Priority'
    monitorConfig: {
      protocol: 'HTTPS'
      port: 443
      path: '/health'
      intervalInSeconds: 10
      timeoutInSeconds: 5
      toleratedNumberOfFailures: 3
    }
    endpoints: [
      {
        name: 'primary-norwayeast'
        type: 'Microsoft.Network/trafficmanagerprofiles/azureEndpoints'
        properties: {
          targetResourceId: primaryAppService.id
          priority: 1
          weight: 1
        }
      }
      {
        name: 'secondary-swedencentral'
        type: 'Microsoft.Network/trafficmanagerprofiles/azureEndpoints'
        properties: {
          targetResourceId: secondaryAppService.id
          priority: 2
          weight: 1
        }
      }
    ]
  }
}
"""
```

## Konsistensmodeller og eventual consistency

### CAP-teoremet og AI-systemer

AI-systemer må velge mellom konsistens (C), tilgjengelighet (A) og partisjontoleranse (P). For de fleste AI-workloads er eventual consistency akseptabelt.

### Cosmos DB konsistensmodeller

| Modell | Garanti | Latens | Anbefalt for |
|--------|---------|--------|-------------|
| Strong | Lineariserbar | Høyest | Finansielle transaksjoner |
| Bounded Staleness | K versjoner eller T tid | Høy | Leaderboard, tellere |
| Session | Konsistent innen sesjon | Middels | Chatbot state (anbefalt) |
| Consistent Prefix | Aldri out-of-order | Lav | Aktivitetslogg |
| Eventual | Ingen garanti om rekkefølge | Lavest | Analytics, rapportering |

```csharp
// C# eksempel: Session consistency for AI chatbot state
using Microsoft.Azure.Cosmos;

var cosmosClient = new CosmosClient(
    connectionString,
    new CosmosClientOptions
    {
        ConsistencyLevel = ConsistencyLevel.Session,
        ApplicationPreferredRegions = new List<string>
        {
            Regions.NorwayEast,
            Regions.SwedenCentral
        }
    });

// Hent session token fra response
var response = await container.ReadItemAsync<ConversationState>(
    id: sessionId,
    partitionKey: new PartitionKey(userId));

string sessionToken = response.Headers.Session;

// Bruk session token for konsistent lesing i neste request
var options = new ItemRequestOptions { SessionToken = sessionToken };
```

## Konfliktløsningsstrategier

### Last-Writer-Wins (LWW)

Standard konflikthåndtering i Cosmos DB. Basert på `_ts` (timestamp) feltet — siste skriving vinner.

### Custom conflict resolution

```javascript
// Cosmos DB custom conflict resolution stored procedure
function resolveConflict(incomingRecord, existingRecord, isTombstone, conflictingRecords) {
    // For AI chatbot: merge conversation history
    if (incomingRecord.messageHistory && existingRecord.messageHistory) {
        // Kombiner meldingshistorikk fra begge regioner
        var merged = existingRecord.messageHistory.concat(
            incomingRecord.messageHistory.filter(
                m => !existingRecord.messageHistory.some(e => e.id === m.id)
            )
        );
        // Sorter kronologisk
        merged.sort((a, b) => new Date(a.timestamp) - new Date(b.timestamp));
        existingRecord.messageHistory = merged;
        existingRecord._ts = Math.max(incomingRecord._ts, existingRecord._ts);
    }

    var context = getContext();
    var collection = context.getCollection();
    collection.replaceDocument(existingRecord._self, existingRecord);
}
```

### Konfliktmønstre for AI-data

| Datatype | Konfliktrisiko | Anbefalt strategi |
|----------|---------------|-------------------|
| Brukerpreferanser | Lav | Last-Writer-Wins |
| Konversasjonshistorikk | Middels | Merge med dedup |
| Feedback/ratings | Lav | Append-only |
| Search indeks-oppdateringer | Høy | Source-of-truth rebuild |
| Model config | Lav | Version-basert (IaC) |

## Monitoring av replikasjonsforsinkelse og helse

### Azure Monitor for replication health

```kusto
// KQL: Overvåk Cosmos DB replication lag
AzureDiagnostics
| where ResourceProvider == "MICROSOFT.DOCUMENTDB"
| where Category == "DataPlaneRequests"
| summarize
    AvgLatencyMs = avg(duration_s * 1000),
    MaxLatencyMs = max(duration_s * 1000),
    P99LatencyMs = percentile(duration_s * 1000, 99)
    by bin(TimeGenerated, 5m), regionName_s
| order by TimeGenerated desc
```

```kusto
// KQL: Azure Storage Last Sync Time for GRS
StorageBlobLogs
| where OperationName == "GetBlobServiceProperties"
| extend lastSyncTime = tostring(parse_json(ResponseBody).GeoReplication.LastSyncTime)
| project TimeGenerated, lastSyncTime, StatusCode
| order by TimeGenerated desc
```

### Alert-regler for replication health

```bash
# Azure Monitor alert: Cosmos DB replication lag > 5 sekunder
az monitor metrics alert create \
  --name "cosmosdb-replication-lag-alert" \
  --resource-group "rg-ai-prod" \
  --scopes "/subscriptions/{sub}/resourceGroups/rg-ai-prod/providers/Microsoft.DocumentDB/databaseAccounts/cosmos-ai-state" \
  --condition "avg ReplicationLatency > 5000" \
  --window-size 5m \
  --evaluation-frequency 1m \
  --severity 2 \
  --action-group "ag-oncall-team"

# Azure Storage: Last Sync Time alert
az monitor metrics alert create \
  --name "storage-geo-lag-alert" \
  --resource-group "rg-ai-prod" \
  --scopes "/subscriptions/{sub}/resourceGroups/rg-ai-prod/providers/Microsoft.Storage/storageAccounts/staiprod" \
  --condition "avg GeoReplicationLag > 900" \
  --window-size 15m \
  --evaluation-frequency 5m \
  --severity 2 \
  --action-group "ag-oncall-team"
```

### Dashboard-metrikker

| Metrikk | Terskel (Warning) | Terskel (Critical) | Tjeneste |
|---------|-------------------|-------------------|----------|
| Replication Latency | > 2 sek | > 10 sek | Cosmos DB |
| Geo Replication Lag | > 5 min | > 15 min | Azure Storage |
| Last Sync Time age | > 10 min | > 30 min | Azure Storage GRS |
| Active Geo-Repl lag | > 10 sek | > 60 sek | Azure SQL |
| Search index sync delta | > 100 docs | > 1000 docs | AI Search (custom) |

## Referanser

- [Azure Storage redundancy](https://learn.microsoft.com/en-us/azure/storage/common/storage-redundancy) — LRS, ZRS, GRS, GZRS-oversikt
- [Azure Storage Geo Priority Replication](https://learn.microsoft.com/en-us/azure/storage/common/storage-redundancy-priority-replication) — SLA-backed RPO
- [Active geo-replication for Azure SQL Database](https://learn.microsoft.com/en-us/azure/azure-sql/database/active-geo-replication-overview) — SQL Database replikering
- [Azure Cosmos DB global distribution](https://learn.microsoft.com/en-us/azure/cosmos-db/distribute-data-globally) — Multi-region writes og consistency
- [What are redundancy, replication, and backup?](https://learn.microsoft.com/en-us/azure/reliability/concept-redundancy-replication-backup) — Grunnleggende konsepter
- [Use geo-redundancy to design highly available applications](https://learn.microsoft.com/en-us/azure/storage/common/geo-redundant-design) — RA-GRS/RA-GZRS designmønstre
- [Multi-region deployments in Azure AI Search](https://learn.microsoft.com/en-us/azure/search/search-multi-region) — AI Search multi-region

## For Cosmo

- **Bruk denne referansen** når kunden trenger hjelp med å velge replikasjonsmekanismer for AI-løsninger, eller når de designer multi-region arkitekturer.
- Anbefal alltid GZRS (ikke GRS) for AI-workloads der Availability Zones er tilgjengelig — det gir best kombinasjon av intra-region HA og cross-region DR.
- For Cosmos DB: Session consistency er nesten alltid riktig valg for AI chatbots — det gir "read-your-own-writes" uten unødvendig latenskostnad.
- Påminn om at Azure AI Search IKKE har innebygd replikering — multi-region krever manuell dual-indexing eller rebuild fra kilde.
- For data residency: Verifiser alltid at sekundærregionen er innenfor godkjente geografiske grenser (Norway East ↔ Sweden Central er typisk godkjent for norske organisasjoner).
