Was this page helpful?
Client routes (PrivateLink / Private Service Connect)¶
Client routes let the driver connect to a ScyllaDB Cloud cluster through private
endpoints instead of the public host addresses. ScyllaDB Cloud exposes a
system.client_routes table that maps each host to the private endpoint that
serves it; when client routes are enabled, the driver reads that table and
translates every host address to its per-host private endpoint address and port.
Client routes require server support for both system.client_routes and the
CLIENT_ROUTES_CHANGE event.
This feature is also known as PrivateLink support, private link,
private service connection, AWS PrivateLink (PL), and GCP
Private Service Connect (PSC). The driver API is named after the
system.client_routes table, so it is also written as client_routes or
clientroutes.
Limitations¶
Mixed clusters are not supported. Every node must be reachable through client
routes, that is, have a row in system.client_routes for one of the connection
IDs you configured. If a node has no matching route, the driver fails to translate
its address and does not fall back to the node’s broadcast address — connections to
that node fail.
Enabling client routes¶
Use WithClientRoutes and pass the connection IDs you receive from
ScyllaDB Cloud:
cluster := gocql.NewCluster("private-link.dns.name")
cluster.WithOptions(
gocql.WithClientRoutes(
gocql.WithEndpoints(
gocql.ClientRoutesEndpoint{ConnectionID: "your-connection-id"},
),
),
)
At least one connection ID is required. Configuring client routes without any
endpoint is a configuration error and session creation fails. Every configured
endpoint must have a non-empty ConnectionID.
The driver loads route rows and accepts route-change events only for configured connection IDs.
Note that the contact points themselves are not translated. Translation is
keyed by host ID, and the initial contact point has no host ID yet, so it is dialed
exactly as configured. The address you pass to NewCluster must therefore already
be reachable from the client — normally a private endpoint address. Only the cluster
nodes the driver subsequently discovers are routed through system.client_routes.
Multiple connection IDs¶
If your deployment routes traffic through more than one private endpoint — for
example one per availability zone — configure all of them. WithEndpoints is
variadic, and each row of system.client_routes is matched against the whole
list:
cluster := gocql.NewCluster()
cluster.WithOptions(
gocql.WithClientRoutes(
gocql.WithEndpoints(
gocql.ClientRoutesEndpoint{
ConnectionID: "conn-id-az-1",
ConnectionAddr: "endpoint-az-1.eu-west-1.vpce.amazonaws.com",
},
gocql.ClientRoutesEndpoint{
ConnectionID: "conn-id-az-2",
ConnectionAddr: "endpoint-az-2.eu-west-1.vpce.amazonaws.com",
},
),
),
)
When several configured endpoints provide a route to the same host, the driver
picks one preferred route per host and keeps using it until that route disappears.
A connection-health failure alone does not switch routes. If a
CLIENT_ROUTES_CHANGE update removes the selected route, the next translation
selects another configured route for that host.
Overriding the endpoint address¶
ClientRoutesEndpoint has two fields:
Field |
Description |
|---|---|
|
Required. The ScyllaDB Cloud connection ID to read from
|
|
Optional. IP address or DNS name of the private endpoint. When empty, the
driver uses the address from the |
ConnectionAddr has a second effect: if the cluster has no hosts configured when
WithClientRoutes is applied, every non-empty ConnectionAddr is also used as
an initial contact point. This lets you seed the cluster entirely from private
endpoint hostnames:
cluster := gocql.NewCluster() // no public contact points
cluster.WithOptions(
gocql.WithClientRoutes(
gocql.WithEndpoints(
gocql.ClientRoutesEndpoint{
ConnectionID: "your-connection-id",
ConnectionAddr: "vpce-0123456789abcdef.vpce-svc-0123456789abcdef.eu-west-1.vpce.amazonaws.com",
},
),
),
)
These inferred contact points use ClusterConfig.Port, which defaults to
9042. Specify contact points explicitly with NewCluster when bootstrap
endpoints use different ports. An embedded port applies only while dialing that
contact point; connections to discovered hosts use port or tls_port from
the route table.
TLS¶
TLS is supported. system.client_routes exposes both a plain port and a
tls_port for each route; the driver selects both columns in its query and uses
the tls_port whenever ClusterConfig.SslOpts is set. Every selected TLS
route must provide tls_port. No client-routes-specific TLS configuration is
needed.
Custom HostDialer implementations are not supported with client routes.
HostInfo exposes the translated route address but not its translated port,
so a custom host dialer may use the node-advertised port instead. Use
ClusterConfig.Dialer when client routes require custom dialing.
Configuration options¶
Option |
Description |
|---|---|
|
Sets the private endpoints to use. At least one is required. |
|
Overrides the route table for tests. Production use requires
|
|
Opts in to advanced shard awareness. Disabled by default. See Shard awareness. |
Deprecated options¶
The following options no longer have any effect and will be removed in a future
release: WithMaxResolverConcurrency, WithResolveHealthyEndpointPeriod, and
the ClientRoutesConfig fields ResolveHealthyEndpointPeriod,
ResolverCacheDuration, MaxResolverConcurrency, and
BlockUnknownEndpoints. Unknown endpoints are always blocked.
How routes are kept up to date¶
The driver reads system.client_routes once when the session starts, and then
refreshes it in response to events rather than by polling:
a
CLIENT_ROUTES_CHANGEevent is filtered down to the connection IDs you configured, and ignored if none of them remain. If the event also names host IDs, only those (connection ID, host ID) pairs are re-read; if it names none, every host on the affected connection IDs is re-read;if the control connection is recreated, all configured connection IDs are re-read.
The driver only registers for CLIENT_ROUTES_CHANGE when client routes are
configured.
Interaction with AddressTranslator¶
Client routes are implemented as an address translator. ClientRoutesConfig and
ClusterConfig.AddressTranslator are therefore mutually exclusive — setting both
fails validation with AddressTranslator and ClientRoutesConfig should not be set
at the same time.