Drivers in clustered TypeDB
TypeDB gRPC drivers connect to TypeDB clusters and operate across multiple server replicas automatically.
|
Clustering is released and generally available in TypeDB Enterprise and TypeDB Cloud, starting from TypeDB server version 3.14.1. Use TypeDB drivers 3.14.0 or later. |
This page covers the gRPC drivers; for HTTP clients, including the TypeScript HTTP driver, see the HTTP API reference.
Connecting to a cluster
A driver accepts a single address, several addresses, or an address translation map. See How clients reach the replicas to choose between addresses and translation.
Single address
Connect through any one replica; the driver learns the others from it:
-
Python
-
Java
-
Rust
driver = TypeDB.driver("host1:port1", credentials, driver_options)
Driver driver = TypeDB.driver("host1:port1", credentials, driverOptions);
let driver = TypeDBDriver::new(
Addresses::try_from_address_str("host1:port1").unwrap(),
credentials,
driver_options,
)
.await
.unwrap();
Multiple addresses
Provide several replica addresses so that the driver can still make first contact while some replicas are down:
-
Python
-
Java
-
Rust
driver = TypeDB.driver(
["host1:port1", "host2:port2", "host3:port3"],
credentials,
driver_options
)
Driver driver = TypeDB.driver(
Set.of("host1:port1", "host2:port2", "host3:port3"),
credentials,
driverOptions
);
let driver = TypeDBDriver::new(
Addresses::try_from_addresses_str(["host1:port1", "host2:port2", "host3:port3"]).unwrap(),
credentials,
driver_options,
)
.await
.unwrap();
Address translation
When the replicas' advertise addresses are not reachable from the client, map the address the client reaches each replica at to that replica’s gRPC advertise address (server.advertise-address, exactly as configured).
Include every replica: a replica missing from the map is contacted at its advertise address.
The driver connects to the map’s keys, and reports them as the replicas' addresses.
-
Python
-
Java
-
Rust
translation = {
"typedb-1.example.com:1729": "10.0.0.1:1729",
"typedb-2.example.com:1729": "10.0.0.2:1729",
"typedb-3.example.com:1729": "10.0.0.3:1729",
}
driver = TypeDB.driver(translation, credentials, driver_options)
Map<String, String> translation = Map.of(
"typedb-1.example.com:1729", "10.0.0.1:1729",
"typedb-2.example.com:1729", "10.0.0.2:1729",
"typedb-3.example.com:1729", "10.0.0.3:1729"
);
Driver driver = TypeDB.driver(translation, credentials, driverOptions);
use std::collections::HashMap;
let translation = HashMap::from([
("typedb-1.example.com:1729", "10.0.0.1:1729"),
("typedb-2.example.com:1729", "10.0.0.2:1729"),
("typedb-3.example.com:1729", "10.0.0.3:1729"),
]);
let addresses = Addresses::try_from_translation_str(translation)?;
let driver = TypeDBDriver::new(
addresses,
credentials,
driver_options,
).await?;
Failover and timeout options
Two DriverOptions settings matter most in a cluster; see the driver API reference for all options.
| Option | Description |
|---|---|
Primary failover retries |
How many times the driver looks for a new primary and retries a request after a connection failure, waiting 2 seconds between attempts while an election is in progress. Default value: |
Request timeout |
The longest time the driver waits for a response to a request outside a transaction, such as creating a database or opening a transaction. Queries and commits are not affected. Default value: 2 hours. |
-
Python
-
Java
-
Rust
driver_options = DriverOptions(
DriverTlsConfig.enabled_with_native_root_ca(),
primary_failover_retries=3,
request_timeout_millis=60_000,
)
DriverOptions driverOptions = new DriverOptions(DriverTlsConfig.enabledWithNativeRootCA())
.primaryFailoverRetries(3)
.requestTimeoutMillis(60_000);
let driver_options = DriverOptions::new(DriverTlsConfig::enabled_with_native_root_ca())
.primary_failover_retries(3)
.request_timeout(Duration::from_secs(60));
Inspect your cluster
The driver lists the servers of the cluster with their id, address, role (Primary, Secondary, or Candidate), and Raft term, and finds the primary and the server version.
The address is the server’s advertise address, or the client address mapped to it under address translation.
These inspection methods are routed automatically by default.
Pass ServerRouting.Direct with a server’s address, as reported by the driver, to ask that server instead, for example to see its own view of the cluster.
All other operations are always routed to the primary.
-
Python
-
Java
-
Rust
for server in driver.servers():
print(f"Server {server.id}: {server.address}, role={server.role}, term={server.term}")
primary = driver.primary_server()
if primary is not None:
print(f"Primary: {primary.address}")
version = driver.server_version(ServerRouting.Direct("10.0.0.2:1729")) # an address reported by driver.servers()
print(f"{version.distribution} {version.version}")
for (Server server : driver.servers()) {
System.out.printf("Server %d: %s, role=%s, term=%s%n",
server.getID(), server.getAddress(), server.getRole().orElse(null), server.getTerm().orElse(null));
}
driver.primaryServer().ifPresent(primary -> System.out.println("Primary: " + primary.getAddress()));
ServerVersion version = driver.serverVersion(new ServerRouting.Direct("10.0.0.2:1729")); // an address reported by driver.servers()
System.out.println(version.getDistribution() + " " + version.getVersion());
for server in driver.servers().await? {
if let Some(address) = server.address() {
println!("Server at {address}");
}
}
if let Some(primary) = driver.primary_server().await? {
println!("Primary: {}", primary.address());
}
let version = driver
// an address reported by driver.servers()
.server_version_with_routing(ServerRouting::Direct { address: "10.0.0.2:1729".parse().unwrap() })
.await?;
println!("{} {}", version.distribution(), version.version());
Next steps
-
Connect TypeDB Console to a cluster.
-
See the full driver API references in the gRPC drivers reference.
-
Operate the cluster itself: Administering a cluster.