Trino-Gateway is a load balancer / routing proxy / gateway primarily for Trino Query engine, written in Go and uses twirp framework.
-
Horizontally scalable - Each instance of the service is stateless, and a relational database is used for synchronization.
-
Cluster Monitoring - Periodic Trino Cluster healthchecks via a combination of SQL healthcheck queries, APIs.
-
Logical Grouping - Create multiple logical groups of Trino clusters, available routing strategies:
- round robin
- least load
- random
-
Routing policies - Traffic can be routed to logical groups of Trino clusters based on the following parameters:
-
Incoming socket (controlled by deployment infrastructure)
-
HTTP headers (controlled by client)
- client-tags
- connection-properties
- host
-
-
GUI for monitoring queries (EXPERIMENTAL)
-
swaggerUI for service administration
-
Provides REST APIs, gRPC and swaggerUI for service administration
SQL Transactions - Handling SQL transactions is half-baked in the app. Therefore, it is disabled, and the application will throw an exception (HTTP500) if the client tries to initiate transactions.
Proxy entire query lifecycle - A design decision to only route the query submission requests to the backend, so subsequent communication between the server and client happens directly. This removes data transfer overhead from the gateway but requires direct network connectivitybetween Trino clients and servers, which might be undesirable in certain scenarios.
The application requires a relational datastore to store the configs and query history.
Databases supported:
-
MySQL 8+
The DB user configured for the application currently needs full access to the Database.
Refer to Docker Image configs and setup the deployment container properties accordingly.
Refer to Docker Image configs and Build scripts
Default app configs are stored here.
Once the service is up and running head over to <hostname>:<configured app.port>/admin/swaggerui
default would be localhost:8000/admin/swaggerui
Before it can serve traffic, routing policies need to be configured.
- Create atleast one Backend
- Create atleast one Group
- Create Policies as required
All available API endpoints, and more info on their request parameters are available in swaggerUI. Proto file containing all the API contracts is present here
The application comprises of 3 components and they leverage gRPC for Inter-process communication.
-
gatewayserver - Serves as the admin service and contains the logic for interfacing with the service's storage and business logic for selecting Trino cluster to route an incoming query to. Uses twirp framework.
-
monitor - Performs periodic healthchecks of the configured
Backends
. Also tracks configured "uptime schedules" of the clusters and disables/enables them accordingly. -
router - Contains logic to act as a reverse proxy for clients.
The project aims to loosely follow golang-standards/project-layout structure
/third_party/swaggerui - Contains swaggerui distribution files
If you already have VS Code and Docker installed, you can click the badge above or here to get started. Clicking these links will cause VS Code to automatically install the Dev Containers extension if needed, clone the source code into a container volume, and spin up a dev container for use.
A container-based development environment can be set up in the project via docker-compose or similar tools with the only prerequisite being docker installation (or similar tools like podman + buildah etc).
Docker based env can be setup by invoking
make dev-docker-up
For more details check the Makefile
Rest of this section covers non-container based build environment.
-
Install Golang(It is recommended that the version matches exactly as defined in go.mod)
-
Install dependencies
Run
go mod download
make setup
- Setup a Mysql8 instance
make build build-frontend
note: building frontend takes time and can be skipped if there are no changes to frontend module.
Make required changes to app config
For bootstrapping the DB schemas
go run ./cmd/migration up
More available options can be found by running
go run ./cmd/migration
Once the DB schema is initialized, run the app
App uses uber/zap for logging with everything in single line json, use jq
or similar cli json parsers to prettify the logs.
go run ./cmd/gateway | jq
{{Add your org here}}
- Extract https://github.com/swagger-api/swagger-ui/tree//dist -> third_party/swaggerui
- Modify swagger-initializer.js to point to generated openApi spec
rough notes
Add DB query history purge logic.
Add initial setup configs
Integration tests
Fix GORM model regression in later version
Use https://github.com/samber/mo and https://github.com/samber/lo
Support Transactions (need sticky routing on transaction id), need caching layer or else performance is poor.
Setup cache layer for storing query_id -> backend_id mapping
Proper GUI - scope would be limited but current implementation of using vecty + gopherjs is hard to maintain and deploy.
Switch to Server side rendering for frontend eg: - https://hotwired.dev/ - https://github.com/wolfeidau/hotwire-golang-website
Tracing integration
Explore victoriaMetrics go client https://github.com/VictoriaMetrics/metrics
Handle routing errors properly instead of returning HTTP500 in all cases, eg: sql transaction request must return HTTP400 instead of HTTP500