Steg 9 (R4): unified migrate-corpus.mjs --write over engineering/governance/ infrastructure/security. 327 filer mutert, verified=null, prosa byte-identisk (fra første ## seksjon), advisor urørt (0 endringer). To applier-fixes oppdaget under kjøring (TDD, RED→GREEN): - insertHeaderFields: anker faller nå tilbake når en meta-linje selv passerer 500B (2 filer pakket et avsnitt i **Status:** → Type/Source landet utenfor scan-vinduet, applierens post-write-assertion fanget + restaurerte). - normalizeStaleVerified: fjerner nå ALLE stale non-date **Verified:** i 500B-vinduet, inkl. stray body-dup rett under --- (9 mlops-genaiops-filer var ellers falskt "verified"/fresh, droppet fra worklist). Operatør-godkjent utvidelse av carve-out; kun stray metadata-linjer, aldri prosa. test-transform-criterion: precondition oppdatert til post-migrasjons-sannhet (fila bærer nå Source). Suite 728/728 grønn.
319 lines
13 KiB
Markdown
319 lines
13 KiB
Markdown
# Data Replication Patterns for AI Systems
|
|
|
|
**Last updated:** 2026-06-24
|
|
**Status:** GA
|
|
**Category:** Business Continuity & Disaster Recovery
|
|
**Type:** reference
|
|
**Source:** https://learn.microsoft.com/azure/reliability/concept-redundancy-replication-backup
|
|
|
|
---
|
|
|
|
## Innhold
|
|
|
|
- [Introduksjon](#introduksjon)
|
|
- [Synkron vs. asynkron replikering](#synkron-vs-asynkron-replikering)
|
|
- [Active-Active og Active-Passive mønstre](#active-active-og-active-passive-mønstre)
|
|
- [Konsistensmodeller og eventual consistency](#konsistensmodeller-og-eventual-consistency)
|
|
- [Konfliktløsningsstrategier](#konfliktløsningsstrategier)
|
|
- [Monitoring av replikasjonsforsinkelse og helse](#monitoring-av-replikasjonsforsinkelse-og-helse)
|
|
- [Referanser](#referanser)
|
|
- [For Cosmo](#for-cosmo)
|
|
|
|
## 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).
|