From 986bee93e2a1d882c78a110a591c8a7d0224df74 Mon Sep 17 00:00:00 2001 From: hfxia Date: Mon, 7 Sep 2026 05:27:08 -0400 Subject: [PATCH 1/2] docs(redis): PVC backup on node-local storage; refresh CRDs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Backup no longer needs a ReadWriteMany provider. The backup PVC is created ReadWriteOnce by default (spec.accessModes on RedisBackup / RedisClusterBackup), and restore no longer mounts that PVC into every Redis pod: a transient in-cluster source serves it read-only and each pod pulls its own data over the network. Verified against redis-operator 4f13d6c1 and f1eff1e6, both carried by tag v5.1. - release_notes: new 5.1.0 entry, with the two limits that apply — the path is chosen by bundle version, not by the backup's access mode, and picking a node-local StorageClass in the console needs Data Services Essentials v4.4.1 or later (chart-middleware 320c9cc, first tagged in v4.4.1) - 70-backup-restore: drop the stale "requires node migration and ReadWriteMany, such as NFS or Ceph" claim and the "network-based StorageClass" prerequisite; document the provisioner allow-list the console filters on (middleware-sc-cm-base merged with middleware-sc-cm) and the restore caveat for instances held on an older bundle version Refresh docs/shared/crds from redis-operator release-5.1 (9b8d1fbc), which carries two breaking API changes made after the docs were written (9630abfa, 77851bdc): redisUserName -> redisUserRef on Redis and ActiveRedis, secretName -> redisUserRef on ActiveRedisInspection, ActiveRedisConnection.secretName removed, and peerPort's schema default dropped. The prose still uses the old names in five pages under functions/95-disaster-recovery — a separate pass, since the 6.0 link-auth flow changed behavior and not just field names. Also carries two working-tree edits that predate this work: the "Redesigned" prefix dropped from the Cross-Datacenter Replication heading, and the &project=Middleware parameter removed from the three v5.1.0 release-notes-for-bugs templates. --- TERMINOLOGY_CANDIDATES.md | 18 ++++++++++ docs/en/functions/70-backup-restore.mdx | 12 +++++-- docs/en/release_notes.mdx | 16 ++++++--- .../crds/middleware.alauda.io_redis.yaml | 33 +++++++++++++------ ...edis.middleware.alauda.io_activeredis.yaml | 15 +++++---- ...ware.alauda.io_activeredisconnections.yaml | 23 +++++-------- ...ware.alauda.io_activeredisinspections.yaml | 17 +++++++--- ...iddleware.alauda.io_activeredismeshes.yaml | 4 +-- 8 files changed, 94 insertions(+), 44 deletions(-) diff --git a/TERMINOLOGY_CANDIDATES.md b/TERMINOLOGY_CANDIDATES.md index 7d85baa..d4c5e45 100644 --- a/TERMINOLOGY_CANDIDATES.md +++ b/TERMINOLOGY_CANDIDATES.md @@ -79,6 +79,24 @@ checkouts `redis-group/redis-operator` and `redis-group/redis-modules`. | **membership lifecycle** | `activeredismesh_types.go` — `MeshMemberAlive`, `MeshMemberSuspect`, `MeshMemberDead` | Heading only, for the alive → suspect → dead progression. The state names themselves are already registered above. | | **announced RESP address** | `activeredis_types.go` — `Access.AnnounceAddress`, `Access.AnnouncePort`; the `mesh-seeds` grammar `host:redis-port@peer-port` in `internal/controller/middleware/activeredis/meshconfig.go:46` | Names the address that identifies a member inside the mesh, as distinct from the peer port that carries the traffic. The component words are already registered; confirm the compound. | +## Backup storage (added 2026-09-07) + +Terms introduced by the v5.1.0 release note *PVC Backup and Restore on +Node-Local Storage* and the corresponding correction of +`docs/en/functions/70-backup-restore.mdx`. Repository paths are relative to the +sibling checkout `redis-group/redis-operator`. `ReadWriteOnce` / +`ReadWriteMany` and *access mode* are Kubernetes API vocabulary and are written +out in full; the abbreviations RWO / RWX used in the operator's commit messages +and in `doc/backup-restore-rwo.md` are deliberately kept out of customer docs. + +| Term as used in docs | Provenance | Note for the reviewer | +|:---|:---|:---| +| **node-local block storage** | `api/middleware/redis/v1/redisbackup_types.go:64-66` and `api/middleware/redis/v1/redisclusterbackup_types.go:53-55` — the `AccessModes` field doc ("node-local/RWO storage (e.g. TopoLVM)"); `doc/backup-restore-rwo.md` | **Coined for these docs.** The code says "node-local / RWO storage" and names TopoLVM as the example; the docs use neither the abbreviation nor the product name. Confirm the phrase, and confirm that no concrete provider should be named here — the same page still names NFS and Ceph on the `ReadWriteMany` side. | +| **backup volume** | `internal/controller/middleware/redisbackup/service/generator.go:421,433` — the PersistentVolumeClaim the backup Job writes to | Used instead of repeating "backup PVC". The page already names the method **PVC Backup**, so both spellings now appear on it. Confirm which is canonical. | +| **provisioner allow-list** | `chart-middleware/middleware/templates/configmap.yaml` — ConfigMap `middleware-sc-cm-base`, key `middleware_sc_map.yaml`, entry `Redis.backup`. Applied as a hard filter on the dropdown in `redis-group/redis-frontend/modules/meepo-shared/src/lib/components/storage-class/component.ts:148-162` (`items.filter(... supportedStorages[target]?.includes(item.provisioner))`), over the union of `middleware-sc-cm-base` and `middleware-sc-cm` (`.../services/storage-class.service.ts:84-118`, `mergeStorageClassConfigs`) | **Coined for these docs.** Names the platform-side filter that decides which StorageClasses the backup forms offer. The code has no name for it — the one named constant, `BACKUP_SUPPORTED_STORAGE_TYPE`, is unused (`redis-group/redis-frontend/src/app/constants.ts:10-25`). Confirm the phrase. | +| **bundle version** (API `spec.upgradeOption.crVersion`) | `redis-operator` `api/middleware/v1/redis_types.go:32-36` (`CRVersion`, `AutoUpgrade`) and `:339` (`printcolumn` name `Bundle Version`); annotation `middleware.instance/crVersion` in `internal/config/keys.go:44`; tier selection in `pkg/actor/manager.go:107-140` (`Search` takes the highest actor whose `Version()` is not greater than the annotation, defaulting to the operator's own version) | Not new — `docs/en/functions/10-create-instance.mdx:261` already documents the `BUNDLE VERSION` column as "the version number of the operator managing the instance". This is the first place the docs pair that display name with the `crVersion` / `autoUpgrade` API fields, and the first place a docs statement depends on a specific value. `crVersion` is the operator's own version (`internal/vc/generator.go:60,163`, from `REDIS_OPERATOR_VERSION`), so the column is product-version-shaped. **The published threshold `5.1.0` is deliberately conservative**: the code boundary is `4.1.2`, because the frozen `v5.0` tier (`Version()` `4.1.2`, serving `[4.1.2, 5.1.0)`, introduced by `7a7ebc3c` as a verbatim copy of a canonical builder that already carried the network-delivered restore) also skips the mount-based path — so instances pinned at `4.1.2`–`5.0.x` do not in fact need `ReadWriteMany`. Wording chosen by the maintainer 2026-09-07; revisit if the frozen tier changes. | +| **transient in-cluster source** | `internal/ops/restoresource/source.go`; `internal/builder/restorebuilder/source.go`; wired by the base and `v5.0` ensure-resource actors (`internal/ops/{cluster,failover}/actor[/v5.0]/actor_ensure_resource.go`) | **Coined for these docs.** The implementation is a versitygw S3 gateway; the docs deliberately name neither the project nor S3, to avoid confusing it with the **S3 Backup** method on the same page. Confirm the phrase. | + ## Known inconsistencies to resolve 1. **"Source side" / "Target side" (Web Console) vs. "upstream" / "downstream" diff --git a/docs/en/functions/70-backup-restore.mdx b/docs/en/functions/70-backup-restore.mdx index 5dfac51..1f9e302 100644 --- a/docs/en/functions/70-backup-restore.mdx +++ b/docs/en/functions/70-backup-restore.mdx @@ -10,11 +10,13 @@ Implementing a robust backup strategy is essential for data protection. Regular Alauda Cache Service E1 supports two backup methodologies: * **S3 Backup:** Stores backup data in S3-compatible object storage systems, providing scalable and durable off-cluster backup capabilities. -* **PVC Backup:** Utilizes Kubernetes PersistentVolumeClaims to store backup data on persistent volumes. This method requires PV infrastructure that supports both node migration and the ReadWriteMany access mode, such as NFS or Ceph storage systems. +* **PVC Backup:** Utilizes Kubernetes PersistentVolumeClaims to store backup data on persistent volumes. The backup volume is created with the `ReadWriteOnce` access mode by default, so node-local block storage can be used; a `ReadWriteMany` provider such as NFS or Ceph is accepted but is not required. Set `spec.accessModes` on `RedisBackup` or `RedisClusterBackup` to request a different access mode. ## Prerequisites -To utilize S3 backup functionality with your own storage buckets, confirm with your administrator that S3 storage integration has been properly configured for your project namespace. Alternatively, ensure your cluster provides a network-based `StorageClass` capable of provisioning appropriate storage resources. +To utilize S3 backup functionality with your own storage buckets, confirm with your administrator that S3 storage integration has been properly configured for your project namespace. Alternatively, ensure your cluster provides a `StorageClass` capable of provisioning the backup volume; node-local block storage is sufficient. + +For PVC backup, the **Storage Class** selector — shown both when you create a backup and when you edit the automatic backup setting — offers only the StorageClasses whose provisioner appears in the allow-list the platform publishes on the `global` cluster: the `Redis.backup` key of `middleware_sc_map.yaml`, held in the `cpaas-system` namespace by the plugin-supplied `middleware-sc-cm-base` ConfigMap together with the optional `middleware-sc-cm` ConfigMap that carries your own additions. Alauda Container Platform Data Services Essentials `v4.4.1` and later ship `nfs.csi.k8s.io`, `rook-ceph.cephfs.csi.ceph.com`, and `topolvm.cybozu.com` in that list, so node-local TopoLVM volumes are selectable with no further configuration. If that version of the plugin cannot be installed, add the provisioner you use to `middleware-sc-cm`: its entries are added to the shipped list rather than replacing it, and are not overwritten when the plugin is upgraded. ## Immediate Backup @@ -62,6 +64,12 @@ Automatic backups allow you to schedule regular, recurring backups of your Redis The restore operation creates a new Redis instance populated with data from a previous backup. +A PVC backup is delivered over the network: the platform mounts the backup volume read-only into a transient in-cluster source, each Redis pod pulls its own data from that source, and the source is removed once the instance is ready. Every PVC backup takes this path regardless of the access mode it was created with, which is why a `ReadWriteMany` volume is no longer required. An S3 backup is pulled directly from the object store, as before. + + +The restore path is chosen by the instance's bundle version, not by the backup's access mode. An instance whose **BUNDLE VERSION** — `status.upgradeStatus.crVersion`, shown by `kubectl get redis` — is earlier than `5.1.0` may still restore by mounting the backup volume into every Redis pod, which requires the backup to be on a `ReadWriteMany` volume: create the backup with `spec.accessModes: [ReadWriteMany]` when you intend to restore it into such an instance. An instance stays on an earlier bundle version only while it is held there, by `spec.upgradeOption.autoUpgrade` set to `false` together with a pinned `spec.upgradeOption.crVersion`. + + ### Procedure diff --git a/docs/en/release_notes.mdx b/docs/en/release_notes.mdx index c9e6639..00f0f10 100644 --- a/docs/en/release_notes.mdx +++ b/docs/en/release_notes.mdx @@ -23,7 +23,7 @@ The following table shows the compatibility and support matrix between Alauda Ca ### New and Optimized Features -#### Redesigned Cross-Datacenter Replication (Alpha) +#### Cross-Datacenter Replication (Alpha) Redis `7.2` instances now run a redesigned replication module, offering two modes selected per instance through `spec.activeRedis.mode`: @@ -50,21 +50,29 @@ The two module generations do not interoperate, so the whole group must be upgra `ActiveRedisConnection` now carries a `teardownPolicy`. `Detach` (the default) removes the link but keeps the peer's bookkeeping so the link can be re-created later. `Decommission` permanently retires a peer and releases the retention floors held for it — the correct teardown for a datacenter that is gone for good. +#### PVC Backup and Restore on Node-Local Storage + +PVC backup no longer requires a `ReadWriteMany`-capable storage provider. The backup volume is now created with the `ReadWriteOnce` access mode by default — configurable through `spec.accessModes` on `RedisBackup` and `RedisClusterBackup` — so backups can be stored on node-local block storage. Restore no longer mounts the backup volume into every Redis pod either: the data is delivered to the pods over the network instead of through a shared mount. + +Existing backups on `ReadWriteMany` volumes stay restorable and take the same network-delivered path, and S3 backups keep their existing direct-pull path. The path is chosen by the instance's bundle version, not by the backup's access mode: an instance pinned to a bundle version earlier than `5.1.0` may still perform the previous mount-based restore, and needs its backup on a `ReadWriteMany` volume. + +Selecting a node-local `StorageClass` in the Web Console additionally requires Alauda Container Platform Data Services Essentials `v4.4.1` or later. See [Backup & Restore Instance](./functions/70-backup-restore.mdx). + #### New APIs The `ActiveRedis`, `ActiveRedisMesh`, and `ActiveRedisInspection` resources are documented under [Redis APIs](./apis/kubernetes_apis/redis/index.mdx). ### Fixed Issues -{/* release-notes-for-bugs?template=mw-redis-v5.1.0-fixed&project=Middleware */} +{/* release-notes-for-bugs?template=mw-redis-v5.1.0-fixed */} ### Known Issues -{/* release-notes-for-bugs?template=mw-redis-v5.1.0-known&project=Middleware */} +{/* release-notes-for-bugs?template=mw-redis-v5.1.0-known */} ### Security Fixes -{/* release-notes-for-bugs?template=mw-redis-v5.1.0-security&project=Middleware */} +{/* release-notes-for-bugs?template=mw-redis-v5.1.0-security */} ## v5.0.1 diff --git a/docs/shared/crds/middleware.alauda.io_redis.yaml b/docs/shared/crds/middleware.alauda.io_redis.yaml index 96c2b4e..d20573f 100644 --- a/docs/shared/crds/middleware.alauda.io_redis.yaml +++ b/docs/shared/crds/middleware.alauda.io_redis.yaml @@ -1641,17 +1641,28 @@ spec: type: object type: array type: object - redisUserName: + redisUserRef: description: |- - RedisUserName names the RedisUser (same namespace) whose username/password - back the module's peer-auth credential (activeredis.peer-auth-user/-pass). - The new module (7.2) REQUIRES peer-auth: without it every inbound peer + RedisUserRef names the RedisUser OBJECT (same namespace) whose + username/password back the module's peer-auth credential + (activeredis.peer-auth-user/-pass). It is a resource reference, NOT an ACL + username: the referenced object is what carries the username, which is + typically "default" or a custom account name and rarely matches the object + name (e.g. the object "rfr-acl--default" holds username + "default"). + + The new module (7.2/8.4) REQUIRES peer-auth: without it every inbound peer link (peerof and mesh) is rejected. The referenced RedisUser must target - this instance and be a custom account with at least one password, and the - SAME username/password must be bound on every instance participating in - the replication — the module rejects an inbound peer whose presented - username differs from the local peer-auth-user. Required when activeRedis - is enabled on 7.2; ignored for the 6.0 legacy module. + this instance and carry at least one password; it may be the instance's + default account or a custom one, but never the system account (the + operator's own internal account). The SAME username/password must be + bound on every instance participating in the replication — the module + rejects an inbound peer whose presented username differs from the local + peer-auth-user — which usually means a custom account minted alike in + every data center, since default-account passwords differ per instance. + Required when activeRedis is enabled on 7.2/8.4. On the 6.0 legacy module + the module itself has no peer-auth, but the binding is still provisioned + and honoured by the proxy, so the same credential selection works there. type: string serviceID: description: |- @@ -6935,7 +6946,9 @@ spec: The API accepts every version in the enum, but a version only deploys when the installed bundle's ImageVersion carries a matching server image — today 6.0 and - 7.2. + 7.2. Redis 8.4 stays API-accepted while shipping no image (the bundle omits an + 8.4 server image for licensing reasons); deploying it requires supplying an 8.4 + image out of band. enum: - "6.0" - "6.2" diff --git a/docs/shared/crds/redis.middleware.alauda.io_activeredis.yaml b/docs/shared/crds/redis.middleware.alauda.io_activeredis.yaml index 40c8609..331c62f 100644 --- a/docs/shared/crds/redis.middleware.alauda.io_activeredis.yaml +++ b/docs/shared/crds/redis.middleware.alauda.io_activeredis.yaml @@ -1631,12 +1631,13 @@ spec: type: object type: array type: object - redisUserName: + redisUserRef: description: |- - RedisUserName mirrors the bound instance's peer-auth RedisUser binding - (spec.activeRedis.redisUserName on the Redis CR). The ActiveRedis - reconciler resolves it and pushes activeredis.peer-auth-user/-pass to - every node; link controllers reuse the same credential for as.peerof. + RedisUserRef mirrors the bound instance's peer-auth RedisUser binding + (spec.activeRedis.redisUserRef on the Redis CR) — a RedisUser OBJECT name, + not an ACL username. The ActiveRedis reconciler resolves it and pushes + activeredis.peer-auth-user/-pass to every node; link controllers reuse the + same credential for as.peerof. type: string required: - instance @@ -1826,8 +1827,8 @@ spec: version: description: |- Version is the redis version of the bound instance. It selects the AA - module generation: 6.0 uses the legacy module, 7.2 uses the new module's - native peer-port transport. + module generation: 6.0 uses the legacy module + proxy, 7.2/8.4 use the new + module's native peer-port transport (no proxy). type: string required: - phase diff --git a/docs/shared/crds/redis.middleware.alauda.io_activeredisconnections.yaml b/docs/shared/crds/redis.middleware.alauda.io_activeredisconnections.yaml index 1fa7810..12d9343 100644 --- a/docs/shared/crds/redis.middleware.alauda.io_activeredisconnections.yaml +++ b/docs/shared/crds/redis.middleware.alauda.io_activeredisconnections.yaml @@ -85,25 +85,20 @@ spec: This is useful for maintenance or temporary disabling of the connection. type: boolean peerPort: - default: 7379 description: |- - PeerPort is the upstream proxy's peer-port — the AS_MESH replication - endpoint the local masters dial (the ONLY peer transport; the legacy - as.peersync-over-RESP transport was removed). The host is taken from - Addresses[0]; this is the port. Override it when an external LB/F5 - exposes the proxy peer-port under a different number. + PeerPort is the port the local masters dial for the AS_MESH replication + stream (the ONLY peer transport; the legacy as.peersync-over-RESP + transport was removed). The host is taken from Addresses[0]; this is the + port. LEAVE IT UNSET: the upstream proxy serves the replication stream and + the RESP control plane on one endpoint, so the default is the port of + Addresses[0] itself. Set it only when an external LB/F5 splits the two onto + different numbers. There is deliberately NO schema default — a stamped + value cannot be told apart from a deliberate one, and the port that used to + be defaulted here (7379) is unreachable on a NodePort-exposed upstream. format: int32 maximum: 65535 minimum: 1 type: integer - secretName: - description: |- - SecretName the secret name for redis authentication (username/password - keys). Required for the 6.0 legacy module ONLY — enforced by the - admission webhook, not the schema. The new (7.2) module ignores it: - its peer links authenticate with the instance-level peer-auth binding - (Redis spec.activeRedis.redisUserName), the same credential in every DC. - type: string teardownPolicy: default: Detach description: |- diff --git a/docs/shared/crds/redis.middleware.alauda.io_activeredisinspections.yaml b/docs/shared/crds/redis.middleware.alauda.io_activeredisinspections.yaml index 880f581..732957e 100644 --- a/docs/shared/crds/redis.middleware.alauda.io_activeredisinspections.yaml +++ b/docs/shared/crds/redis.middleware.alauda.io_activeredisinspections.yaml @@ -55,12 +55,19 @@ spec: description: Instance is the instance name of local redis. minLength: 1 type: string - secretName: + redisUserRef: description: |- - SecretName the secret name for redis authentication. for default user, - the password field is required. Optional: only the 6.0 legacy module - authenticates the probe with this secret; the new (7.2) module uses - the instance-level peer-auth binding and ignores it. + RedisUserRef names the RedisUser OBJECT whose credential the probe + authenticates with on the new (7.2/8.4) module — a resource reference, not + an ACL username (the referenced object carries the username). Optional: the + inspection prefers the instance's own spec.activeRedis.redisUserRef + binding; this field only fills in when the instance declares none — the + pre-flight probe a console runs BEFORE active-active is enabled on the + instance, when no binding exists yet and the account is still only a + selection in the form. The RedisUser must target this instance and carry + the same username/password every DC in the replication group binds. The 6.0 + legacy module has no peer-auth and ignores this field, authenticating + the probe with SecretName instead. type: string serviceID: description: |- diff --git a/docs/shared/crds/redis.middleware.alauda.io_activeredismeshes.yaml b/docs/shared/crds/redis.middleware.alauda.io_activeredismeshes.yaml index 988b542..8963c51 100644 --- a/docs/shared/crds/redis.middleware.alauda.io_activeredismeshes.yaml +++ b/docs/shared/crds/redis.middleware.alauda.io_activeredismeshes.yaml @@ -40,7 +40,7 @@ spec: openAPIV3Schema: description: |- ActiveRedisMesh is the Schema for the activeredismeshes API. It drives full - gossip active-active (mesh mode) for the new 7.2 module. + gossip active-active (mesh mode) for the new 7.2/8.4 module. properties: apiVersion: description: |- @@ -84,7 +84,7 @@ spec: SecretName is the secret holding peer-auth credentials (username/password) used for gossip and replication to peers. Deprecated: never wired. The peer-auth credential is the instance-level - RedisUser binding (Redis spec.activeRedis.redisUserName), resolved and + RedisUser binding (Redis spec.activeRedis.redisUserRef), resolved and pushed by the ActiveRedis reconciler; mesh mode only exists on the new module, so this field has no remaining consumer. Ignored. type: string From 9bb292ea002d9a8dc3a648a93b902b5622be07aa Mon Sep 17 00:00:00 2001 From: hfxia Date: Mon, 7 Sep 2026 05:43:12 -0400 Subject: [PATCH 2/2] docs(redis): define the heading ids the anchor links target `doom lint` resolves in-page anchors against explicit ids, not against slugs derived from heading text, so four links resolved to nothing: - architecture.mdx `## Sentinel Mode` had no id, breaking the link from the Disaster Recovery architecture page - the Active-Active architecture page linked to two of its own headings that carried no id - the Active-Active setup page pointed `tuning` at a same-page `#tuning` section that lives in 30-operations.mdx Add the three ids and repoint the fourth link at the page that owns the section. Every remaining in-repo anchor link resolves. --- docs/en/architecture.mdx | 2 +- .../95-disaster-recovery/30-active-active/10-architecture.mdx | 4 ++-- .../95-disaster-recovery/30-active-active/20-setup.mdx | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/en/architecture.mdx b/docs/en/architecture.mdx index 900d791..23c6a3d 100644 --- a/docs/en/architecture.mdx +++ b/docs/en/architecture.mdx @@ -12,7 +12,7 @@ Alauda Cache Service E1 offers two distinct deployment architectures, each desig - **Cluster Mode**: A distributed architecture that implements horizontal scaling through data sharding across multiple Redis nodes. This configuration provides enhanced read/write throughput, automatic failover capabilities, and intelligent data partitioning for optimal performance and availability in high-scale environments. -## Sentinel Mode +## Sentinel Mode \{#sentinel-mode} Sentinel Mode implements a high-availability solution based on Redis's native primary-replica replication. Redis Sentinel monitors the Redis nodes and can promote a replica to primary when the primary fails and the required quorum and majority authorization are available. Key characteristics include: diff --git a/docs/en/functions/95-disaster-recovery/30-active-active/10-architecture.mdx b/docs/en/functions/95-disaster-recovery/30-active-active/10-architecture.mdx index bb955eb..3a384f5 100644 --- a/docs/en/functions/95-disaster-recovery/30-active-active/10-architecture.mdx +++ b/docs/en/functions/95-disaster-recovery/30-active-active/10-architecture.mdx @@ -33,7 +33,7 @@ Two consequences follow, and they are the whole reason the rest of this page exi * **Concurrent writes to the same key are normal**, not exceptional. They are reconciled automatically, by rules that differ from standalone Redis. * **There is no promotion step** when a datacenter is lost. The surviving members were already accepting writes, so recovery is a matter of redirecting clients. -## Discovered membership, not declared links +## Discovered membership, not declared links \{#discovered-membership-not-declared-links} Disaster Recovery declares every link: one `ActiveRedisConnection` per edge, naming both ends. Active-Active declares only a **starting point**. Each cluster owns one `ActiveRedisMesh` for its local instance, carrying a short list of `seeds` — externally-routable addresses of members in other datacenters. From there the members gossip: they exchange membership records, learn about members nobody told them about, and form the remaining links themselves. @@ -71,7 +71,7 @@ The operator pushes the seed list to **every** node of the instance, replicas in That is what makes re-entry automatic: when a pod restarts, or a Sentinel or Cluster failover promotes a replica, the newly-serving node already holds the seed list and rejoins the mesh on its own. No `ActiveRedisMesh` has to be edited and no other datacenter has to be reconfigured. -## Redis Cluster members +## Redis Cluster members \{#redis-cluster-members} In Cluster mode the mesh is not one ring but one **ring per shard**: shard 0 replicates with shard 0 in the other datacenters, shard 1 with shard 1, and so on. The module replicates within a shard position and does not route hash slots — Redis Cluster itself does that — so every member of the group must have a matching shard count and slot layout. The `ActiveRedisMesh` status reports a `shardID` alongside each member's `serviceID` for this reason. diff --git a/docs/en/functions/95-disaster-recovery/30-active-active/20-setup.mdx b/docs/en/functions/95-disaster-recovery/30-active-active/20-setup.mdx index aa1c5bf..4f166d9 100644 --- a/docs/en/functions/95-disaster-recovery/30-active-active/20-setup.mdx +++ b/docs/en/functions/95-disaster-recovery/30-active-active/20-setup.mdx @@ -135,7 +135,7 @@ The operator injects the normalized set on **every** node, replicas included, so |:------|:------------| | `pause` | Suspends mesh participation. Defaults to `false`. | | `enableTLS` | Enables TLS for the peer transport. | -| `tuning` | Optional gossip and membership timers. See [Tuning](#tuning). | +| `tuning` | Optional gossip and membership timers. See [Tuning](./30-operations.mdx#tuning). | | `secretName` | **Deprecated and ignored.** The peer-auth credential is the instance-level `RedisUser` binding. | ## Step 4: Verify convergence