Replies: 1 comment 6 replies
|
We've been hitting the "only one snapshot at a time" limitation from a slightly different angle, and built a working prototype of the internal concurrency pieces from this proposal, specifically for Postgres source + Postgres storage on storage v2. Sharing the data here since it speaks directly to a couple of the open points, particularly the op-id / consistency question. Context: with wildcard schemas (#703), one sync config resolves to hundreds of source tables (tables x tenant schemas). On our deployment (200+ tenant schemas), initial replication snapshots them strictly sequentially, and a full re-replication takes hours. The "stream while snapshotting" work landed for MongoDB (#641), but the Postgres side (#426) was closed, so this path is still open here. Where the time actually goesInstrumented
Raising PrototypeBranch:
This leans on two existing properties, which I think are the reason it works on v2 without touching the consistency model: each table records its own consistency LSN ( Results on a small staging host, 4 workers:
On the points from the proposal"Consider using a worker_thread per worker to remove the CPU as a bottleneck." Confirmed on our host. Above ~1.55x the ceiling is the Node main thread, pegged at ~99% of one core (decode, bucket eval and wire serialization share it). The inflated stream-wait values above are event loop queueing, not a slow source. So the CPU bottleneck is real and single-process concurrency alone tops out fairly quickly; worker_threads (or the multi-process model in this proposal) is what unlocks the rest. "Pre-generate op-id sequence number batches for each worker... we'll need to thoroughly investigate consistency guarantees." In the prototype the workers do not pre-allocate op-id ranges; each writer just calls One concrete bug found along the way. One more, orthogonalThe An opt-in hint (e.g. Happy to adapt any of this to fit how you'd like the Postgres side to land relative to the multi-process model here. Tenant schemas are renamed in the logs above. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Background
Currently, we recommend running exactly one replication process. This process is responsible for replicating both "active" and "reprocessing" sync rules, doing both streaming replication and snapshot replication for each.
This has various issues:
This work forms part of the larger Incremental reprocessing project.
Proposal
The basic idea is to allow multiple processes to do replication concurrently, with a configurable number of "workers" on each.
New config option:
This configures the number of workers in each process. By specifying the max as 1 and running multiple processes, we avoid the performance issues from concurrent processing within one process.
Additionally, the CLI "role" option will be expanded to get two new sub-options:
--role replication(same as the current--role sync, just a rename to be less ambiguous)--role replication:streaming--role replication:snapshotThis can restrict the worker(s) in a process to only do streaming or snapshot replication, instead of both.
Auto-scaling
The metrics produced by replication workers will be expanded to include some new ones:
This can then be used with HPA config for auto-scaling:
powersync run -r replication:streaming, min replicas = 1, target replicas = powersync_total_stream_count, max replicas = 2.powersync run -r replication:snapshot, min replicas = 0, target replicas = powersync_pending_snapshot_count, max replicas = 4.This config will run a single streaming replication process in the steady state, but up to 5 additional processes to handle re-replication and snapshots.
Internal concurrency improvements
To take full advantage of this, we need some internal improvements:
a. This one could be tricky - we'll need to thoroughly investigate consistency guarantees.
Deployment architecture
While the new options give flexibility in how the replication process(es) are deployed, we'll have a couple of recommended setups:
powersync run -r replicationwithreplication.workers_per_process = 4, and generous CPU and memory limits (say cpu: 2 and memory: 2Gi). This simplifies the deployment compared to auto-scaling, at the cost of more resource usage.powersync run -r replicationwithreplication.workers_per_process = 2, and smaller CPU and memory limits. This is effectively the same setup as before these changes, and could still be a good choice for development setups.powersync run -r replication,replication.workers_per_process = 1. This is similar to the single large process setup, but gives some redundancy.Processing priorities
Work is prioritized in this order:
Note that:
Relation to incremental reprocessing
The changes here can be implemented independently, but are also part of the larger Incremental reprocessing project. That project affects this in some ways:
All reactions