##Introduction to Staged Remediation
Understanding Topology Hints
Topology hints are metadata that a node attaches to outgoing requests to steer traffic toward replicas that are topologically close (e.g., same rack, same availability zone). In distributed data stores such as Cassandra, ScyllaDB, and CockroachDB, hints reduce cross‑zone latency and improve read‑locality. When hints become stale or mis‑aligned—often after a network partition, node replacement, or zone‑level outage—they can cause request routing to fail repeatedly, manifesting as timeouts that appear application‑level but are actually hint‑driven mis‑routes.
Importance of Pre‑Checks
Before changing any routing‑influencing configuration, establish a known‑good baseline and verify that the system is not already in a failure cascade. Pre‑checks provide:
- Evidence that observed timeouts are hint‑related (rising hint counters, request traces showing mis‑directed hops).
- A measurable safety envelope (baseline latency, error rates, throughput) against which each remediation step can be judged.
- A clear rollback trigger (if any metric deviates beyond a pre‑defined threshold, halt and revert the change).
Skipping pre‑checks turns a controlled remediation into a gamble, risking a local zone problem becoming a cluster‑wide rebalance shock because hints are removed everywhere at once, forcing all nodes to re‑evaluate replica placement simultaneously.
Pre‑Remediation Checks
Network and System Health
- Node‑level health – Confirm each node reports
UPin gossip and none areDOWNorLEAVING.nodetool status | grep -E 'UN|UP' - Inter‑node latency – Measure 95th‑percentile RTT between zones using
pingortcptrace.ping -c 20 <node-in-zone-b> | tail -1 - Resource saturation – CPU, memory, disk I/O, and network utilization < 70 % on all nodes (adjust per SLA). Use
collectd,Prometheus node_exporter, orsar. - Hint statistics – Verify hint counters are non‑zero and trending upward in the affected zone.
nodetool gossipinfo | grep hint # or via JMX: org.apache.cassandra.metrics:type=HintedHandoff,name=TotalHints
Traffic Patterns and Baselines
- Request latency – Capture 99th‑percentile read/write latency per client zone for the last 15 min.
- Error rate – Track HTTP 5xx / database timeout errors per zone.
- Throughput – Measure requests per second (RPS) per zone.
Store these numbers in a time‑series dashboard (Grafana, CloudWatch) and export as CSV for later comparison.
Current Topology Hint Configuration
- Hint enabled flag – Ensure hints are globally enabled (
hinted_handoff_enabled: trueincassandra.yaml). - Per‑zone hint settings – Check for any datacenter‑specific overrides.
- Hint TTL – Note
max_hint_window_in_msto understand how long stale hints may linger. - Recent changes – Review Git/ChatOps logs for hint‑related modifications in the past 24 h.
If any check fails (node down, latency > 2× baseline, hint counters zero despite timeouts), abort and investigate the underlying cause first.
Designing the Canary Scope
Selecting Representative Nodes
Pick a small, homogeneous subset that mirrors the failure zone:
| Criterion | Reason |
|---|---|
| Same rack / availability zone as timing‑out traffic | Reproduces the hint behavior observed in production. |
| Mixed workload (read‑heavy and write‑heavy) | Validates both paths are affected. |
| CPU < 50 % | Reduces chance the canary itself triggers a rebalance. |
| Same software version and configuration | Guarantees parity. |
Typical size: 3‑5 nodes (~5 % of a 60‑node cluster) per zone.
Isolating Canary Scope Traffic
- Dedicated client profile – Point a small set of test clients (or a canary service) to the canary nodes only via a load‑balancer ACL or DNS override.
- Tag the traffic – Use a custom HTTP header (
X-Canary: true) or a distinct Cassandra username/password so metrics can be filtered. - Disable hint propagation from canary to non‑canary – Set
hinted_handoff_throttle_in_kb: 0on the canary nodes only (prevents them from sending hints to the rest of the cluster while testing removal).# Update cassandra.yaml on canary nodes, then restart sudo sed -i 's/^hinted_handoff_throttle_in_kb:.*/hinted_handoff_throttle_in_kb: 0/' /etc/cassandra/cassandra.yaml sudo systemctl restart cassandra
Monitoring and Feedback Mechanisms
- Real‑time dashboards – Graph hint counters, read/write latency, and timeout rates for the canary traffic stream.
- Alert thresholds – Pre‑define:
- Latency increase > 20 % over baseline → pause rollout.
- Timeout rate > 0.5 % of canary RPS → abort and rollback.
- Hint drop rate > 90 % with no latency regression → proceed.
- Log‑based verification – Enable trace logging on canary nodes (
log_level: DEBUGfororg.apache.cassandra.service.StorageProxy) and grep forHintedHandoffManager. - Automated verification script – A short Python/Bash loop that queries the metrics API every 10 s and exits with non‑zero if any threshold is breached.
Implementing Rollback Thresholds
Defining Threshold Metrics
| Metric | Safe Range (baseline ± X) | Rollback Trigger |
|---|---|---|
| 99th‑pct read latency (ms) | ≤ baseline × 1.2 | > baseline × 1.2 |
| 99th‑pct write latency (ms) | ≤ baseline × 1.2 | > baseline × 1.2 |
| Timeout errors per second | ≤ baseline × 1.1 | > baseline × 1.1 |
| Hint count (total) | ≥ baseline × 0.1 (not completely drained) | < baseline × 0.1 for > 2 min |
Cluster-wide gossip DOWN count | 0 | > 0 |
These thresholds are operational (based on observed variance), not system guarantees; they rely on the operator to act when breached.
Automated Rollback Triggers
- Prometheus alert rule (example):
- alert: TopologyHintRemediationLatencyHigh expr: histogram_quantile(0.99, sum(rate(read_latency_seconds_bucket[5m])) by (le)) > 0.00024 # 240 ms for: 2m labels: severity: critical annotations: summary: "Read latency exceeded safe threshold on canary" description: "Latency is {{ $value }}s, baseline is {{ $baseline }}s." - Alertmanager webhook triggers a rollback script that:
- Re‑applies the original
cassandra.yamlhint settings on canary nodes. - Restarts the Cassandra service.
- Sends a notification to the on‑call channel.
- Re‑applies the original
Manual Intervention Points
- Pre‑commit checkpoint – After updating canary nodes but before setting hint throttle to zero, run a manual verification (
nodetool status+ hint check) and sign off in the change ticket. - Post‑step verification gate – After each batch of nodes, review the dashboard; if any metric is amber (approaching threshold), pause and investigate before proceeding.
- Emergency stop – A dedicated Slack command (
/remediation-stop) that instantly runs the rollback script on all touched nodes.
Executing the Remediation Plan
Step‑by‑Step Procedure
| Phase | Action | Verification Gate |
|---|---|---|
| 0 – Prep | Export baseline metrics, tag canary traffic, verify health checks. | All pre‑checks pass; canary traffic isolated. |
| 1 – Hint Throttle Zero | Set hinted_handoff_throttle_in_kb: 0 on canary nodes (prevents new hints). | Hint increase rate drops to ~0 within 2 min (JMX HintedHandoffManager). |
| 2 – Disable Hint Persistence | Set max_hint_window_in_ms: 0 (or comment out) to stop hint storage. | No new hint files appear in /var/lib/cassandra/hints. |
| 3 – Flush Existing Hints | Run nodetool disablehints (or nodetool flush then nodetool drain on each canary node) to discard in‑flight hints. | Hint count reported by JMX drops to zero. |
| 4 – Validate Traffic | Run synthetic read/write workload against canary clients for 5 min. | Latency & error rates within safe bounds; no timeout spikes. |
| 5 – Roll‑out to Next Batch | Select next 3‑5 nodes (different rack, same zone) and repeat steps 1‑4. | Same verification gate; if any gate fails, trigger rollback for all touched nodes. |
| 6 – Full‑Zone Sweep | After all nodes in the affected zone have been processed, remove the per‑node throttle zero and restore default hint TTL (if desired). | Cluster‑wide hint metrics show near‑zero; latency stable across zones. |
| 7 – Global Clean‑up (Optional) | If keeping hints disabled globally, update global cassandra.yaml and roll a staged restart (same canary pattern) across the entire cluster. | Final validation: hint counters remain zero, SLA met. |
Code/CLI Examples for Topology Hint Removal
Cassandra (nodetool)
# 1. Disable hint throttle on a node (yaml edit)
sudo sed -i 's/^hinted_handoff_throttle_in_kb:.*/hinted_handoff_throttle_in_kb: 0/' /etc/cassandra/cassandra.yaml
sudo systemctl restart cassandra # reload if supported, otherwise restart
# 2. Disable hint persistence (max_hint_window)
sudo sed -i 's/^max_hint_window_in_ms:.*/max_hint_window_in_ms: 0/' /etc/cassandra/cassandra.yaml
sudo systemctl restart cassandra
# 3. Flush existing hints (immediate)
nodetool disablehints # stops accepting new hints
nodetool flush # forces memtable to SSTable; hints cleared on flush
# Verify
nodetool gossipinfo | grep Hint
# Expected: HintedHandoffManager: ActiveHints=0
ScyllaDB (scylla-cli)
# Truncate hints table
cqlsh -e "TRUNCATE system.hints;"
# Disable hinted handoff via scylla.yaml
sudo sed -i 's/^hinted_handoff_enabled:.*/hinted_handoff_enabled: false/' /etc/scylla/scylla.yaml
sudo systemctl restart scylla
CockroachDB – Cockroach does not use hinted handoff; the analogous knob is kv.rangefeed.enabled. For this article we assume a Cassandra‑style system.
Verification of Successful Removal
- JMX/MBean –
org.apache.cassandra.metrics:type=HintedHandoff,name=WaitingHintsshould report0. - File system –
ls -l /var/lib/cassandra/hints/shows no.Hintfiles. - Trace – Enable request tracing (
cqlsh -e "TRACING ON"), run a query, and confirm the trace does not contain aHintedHandoffstage. - Metrics – Graph
cassandra_thread_pool_pending_tasksforHintedHandoffPool– should stay at zero.
Monitoring and Validation
Proof Points for Successful Remediation
- Hint Count = 0 for ≥ 5 min across all nodes in the remediated zone.
- 99th‑p latency ≤ baseline × 1.05 (no regression).
- Timeout rate ≤ baseline × 1.05.
- No new hint files created in the hint directory.
- Gossip convergence – all nodes report
UN(Up Normal) and noLEAVING/JOINGstates.
If any proof point fails, the rollback trigger must fire.
Identifying and Addressing Local Zone Problems
- Local hotspot – If a single rack shows higher latency after hint removal, check token distribution with
nodetool ring. - Repair backlog – Stale hints can mask anti‑entropy delays; run
nodetool repair -pron the affected rack to catch up. - Client‑side retry storms – Increase client-side timeout or enable exponential backoff if retries surge after hint removal.
Preventing Cluster‑Wide Rebalance Shock
- Gradual scope – Never hint‑disable more than one failure zone at a time.
- Throttle rebalancing – Set
stream_throughput_outbound_megabits_per_secto a low value (e.g., 20 Mbps) during remediation to limit streaming traffic when nodes re‑evaluate replica placement. - Pause automatic bootstraps – Disable
auto_bootstrap: truetemporarily (nodetool pausehandoff) to stop new nodes from streaming data while hints are cleared. - Monitor
PendingCompactionsandPendingFlushes– spikes indicate catch‑up effort; if they exceed 2× baseline, pause further node batches.
Troubleshooting Common Issues
Identifying and Resolving Traffic Timeouts
| Symptom | Likely Cause | Diagnostic | Fix |
|---|---|---|---|
| Sudden rise in read timeouts after hint removal | Clients still routing to replicas based on stale hints cached in driver | Enable driver‑side logging (com.datastax.driver.core.QueryLogger) | Refresh driver metadata (cluster.getMetadata().refresh()) or restart client pods |
| Write timeouts only in one rack | Uneven hint distribution causing overloaded replicas | nodetool tpstats shows high MutationStage pending | Run nodetool repair on the rack, then consider temporary write‑rate throttling |
Hint count stays high despite disablehints | Hint files generated faster than flushed | Check system.log for HintedHandoffManager messages | Increase memtable_flush_writers or reduce write load temporarily |
End of document.