VTGate’s connection pools are actually two distinct pools, one for talking to clients (your application) and another for talking to VTTablet.
# Example: VTGate client connection pool configuration (in vtgateservice.json)
{
"bind_address": ":15991",
"grpc_port": 15991,
"tablet_manager_grpc_port": 15992,
"mysql_server_port": 15990,
"cell": "zone1",
"tablet_manager_protocol": "grpc",
"grpc_max_message_size": 16777216,
"service_map": {
"vtgate": "/debug/vt/vtgate",
"vtctld": "/debug/vt/vtctld",
"vt tablet": "/debug/vt/tablet",
"throttler": "/debug/vt/throttler"
},
"access_control": {
"allow_all": true
},
"authentication": {
"builtin": {
"users": {
"user1": "password"
}
}
},
"gateway_implementation": "grpc",
"log_dir": "/vt/logs",
"metrics_dir": "/vt/metrics",
"tracing": {
"jaeger": {
"agent_host": "jaeger-agent",
"agent_port": 6831
}
},
"cluster_name": "mycluster",
"vtctld_grpc_addr": "localhost:15999",
"num_worker_threads": 16,
"buffer_pool_size": 4194304,
"session_payload_size": 1024,
"tx_coordinator_address": "",
"tx_mode": "multi",
"tx_timeout": 30,
"query_timeout": 120,
"max_workflow_duration": 3600,
"max_replication_lag": 600,
"tablet_watch_poll_interval": "1s",
"resource_manager_address": "",
"cell_alias": "zone1-alias",
"enable_active_reparents": true,
"enable_table_acl_policy": false,
"enable_query_plan_cache": true,
"query_plan_cache_size": 10000,
"schema_reload_interval": "10m",
"schema_change_listener": [],
"vtgate_conn_pool": {
"size": 50,
"idle_timeout": "5m",
"max_lifetime": "30m"
},
"vtgate_grpc_pool": {
"size": 50,
"idle_timeout": "5m",
"max_lifetime": "30m"
}
}
VTGate manages two primary connection pools:
-
Client Connection Pool (VTGate’s internal pool for incoming client connections): This pool is not directly configured by
vtgateservice.json. Instead, it’s managed by the underlying gRPC server. Thegrpc_max_message_sizeinvtgateservice.jsoninfluences the maximum size of individual RPC messages, indirectly affecting how much data can be sent in a single client request. The number of concurrent client connections is largely determined by the OS’s file descriptor limits and the gRPC server’s internal handling of goroutines. -
VTTablet Connection Pool (VTGate’s pool for outgoing connections to VTTablet): This is the pool you configure with
vtgate_conn_poolandvtgate_grpc_pool(for gRPC connections to VTTablet’svtctlservice).-
vtgate_conn_pool: This refers to the pool of MySQL connections VTGate maintains to eachVTTablet. When VTGate needs to execute a query against a specific tablet, it will grab a connection from this pool for that tablet.size: The maximum number of idle connections to maintain per tablet. A value of50means VTGate will try to keep up to 50 idle MySQL connections open to eachVTTabletit interacts with.idle_timeout: Connections idle for longer than5m(5 minutes) will be closed. This prevents resources from being held indefinitely by unused connections.max_lifetime: Connections will be closed and re-established after30m(30 minutes), even if they are active. This helps to mitigate issues like memory leaks or stale network states that can accumulate over time.
-
vtgate_grpc_pool: This refers to the pool of gRPC connections VTGate maintains to thevtctlserviceendpoint on eachVTTablet. These connections are used for administrative tasks and metadata retrieval, not for query execution.size: The maximum number of idle gRPC connections to maintain to eachVTTablet’svtctlservice.idle_timeout: gRPC connections idle for longer than5mwill be closed.max_lifetime: gRPC connections will be closed and re-established after30m.
-
The most surprising thing about VTGate’s connection pooling is that the pool for your application’s direct connections isn’t explicitly tunable in vtgateservice.json; it’s implicitly handled by the gRPC framework itself.
Let’s see VTGate in action. Imagine your application makes a SELECT * FROM users WHERE id = 1 query.
- The query arrives at VTGate’s gRPC server (listening on
bind_addressandgrpc_port). - VTGate’s query planner determines which tablet(s)
usersbelongs to. Let’s say it’szone1-0000000001. - VTGate needs to send this query to the
VTTabletprocess running onzone1-0000000001. - VTGate looks in its
vtgate_conn_poolfor an available MySQL connection tozone1-0000000001. - If a connection is available and healthy, it’s used. If not, VTGate establishes a new MySQL connection (up to the
sizelimit per tablet). - VTGate sends the
SELECTquery over this MySQL connection to theVTTablet. VTTabletexecutes the query against its local MySQL instance, retrieves the data, and sends it back to VTGate.- VTGate formats the result and sends it back to your application over the original incoming gRPC connection.
The vtgate_conn_pool is crucial because establishing new MySQL connections is relatively expensive. By keeping a pool of connections open to each tablet, VTGate can serve incoming queries much faster, avoiding the overhead of connection setup for every single query. The idle_timeout and max_lifetime settings help manage resource utilization and prevent stale connections from causing problems.
A key detail often missed is that the vtgate_conn_pool settings (size, timeouts) are applied per-tablet. If VTGate is routing queries to 100 different tablets, it can potentially maintain up to 100 * vtgate_conn_pool.size MySQL connections concurrently across the system, plus connections for its gRPC communication. This scale is essential for handling distributed workloads.
The next concept to explore is how VTGate handles transactions and their associated connection management, especially in distributed scenarios.