Prefer the nearest data center
Below are examples of setting the "prefer the nearest data center" balancing algorithm in different YDB SDKs.
package main
import (
"context"
"os"
"github.com/ydb-platform/ydb-go-sdk/v3"
"github.com/ydb-platform/ydb-go-sdk/v3/balancers"
)
func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
db, err := ydb.Open(ctx,
os.Getenv("YDB_CONNECTION_STRING"),
ydb.WithBalancer(
balancers.PreferLocalDC(
balancers.RandomChoice(),
),
),
)
if err != nil {
panic(err)
}
defer db.Close(ctx)
// ...
}
Client-side balancing in the YDB database/sql driver happens only when opening a new connection (in database/sql terms), which corresponds to a YDB session on a specific node. After the session is created, all queries on that session go to that node. Queries on the same YDB session are not balanced across nodes.
Example for "prefer the nearest data center" balancing:
package main
import (
"context"
"database/sql"
"os"
"github.com/ydb-platform/ydb-go-sdk/v3"
"github.com/ydb-platform/ydb-go-sdk/v3/balancers"
)
func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
nativeDriver, err := ydb.Open(ctx,
os.Getenv("YDB_CONNECTION_STRING"),
ydb.WithBalancer(
balancers.PreferLocalDC(
balancers.RandomChoice(),
),
),
)
if err != nil {
panic(err)
}
defer nativeDriver.Close(ctx)
connector, err := ydb.Connector(nativeDriver)
if err != nil {
panic(err)
}
db := sql.OpenDB(connector)
defer db.Close()
// ...
}
The YDB C++ SDK uses the prefer_local_dc (prefer nearest data center) algorithm by default.
#include <ydb-cpp-sdk/client/driver/driver.h>
int main() {
auto connectionString = std::string(std::getenv("YDB_CONNECTION_STRING"));
auto driverConfig = NYdb::TDriverConfig(connectionString)
.SetBalancingPolicy(NYdb::TBalancingPolicy::UsePreferableLocation());
NYdb::TDriver driver(driverConfig);
// ...
driver.Stop(true);
return 0;
}
import os
import ydb
driver_config = ydb.DriverConfig(
endpoint=os.environ["YDB_ENDPOINT"],
database=os.environ["YDB_DATABASE"],
credentials=ydb.credentials_from_env_variables(),
use_all_nodes=False, # prefer the nearest data center
)
with ydb.Driver(driver_config) as driver:
driver.wait(timeout=5)
# ...
import os
import ydb
import asyncio
async def ydb_init():
driver_config = ydb.DriverConfig(
endpoint=os.environ["YDB_ENDPOINT"],
database=os.environ["YDB_DATABASE"],
credentials=ydb.credentials_from_env_variables(),
use_all_nodes=False, # prefer the nearest data center
)
async with ydb.aio.Driver(driver_config) as driver:
await driver.wait()
# ...
asyncio.run(ydb_init())
import os
import sqlalchemy as sa
engine = sa.create_engine(
os.environ["YDB_SQLALCHEMY_URL"],
connect_args={
"driver_config_kwargs": {
"use_all_nodes": False, # prefer the nearest data center
}
},
)
This section is under development.
import tech.ydb.core.grpc.BalancingSettings;
import tech.ydb.core.grpc.GrpcTransport;
try (GrpcTransport transport = GrpcTransport.forConnectionString("grpc://localhost:2136/local")
.withBalancingSettings(BalancingSettings.detectLocalDs())
.build()) {
// ...
}
See JDBC driver properties; configure balancing via the native transport if needed.
In Spring Boot, ORMs, and other JDBC wrappers, use the same JDBC URL and balancing settings as with the driver directly (for example spring.datasource.url or DataSource properties).