[gprd] Add new nodes for the 6th Shard to redis-cluster-ratelimiting
Production Change
Change Summary
This change request adds a 6th shard (master + 2 replicas) to the existing gprd redis-cluster-ratelimiting cluster, growing it from 5 → 6 shards (15 → 18 nodes). This is the node-provisioning step only; migration of key(slot)s onto the new master is a follow-up CR (see the linked reshard CR below).
Purpose: horizontally scale out redis-cluster-ratelimiting to add CPU/ops headroom ahead of the Rack::Attack → Labkit::RateLimit shadow rollout (both rate limiters run in parallel during comparison, roughly doubling counter operations) and expected demand growth. Adding the 5th shard previously brought per-primary CPU saturation down as expected.
Tested in staging: this procedure was executed in gstg via #22494 (closed) (node-add) and #22495 (closed) (reshard).
Notes specific to gprd:
- Compute reservation must be bumped. Unlike gstg, gprd reserves these nodes:
environments/gprd/compute-reservations.tfholdsc2-standard-4reservations atcount = 5/zone (us-east1-b/c/d). Adding a 6th node per zone requires bumping these tocount = 6/zone in the same config-mgmt MR, otherwise the 3 new nodes fall back to on-demand capacity.
Change Details
-
Services Impacted - ServiceRedisClusterRateLimiting
-
Change Technician - @haseeb_ahmed
-
Change Reviewer - @sun_lee
-
Scheduled Date and Time (UTC in format YYYY-MM-DD HH:MM) - 2026-07-10 07:15
-
Time tracking - 60 minutes
-
Downtime Component - No downtime expected
Important
If your change involves scheduled maintenance, add a step to set and unset maintenance mode per our runbooks. This will make sure SLA calculations adjust for the maintenance period.
Preparation
Note
The following checklists must be done in advance, before setting the label changescheduled
Change Reviewer checklist
- Check if the following applies:
- The scheduled day and time of execution of the change is appropriate.
- The change plan is technically accurate.
- The change plan includes estimated timing values based on previous testing.
- The change plan includes a viable rollback plan.
- The specified metrics/monitoring dashboards provide sufficient visibility for the change.
- Check if the following applies:
- The complexity of the plan is appropriate for the corresponding risk of the change. (i.e. the plan contains clear details).
- The change plan includes success measures for all steps/milestones during the execution.
- The change adequately minimizes risk within the environment/service.
- The performance implications of executing the change are well-understood and documented.
- The specified metrics/monitoring dashboards provide sufficient visibility for the change.
- If not, is it possible (or necessary) to make changes to observability platforms for added visibility?
- The change has a primary and secondary SRE with knowledge of the details available during the change window.
- The change window has been agreed with Release Managers in advance of the change. If the change is planned for APAC hours, this issue has an agreed pre-change approval.
- The labels blocks deployments and/or blocks feature-flags are applied as necessary.
Change Technician checklist
- The Change Criticality has been set appropriately and requirements have been reviewed.
- The change plan is technically accurate.
- The rollback plan is technically accurate and detailed enough to be executed by anyone with access.
- This Change Issue is linked to the appropriate Issue and/or Epic
- Change has been tested in staging and results noted in a comment on this issue.
- A dry-run has been conducted and results noted in a comment on this issue.
- The change execution window respects the Production Change Lock periods.
- Once all boxes above are checked, mark the change request as scheduled:
/label ~"change::scheduled" - For C1 and C2 change issues, the change event is added to the GitLab Production calendar by the change-scheduler bot. It is schedule to run every 2 hours.
- For C1 and C2 change issues, Platform Leadership provides approval with the platform_leadership_approved label on the issue.
- For C1, C2, or blocks deployments change issues, confirm with Release managers that the change does not overlap or hinder any release process.
- For C1 change issues or C2 change issues happening during weekend, SREs on-call must be informed at least 2 weeks in advance.
Detailed steps for the change
Pre-execution steps
Note
The following steps should be done right at the scheduled time of the change request.
- Make sure all tasks in Change Technician checklist are done
- There are currently no active incidents that are severity1 or severity2
- If the change involves doing maintenance on a database host, an appropriate silence targeting the host(s) should be added for the duration of the change.
- Verify
railsusers are disallowed to executedebugcommand forredis-cluster-ratelimiting.
Change steps - steps to take to execute the change
Estimated Time to Complete (mins) - 60 minutes
Set label changein-progress /label ~change::in-progress
- Merge chef-repo MR creating the role for the new shard (
role[gprd-base-db-redis-cluster-ratelimiting-shard-06]: https://gitlab.com/gitlab-com/gl-infra/chef-repo/-/merge_requests/7654 - Using Atlantis, merge the config-mgmt MR that (a) bumps the shard count (
count = 5 -> 6inenvironments/gprd/redis-cluster.tf) and (b) bumps thec2-standard-4reservations fromcount = 5 -> 6in each zone (environments/gprd/compute-reservations.tf): https://ops.gitlab.net/gitlab-com/gl-infra/config-mgmt/-/merge_requests/14750- Verify the atlantis plan shows 3 new instances created —
redis-cluster-ratelimiting-shard-06-{01,02,03}-db-gprd— the reservation count changes (b/c/d: 5 → 6), and no changes/recreation on the existing 15 shard-01..05 instances.
- Verify the atlantis plan shows 3 new instances created —
- Wait for successful completion of
startup-script.shin serial-port logs (first converge runs ~15 min/node). Confirm the zone for each node from the atlantis plan before running (expected: 06-01 →us-east1-c, 06-02 →us-east1-d, 06-03 →us-east1-b):
gcloud compute instances get-serial-port-output redis-cluster-ratelimiting-shard-06-01-db-gprd --project gitlab-production --zone us-east1-c --port 1 | grep -aE 'Bootstrap finished|startup-script exit status'
gcloud compute instances get-serial-port-output redis-cluster-ratelimiting-shard-06-02-db-gprd --project gitlab-production --zone us-east1-d --port 1 | grep -aE 'Bootstrap finished|startup-script exit status'
gcloud compute instances get-serial-port-output redis-cluster-ratelimiting-shard-06-03-db-gprd --project gitlab-production --zone us-east1-b --port 1 | grep -aE 'Bootstrap finished|startup-script exit status'- Verify Chef converge completed (Roles/Recipes populated, Cinc version is
16.18.30):
knife node show redis-cluster-ratelimiting-shard-06-01-db-gprd.c.gitlab-production.internal
knife node show redis-cluster-ratelimiting-shard-06-02-db-gprd.c.gitlab-production.internal
knife node show redis-cluster-ratelimiting-shard-06-03-db-gprd.c.gitlab-production.internal
knife node show redis-cluster-ratelimiting-shard-06-01-db-gprd.c.gitlab-production.internal -a chef_packages.chef.version # expect 16.18.30- Verify SSH access works (i.e.
gitlab_usersrecipe ran):
ssh redis-cluster-ratelimiting-shard-06-01-db-gprd.c.gitlab-production.internal- Add the new master (
shard-06-01) and its replicas to the redis cluster viaredis-clion the first node in the cluster:
ssh redis-cluster-ratelimiting-shard-01-01-db-gprd.c.gitlab-production.internal
export ENV=gprd
export PROJECT=gitlab-production
export DEPLOYMENT=redis-cluster-ratelimiting
# This adds the master node
sudo gitlab-redis-cli --cluster add-node \
$DEPLOYMENT-shard-06-01-db-$ENV.c.$PROJECT.internal:6379 \
$DEPLOYMENT-shard-01-01-db-$ENV.c.$PROJECT.internal:6379
# This adds the replica nodes
for j in {02,03}; do
node_id="$(sudo gitlab-redis-cli cluster nodes | grep $DEPLOYMENT-shard-06-01-db-$ENV.c.$PROJECT.internal | awk '{ print $1 }')";
sudo gitlab-redis-cli --cluster add-node \
$DEPLOYMENT-shard-06-$j-db-$ENV.c.$PROJECT.internal:6379 \
$DEPLOYMENT-shard-01-01-db-$ENV.c.$PROJECT.internal:6379 \
--cluster-slave --cluster-master-id $node_id
done- Verify cluster health after the add:
cluster_state:ok,cluster_slots_fail:0, andcluster_known_nodesgrew by 3 (15 → 18):
sudo gitlab-redis-cli cluster info | grep -E 'cluster_state|cluster_slots_fail|cluster_known_nodes|cluster_size'
sudo gitlab-redis-cli cluster nodes | grep shard-06 # master shows in cluster; replicas show "slave <master-id> ... connected"- Set label changecomplete
/label ~change::complete
Rollback
Rollback steps - steps to be taken in the event of a need to rollback this change
Estimated Time to Complete (mins) - 60 minutes
- At this stage the newly added nodes hold no keyslots, so no data-path rollback is required.
- If a node misbehaves, remove it from the cluster with
sudo gitlab-redis-cli --cluster del-node <first-node>:6379 <node-id for the node to delete>(replicas first, then the empty master). - The config-mgmt (
count = 6 -> 5and reservations6 -> 5) and chef-repo role MRs can be reverted to de-provision the instances. - Set label changeaborted
/label ~change::aborted
Monitoring
Key metrics to observe
- Metric: redis-cluster-ratelimiting Apdex and RPS
- Location: Redis-cluster-ratelimiting dashboard (gprd)
- What changes to this metric should prompt a rollback: Degradation in Apdex for over 5 minutes
- Metric: Redis Cluster Slots Failed
- Location: Redis cluster slots failed view (gprd)
- What changes to this metric should prompt a rollback: Non-zero
Redis Cluster Slots Failed