Skip to content

AxonOps — AI-Native Control Plane for Open Source Data Platforms

Phase 2: Astra DB to Apache Cassandra Data Migration (ZDM Proxy and CDM)

This phase moves the data. It assumes completion of ZDM Proxy and Data-Copy Setup: the proxy and bulk-copy tooling are configured to connect to Astra as the origin. It begins with standing up the target Apache Cassandra cluster, then moves traffic and data across.

The migration runs with no downtime. The proxy keeps the application serving traffic throughout, dual-writing to both databases while existing data is copied across in the background. For a typical dataset the copy runs over a few days depending on data volume, network bandwidth, and compaction load on the target.

Stand up a new open-source Apache Cassandra cluster sized for the workload, choosing the topology (node count, datacenters, replication factors) appropriate for the intended deployment. Install the monitoring agent on each node and confirm every node reports UN (Up/Normal) in nodetool status. Then recreate the schema, roles, and credentials captured during assessment before the proxy starts dual-writing, as set out in the target preparation prerequisite.

When migrating from a managed service, the operator takes on cluster management responsibilities. The install should be automated rather than built node by node; automation makes the cluster repeatable and consistent, removes a whole class of human error, and makes scaling, rebuilding, or standing up matching test and production environments a routine operation. AxonOps publishes ready-to-use configuration management for this purpose: the AxonOps Ansible collection and the AxonOps Chef cookbook install and configure Apache Cassandra together with the axon-agent that connects to AxonOps Cloud or to a self-hosted axon-server. For other approaches, such as baking golden machine images, AxonOps can assist in selecting one suited to the organisation's tooling. See why Ansible is recommended for Cassandra in the installation guide to get started.

Astra handled time synchronization automatically. On a self-managed cluster, clock synchronization is the operator's responsibility and has material consequences. In all Cassandra versions, conflicting writes are resolved by timestamp (last write wins) and TTL expiry is timestamp-driven, so the nodes in a cluster must have closely synchronised clocks. If clocks drift, writes may appear lost, deleted data may reappear, and reads may differ depending on which replica answers. Configure a reliable time service (for example, chrony) on every node before the cluster takes traffic, and point all nodes at the same time source: the cloud provider's NTP service (such as time.aws.com or time.google.com) in the cloud, or a dedicated set of NTP servers on-premises. Monitor clock offset on an ongoing basis; AxonOps surfaces per-node NTP offset, confirming that cluster clocks are synchronized and alerting when a node starts to drift. See AxonOps for Cassandra.

  1. Deploy the ZDM Proxy between the application and both databases, and repoint the application at the proxy. Reads go to Astra; writes are dual-written to both Astra and the target. From this moment, all new data is kept in sync on both sides.
  2. Review the copy-tool caveats for collections, user-defined types (UDTs), and TTLs before starting the bulk copy. See Operational Caveats.
  3. Run the bulk copy to move the data that already existed in Astra before dual-writes began. With CDM, copy user-table data from the origin to the target and let it validate row-level consistency. Redirect its output to a log file so any issues can be investigated. For assistance running CDM, contact AxonOps.
  4. Review the copy logs. Confirm the error set is acceptable. If not, re-run the copy, because subsequent passes reduce the error count.
  5. Enable asynchronous dual reads in the proxy configuration so that reads are served against both databases and the target's read path is exercised under real load ahead of cutover.

CDM is the recommended tool for this migration, because it copies and validates row-level consistency out of the box. Other tools can perform the bulk copy with the same ZDM Proxy dual-write setup; only the bulk-backfill tool changes. DataStax Bulk Loader (DSBulk) unloads a table from Astra to files and loads them into the target, connecting to Astra with the Secure Connect Bundle (-b) and the token username and to the target with host, port, and credentials; validate with dsbulk count (see Validation). Apache Spark, using the open-source spark-cassandra-connector, reads from Astra via the Secure Connect Bundle and writes to the target; this suits teams who already run Spark or have existing ETL pipelines. With DSBulk or Spark, the operator builds and validates the copy logic separately, whereas CDM provides both out of the box.

Preserve write timestamps and TTLs during the bulk copy

Problem: The bulk copy must carry the original write timestamps and TTLs on every row. Without them, every migrated row appears to have been written at migration time.

Symptoms: TTL-based expiry is broken (data lives too long or expires at the wrong time), and last-write-wins conflict resolution is corrupted against concurrent dual-writes.

Instead: CDM preserves write timestamps and TTLs by default. Tools that do not, such as DataStax Bulk Loader (DSBulk) or Apache Spark, must be configured to carry the original timestamp and TTL on every row.

Size the bulk-copy host and the target cluster for the data volume: an undersized copy host runs out of memory or drags on for days, and an undersized target cannot absorb the write load. Tune the target to be write-tolerant during the bulk phase, then re-tune for the normal read/write mix once the copy is done. When using a file-based tool such as DSBulk, delete the intermediate dump files after each table loads successfully so a large migration does not fill the disk. Script and version-control the copy commands, proxy deployment, and validation so the process is repeatable across test and production runs.

If the data has short TTLs (days or weeks), the bulk copy may be skippable. Deploy the ZDM Proxy with dual-writes enabled and leave it running until all pre-existing data in Astra has expired naturally. Once the TTL window has passed, the target holds a complete dataset from dual-writes alone. This trades migration time for simplicity.

Counter tables do not fit the standard dual-write and bulk-copy flow, and getting them wrong produces silently incorrect totals. Plan for them separately.

The problem is that counter updates are increments, not absolute values, and they are not idempotent. During the migration the proxy dual-writes each new increment to both Astra and the target, while the bulk copy carries the existing counter total from Astra to the target. Any increment that lands during the copy window is then applied to the target twice (once in the copied total and once through the dual-write), or missed entirely, depending on ordering. Either way the target ends up with the wrong value. For this reason CDM does not copy counter tables when missing by default.

The safe approach is to take counter tables out of the main flow and migrate them in a dedicated step:

  1. Exclude counter tables from the bulk copy used for the rest of the data.
  2. Migrate each counter table once, with no concurrent increments to double-count. In practice this means copying the authoritative counter values during a short window in which updates to those specific tables are paused or quiesced, so nothing is counted twice.
  3. Direct counter traffic to the target as part of cutover, so increments resume against the migrated values.

The right sequencing depends on how the application uses counters, for example whether increments can be paused briefly, and whether the values are recomputable from source data. If counters are central to the workload, talk to AxonOps so the approach can be designed and tested for the specific case before migration.

Go: no dropped read or write requests on either side, and the bulk copy has completed with an acceptable, understood error set.

Rollback: reconfigure the ZDM Proxy to route all traffic back to Astra, and remove the target cluster. Because reads have not yet been switched to the target, this is a clean rollback.

Cluster-level monitoring does not see what happens inside the proxy layer. The AxonOps ZDM Proxy fork exposes migration metrics (origin reads, dual reads, and target reads) that surface degradations or failures visible only at the proxy; run these alongside monitoring on the target cluster. See AxonOps for Cassandra.

Once the data is copied and dual reads are running cleanly, move on to Validation.