Operating WAN geo-replication
This is the operational guide for running WAN-replicated sites — configuring, linking, monitoring, switching over, and troubleshooting. For the model see geo-replication concepts, for the design see the architecture page, and for the client/SDK view see the developer guide.
Geo-replication is new in 2.1.0 and off by default. A store with no site configuration is a normal single-site store.
Enabling the change feed and configuring sites
WAN replication rides on the change feed, so the feed must
be enabled on each cluster, and each store gains a site section. You can do this two ways.
Config file — add changeFeed and site blocks to the store config:
{
"clusterId": "orders",
"changeFeed": { "enabled": true },
"site": {
"id": "dc1",
"role": "Active",
"epoch": 1,
"peers": [
{ "id": "dc2", "store": "orders", "seeds": "dc2-a:7861,dc2-b:7861" }
],
"mergePolicy": "LastWriterWins"
}
}
PowerShell — New-ZrSiteLink configures both sides in one call (it posts the site/change-feed
config to the local and the peer managers and enables the feed), which is the recommended path:
# Active-active link between two stores in two workspaces
New-ZrSiteLink -Store orders-dc1 `
-PeerWorkspace prod-dc2 -PeerStore orders-dc2 `
-LocalSeeds 20.59.9.10:7863 -PeerSeeds 20.59.9.241:7863 `
-Mode ActiveActive -MergePolicy LastWriterWins -Restart
# Or an active -> passive mirror
New-ZrSiteLink -Store orders-dc1 -PeerWorkspace prod-dc2 -PeerStore orders-dc2 `
-LocalSeeds 20.59.9.10:7863 -PeerSeeds 20.59.9.241:7863 `
-Mode ActivePassive -Primary orders-dc1 -Restart
-Restart rolling-restarts each node so it arms the link now; omit it to restart on your own schedule.
The relevant environment knobs (ZARIS_WAN_SYNC_FEED, retention, fencing, and the watermark gate) are
in the configuration reference.
Cmdlets
| Cmdlet | Purpose |
|---|---|
New-ZrSiteLink | Configure an active-active or active-passive link across two workspaces (both sides). |
Get-ZrSiteStatus | Show role, epoch, each peer, and per-peer / per-segment lag (revisions and seconds). |
Remove-ZrSiteLink | Unlink two sites (clears both sides; the feed stays on for other CDC consumers). |
Switch-ZrActiveSite | Planned or forced active → passive switch-over (role change). |
Suspend-ZrSite / Resume-ZrSite | Active-active evacuate — quiesce one site to read-only for maintenance, then resume. |
Status.
New-ZrSiteLink,Get-ZrSiteStatus, andRemove-ZrSiteLinkare the configuration path. The orchestratedSwitch-ZrActiveSiteand theSuspend-ZrSite/Resume-ZrSiteevacuate are a documented management-plane roadmap item in this release; the lag tracking and the zero-loss go/no-go decision they build on are implemented.
The web console Replication tab
The web console adds a top-level Replication tab to the store page (alongside Overview, Nodes,
Partitions, Data, Metrics, Settings). It shows the live replication topology — active vs passive sites,
one-way vs bidirectional lanes, and per-site item counts — a health banner, and a wizard that calls
New-ZrSiteLink under the hood (it can reach multiple managers to pair both sides).
Monitoring
site.*counters, both directions —applied,skipped,conflicts, andbytes, with live rates, plus the per-pass statsapplied/deleted/snapshots/failed/notOwner.- RPO is reported as the age of the oldest un-applied op — about zero when caught up, climbing to real backlog-seconds when a site falls behind.
- Per-peer, per-segment lag in revisions and seconds from
Get-ZrSiteStatus, plus a single "caught up?" per peer. - Health states: healthy (lag near zero, no failures), falling-behind (lag growing), and
stalled (no progress). Alert on sustained
lagMsgrowth or a non-zerofailed/notOwnerstreak. A brief lag spike after a write burst is normal — the feed only serves up to the replicated watermark.
Switch-over
Planned (zero loss). Fence the active's writes (clients get a retryable OwnershipChanging), wait
until the target's cursors reach the old active's head (lag 0 — the command blocks on this), then the
epoch bumps and roles flip; the old active becomes passive and starts pulling from the new active.
Verify with Get-ZrSiteStatus.
Forced (bounded gap). Promotes immediately and reports the un-replicated gap as the accepted loss (A1). When the old active returns it sees the higher epoch and flips to passive; its stale-epoch writes are fenced. Investigate the reported gap if it is larger than expected.
Active-active has no switch-over (both sides already take writes); the maintenance analog is
evacuate — Suspend-ZrSite to quiesce one site to read-only, Resume-ZrSite after. This does not
change roles or bump the epoch.
Adding and removing a site
- Add: register the new peer in every existing site's
peersand set the new site's role/peers. The new site bootstraps from a per-origin snapshot from each peer, then tails each feed — it converges without deleting any existing site's data. - Remove: drop the peer from every other site's
peers, so its cursors and retained feed tail can be released. Confirm no site still lists it.
Geo-aware clear
A clear on a replicated store is geo-aware: it replicates to peers as versioned tombstones rather than dropping only local data, so a cleared keyspace converges across sites instead of resurrecting from a peer.
Clock requirements
Last-writer-wins and TTL use wall-clock-seeded hybrid logical clocks, so keep every site's clock on NTP. A change stamped too far into the future is quarantined by the clock-skew guard and the forward skew is exposed as a metric. On a skew alert, correct NTP promptly — sustained skew distorts conflict outcomes (a fast-clock site wins conflicts it should not) and TTL (early or late expiry).
Troubleshooting
A replicator that stops making progress (stalled). Check Get-ZrSiteStatus for a non-zero failed /
notOwner streak and growing lagMs. notOwner means the segment owner moved — the replicator
re-routes on the next pass. A failed segment is isolated and retried next pass. Confirm the peer is
reachable at its seeds and that the source side still has the feed enabled.
OutOfRange storms. A consumer whose cursor fell below the op-log trim floor re-syncs from a
server-side snapshot — a few after a long cut are normal. Many segments repeatedly going OutOfRange
means the retained tail is too small for the lag: raise ZARIS_WAN_SYNC_FEED_RETENTION_OPS /
_BYTES, or reduce lag (network/capacity). A snapshot that keeps replying "retry" means the segment's
replicated watermark has not caught up (writes in flight or a replica down) — check replica health.
Kubernetes: re-apply site config after a pod reschedule. When a node's site configuration is written
to an emptyDir (ephemeral) volume, a pod reschedule starts the node with no site config and it comes up
as a plain single-site store. Re-apply the geo configuration (New-ZrSiteLink, or a config mounted
from a ConfigMap/PVC) after any reschedule, or mount the site config from durable storage so it survives.
Related
- Geo-replication concepts
- WAN geo-replication architecture
- Geo-replication developer guide
- High availability and disaster recovery — availability within a single site.