Fixed
Details
Details
Assignee
Unassigned
UnassignedReporter
Michael Penick
Michael PenickReviewer
Michael Penick
Michael PenickPull Request
Sprint
Fix versions
Priority
Created September 12, 2016 at 9:16 PM
Updated June 14, 2019 at 2:14 PM
Resolved July 11, 2018 at 8:59 PM
The current C++ driver's architecture funnels all requests through a single session queue that's processed by a single session thread which also manages the control connection. This session thread is responsible for keeping track of the Casandra cluster's state, updating request's with the current cluster's state (by giving it load balancing query plan), and distributing the request among I/O worker (using round robin which not ideal). This has the advantage of making it easy to share cluster state without having to worry about data races. However, It has several disadvantages:
All requests have be pushed through two thread-safe queues, one for the session, and one for the I/O worker.
Request throughput can be limited by the performance of a single thread
Requests processing can be delayed for control connection activity (rebuilding token maps and schema data)
Load balancing requests among the I/O workers is less than ideal. Currently, using a push model via round-robin.
Each session has to have it's own control connection.
In the new architecture, each session would have a single queue which I/O workers would share and pull requests from directly. That would allow the I/O workers to load balance themselves. Because each I/O worker can handle request directly it needs to have it's own read-only copy of the cluster's state (available hosts, token map, latency information, etc.). This cluster state would be kept up-to-date by a shared cluster (control connection) thread (transparently shared with multiple sessions) using libuv's asynchronous events. This dedicated cluster (control connection) thread would be responsible for manage processing events, building schema metadata, and building the token map. There would only be minimal synchronization required to share read-only copies of cluster state from the cluster thread to the I/O worker threads. This has approach has several advantages:
Only a single thread-safe queue required
Better request throughput and lower latency
I/O workers load balance themselves
Multiple-sessions can share a single control connection (this is transparent to the user)
I have a proof of concept going on this branch: https://github.com/mpenick/cpp-driver/tree/nextgen