New to Kestra?
Use blueprints to kickstart your first workflows.
Audits Apache Cassandra hinted handoff delivery queues during node recovery, calculating backlog pressure and alerting SREs on Slack.
In distributed Apache Cassandra architectures, coordinators temporarily store write mutations as hints on local disk when a peer replica node becomes unreachable. When that recovering node rejoins the cluster, coordinators initiate replay sequences to flush accumulated hints.
During major network partitions or prolonged rolling node restarts, millions of pending hints build up across surviving coordinators. Once the recovering instance announces availability, all coordinators attempt simultaneous parallel hint replay, triggering a classic hinted handoff storm. This saturated flood exhausts coordinator JVM heap buffers, causes GC pauses, and chokes inter-datacenter network links.
This blueprint provides an automated cluster durability sentinel. Running on a recurrent ten-minute schedule, it monitors Cassandra StorageMetrics metrics via Prometheus/JMX endpoints, calculates total in-flight and pending handoffs against safety limits, and delivers proactive alerts to SRE teams before cascading node failures happen.
poll_cassandra_hints trigger (io.kestra.plugin.core.trigger.Schedule) initiates the metric scan every ten minutes.scan_hinted_handoff_metrics task (io.kestra.plugin.scripts.python.Script) fetches coordinator metrics, aggregating total hints created, succeeded, timed out, and currently in flight.evaluate_handoff_storm flowable task (io.kestra.plugin.core.flow.If) evaluates whether pending or in-flight hints exceed designated saturation thresholds.alert_slack_handoff_storm (io.kestra.plugin.slack.notifications.SlackIncomingWebhook) delivers an actionable notification with diagnostic commands (nodetool statushandoff, nodetool disablehandoff).log_nominal_hint_flow logs cluster operational health.export_handoff_manifest task emits structured JSON telemetry for Datadog, Grafana, or operational dashboards.flowchart TD
A[Schedule: Every 10 Minutes] --> B[scan_hinted_handoff_metrics: Cassandra StorageMetrics]
B --> C{Handoff Storm Detected?}
C -- Yes --> D[alert_slack_handoff_storm: Slack Webhook]
C -- No --> E[log_nominal_hint_flow: Log]
D --> F[export_handoff_manifest: Return JSON]
E --> F
| Name | Type | Default | Description |
|---|---|---|---|
jmx_exporter_url |
STRING | "http://localhost:7070/metrics" |
Prometheus or JMX exporter endpoint exposing Cassandra StorageMetrics. |
hinted_handoff_threshold |
INT | 50000 |
Maximum pending hinted handoff mutations threshold before declaring a storm. |
max_hints_in_flight |
INT | 10000 |
Maximum allowable concurrent hints being dispatched to recovering nodes. |
slack_channel |
STRING | "#cassandra-reliability" |
Slack channel destination for distributed storage reliability notifications. |
{{ outputs.scan_hinted_handoff_metrics.vars.has_storm }}: Boolean flag indicating if a hinted handoff storm is active.{{ outputs.scan_hinted_handoff_metrics.vars.pending_hints }}: Calculated backlog of pending hints waiting for delivery.{{ outputs.scan_hinted_handoff_metrics.vars.in_flight_hints }}: Number of hints currently in flight to target replicas.{{ outputs.scan_hinted_handoff_metrics.vars.hints_timed_out }}: Count of expired hints dropped past max_hint_window_in_ms.{{ outputs.scan_hinted_handoff_metrics.outputFiles['cassandra_hint_report.json'] }}: Structured diagnostic JSON artifact.SLACK_WEBHOOK_URL: Slack Incoming Webhook endpoint URL with permissions to post messages.SLACK_WEBHOOK_URL in your Kestra namespace secrets.jmx_exporter_url with the network address of your Cassandra coordinator or Prometheus service.max_hint_window_in_ms); monitor hints_timed_out to identify when full nodetool repair is required instead of relying on handoffs.cassandra_storage_ or jvm_cassandra_storage_; ensure your scraper regex accommodates your specific exporter naming convention.nodetool sethintedhandoffthrottlekb via SSH or Ansible when handoff pressure surges.nodetool repair --in-dc on recovering nodes if hints_timed_out exceeds zero.