docker.recipes

Vitess MySQL Sharding Cluster

advanced

Horizontal MySQL scaling with Vitess, VTGate routing, and tablet management.

Overview

Vitess is YouTube's battle-tested database clustering system that transforms MySQL into a horizontally scalable platform capable of handling massive workloads. Originally developed to manage YouTube's explosive growth, Vitess acts as a transparent proxy layer that provides MySQL sharding, connection pooling, and query routing without requiring application changes. The system uses VTGate as the stateless frontend that accepts MySQL connections and routes queries to appropriate shards, while VTTablet manages individual MySQL instances and handles tablet lifecycle operations. This clustering configuration combines Vitess components with etcd for distributed coordination, creating a production-ready sharded MySQL environment. VTGate serves as the MySQL-compatible entry point at port 3306, routing queries across multiple VTTablet instances that each manage their own MySQL data. The etcd cluster maintains topology information and coordinates tablet assignments, while VTCtld provides administrative control over the entire cluster through both web UI and command-line tools. This stack targets organizations experiencing MySQL scaling bottlenecks that single-server configurations cannot resolve. Companies with read-heavy workloads, large datasets requiring horizontal partitioning, or applications needing transparent sharding will benefit from Vitess's proven architecture. The included Prometheus and Grafana monitoring provides visibility into query performance, tablet health, and sharding effectiveness, making it suitable for production environments where observability is crucial.

Key Features

  • Transparent MySQL sharding with automatic query routing across multiple tablet instances
  • VTGate connection pooling and query optimization reduces database connection overhead
  • VTTablet automated failover and primary election for high availability within shards
  • VTCtld web interface for visual cluster management and topology monitoring
  • Etcd-based topology service maintains consistent cluster state and tablet assignments
  • MySQL-compatible protocol support allows existing applications to connect without modification
  • Built-in query rewriting and cross-shard join optimization
  • Integrated Prometheus metrics export for detailed performance monitoring and alerting

Common Use Cases

  • 1E-commerce platforms with growing product catalogs and user bases requiring horizontal MySQL scaling
  • 2SaaS applications implementing tenant-based sharding for multi-customer data isolation
  • 3Gaming companies managing player data and statistics across geographically distributed shards
  • 4Financial services platforms requiring high-availability transactional systems with read replica scaling
  • 5Content management systems with large media libraries needing transparent database partitioning
  • 6Analytics platforms processing time-series data with date-based sharding strategies
  • 7Social media applications managing user-generated content across multiple database instances

Prerequisites

  • Minimum 4GB RAM recommended for running multiple VTTablet instances with embedded MySQL
  • Basic understanding of MySQL sharding concepts and query routing principles
  • Familiarity with etcd cluster operations and distributed consensus systems
  • Available ports 3306, 15000, 15001, 15991, 2379, 9090, and 3000 for service access
  • Understanding of Vitess topology concepts including cells, keyspaces, and tablet types
  • Experience with Prometheus and Grafana for monitoring distributed database systems

For development & testing. Review security settings, change default credentials, and test thoroughly before production use. See Terms

docker-compose.yml

docker-compose.yml
1services:
2 etcd:
3 image: quay.io/coreos/etcd:v3.5.0
4 command:
5 - etcd
6 - --data-dir=/etcd-data
7 - --listen-client-urls=http://0.0.0.0:2379
8 - --advertise-client-urls=http://etcd:2379
9 volumes:
10 - etcd_data:/etcd-data
11 networks:
12 - vitess_net
13
14 vtctld:
15 image: vitess/lite:latest
16 command:
17 - vtctld
18 - --topo_implementation=etcd2
19 - --topo_global_server_address=etcd:2379
20 - --topo_global_root=/vitess/global
21 - --service_map=grpc-vtctl
22 ports:
23 - "15000:15000"
24 - "15999:15999"
25 depends_on:
26 - etcd
27 networks:
28 - vitess_net
29
30 vttablet-zone1-1:
31 image: vitess/lite:latest
32 command:
33 - vttablet
34 - --topo_implementation=etcd2
35 - --topo_global_server_address=etcd:2379
36 - --topo_global_root=/vitess/global
37 - --tablet-path=zone1-0000000001
38 - --init_keyspace=commerce
39 - --init_shard=0
40 - --init_tablet_type=replica
41 - --port=15001
42 - --grpc_port=16001
43 - --service_map=grpc-queryservice,grpc-tabletmanager,grpc-updatestream
44 volumes:
45 - vttablet1_data:/vt/vtdataroot
46 depends_on:
47 - vtctld
48 networks:
49 - vitess_net
50
51 vttablet-zone1-2:
52 image: vitess/lite:latest
53 command:
54 - vttablet
55 - --topo_implementation=etcd2
56 - --topo_global_server_address=etcd:2379
57 - --topo_global_root=/vitess/global
58 - --tablet-path=zone1-0000000002
59 - --init_keyspace=commerce
60 - --init_shard=0
61 - --init_tablet_type=replica
62 - --port=15002
63 - --grpc_port=16002
64 - --service_map=grpc-queryservice,grpc-tabletmanager,grpc-updatestream
65 volumes:
66 - vttablet2_data:/vt/vtdataroot
67 depends_on:
68 - vtctld
69 networks:
70 - vitess_net
71
72 vtgate:
73 image: vitess/lite:latest
74 command:
75 - vtgate
76 - --topo_implementation=etcd2
77 - --topo_global_server_address=etcd:2379
78 - --topo_global_root=/vitess/global
79 - --port=15001
80 - --grpc_port=15991
81 - --mysql_server_port=3306
82 - --mysql_auth_server_impl=none
83 - --cell=zone1
84 - --cells_to_watch=zone1
85 - --tablet_types_to_wait=PRIMARY,REPLICA
86 - --service_map=grpc-vtgateservice
87 ports:
88 - "3306:3306"
89 - "15001:15001"
90 - "15991:15991"
91 depends_on:
92 - vttablet-zone1-1
93 - vttablet-zone1-2
94 networks:
95 - vitess_net
96
97 prometheus:
98 image: prom/prometheus:latest
99 ports:
100 - "9090:9090"
101 volumes:
102 - prometheus_data:/prometheus
103 networks:
104 - vitess_net
105
106 grafana:
107 image: grafana/grafana:latest
108 ports:
109 - "3000:3000"
110 environment:
111 - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD}
112 volumes:
113 - grafana_data:/var/lib/grafana
114 networks:
115 - vitess_net
116
117volumes:
118 etcd_data:
119 vttablet1_data:
120 vttablet2_data:
121 prometheus_data:
122 grafana_data:
123
124networks:
125 vitess_net:

.env Template

.env
1# Vitess MySQL Cluster
2GRAFANA_PASSWORD=secure_grafana_password
3
4# MySQL at localhost:3306
5# VTCtld at http://localhost:15000

Usage Notes

  1. 1MySQL-compatible at port 3306
  2. 2VTCtld admin at http://localhost:15000
  3. 3Horizontal sharding support
  4. 4Used by YouTube for scale
  5. 5Configure sharding via VTCtl

Individual Services(7 services)

Copy individual services to mix and match with your existing compose files.

etcd
etcd:
  image: quay.io/coreos/etcd:v3.5.0
  command:
    - etcd
    - "--data-dir=/etcd-data"
    - "--listen-client-urls=http://0.0.0.0:2379"
    - "--advertise-client-urls=http://etcd:2379"
  volumes:
    - etcd_data:/etcd-data
  networks:
    - vitess_net
vtctld
vtctld:
  image: vitess/lite:latest
  command:
    - vtctld
    - "--topo_implementation=etcd2"
    - "--topo_global_server_address=etcd:2379"
    - "--topo_global_root=/vitess/global"
    - "--service_map=grpc-vtctl"
  ports:
    - "15000:15000"
    - "15999:15999"
  depends_on:
    - etcd
  networks:
    - vitess_net
vttablet-zone1-1
vttablet-zone1-1:
  image: vitess/lite:latest
  command:
    - vttablet
    - "--topo_implementation=etcd2"
    - "--topo_global_server_address=etcd:2379"
    - "--topo_global_root=/vitess/global"
    - "--tablet-path=zone1-0000000001"
    - "--init_keyspace=commerce"
    - "--init_shard=0"
    - "--init_tablet_type=replica"
    - "--port=15001"
    - "--grpc_port=16001"
    - "--service_map=grpc-queryservice,grpc-tabletmanager,grpc-updatestream"
  volumes:
    - vttablet1_data:/vt/vtdataroot
  depends_on:
    - vtctld
  networks:
    - vitess_net
vttablet-zone1-2
vttablet-zone1-2:
  image: vitess/lite:latest
  command:
    - vttablet
    - "--topo_implementation=etcd2"
    - "--topo_global_server_address=etcd:2379"
    - "--topo_global_root=/vitess/global"
    - "--tablet-path=zone1-0000000002"
    - "--init_keyspace=commerce"
    - "--init_shard=0"
    - "--init_tablet_type=replica"
    - "--port=15002"
    - "--grpc_port=16002"
    - "--service_map=grpc-queryservice,grpc-tabletmanager,grpc-updatestream"
  volumes:
    - vttablet2_data:/vt/vtdataroot
  depends_on:
    - vtctld
  networks:
    - vitess_net
vtgate
vtgate:
  image: vitess/lite:latest
  command:
    - vtgate
    - "--topo_implementation=etcd2"
    - "--topo_global_server_address=etcd:2379"
    - "--topo_global_root=/vitess/global"
    - "--port=15001"
    - "--grpc_port=15991"
    - "--mysql_server_port=3306"
    - "--mysql_auth_server_impl=none"
    - "--cell=zone1"
    - "--cells_to_watch=zone1"
    - "--tablet_types_to_wait=PRIMARY,REPLICA"
    - "--service_map=grpc-vtgateservice"
  ports:
    - "3306:3306"
    - "15001:15001"
    - "15991:15991"
  depends_on:
    - vttablet-zone1-1
    - vttablet-zone1-2
  networks:
    - vitess_net
prometheus
prometheus:
  image: prom/prometheus:latest
  ports:
    - "9090:9090"
  volumes:
    - prometheus_data:/prometheus
  networks:
    - vitess_net
grafana
grafana:
  image: grafana/grafana:latest
  ports:
    - "3000:3000"
  environment:
    - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD}
  volumes:
    - grafana_data:/var/lib/grafana
  networks:
    - vitess_net

Quick Start

terminal
1# 1. Create the compose file
2cat > docker-compose.yml << 'EOF'
3services:
4 etcd:
5 image: quay.io/coreos/etcd:v3.5.0
6 command:
7 - etcd
8 - --data-dir=/etcd-data
9 - --listen-client-urls=http://0.0.0.0:2379
10 - --advertise-client-urls=http://etcd:2379
11 volumes:
12 - etcd_data:/etcd-data
13 networks:
14 - vitess_net
15
16 vtctld:
17 image: vitess/lite:latest
18 command:
19 - vtctld
20 - --topo_implementation=etcd2
21 - --topo_global_server_address=etcd:2379
22 - --topo_global_root=/vitess/global
23 - --service_map=grpc-vtctl
24 ports:
25 - "15000:15000"
26 - "15999:15999"
27 depends_on:
28 - etcd
29 networks:
30 - vitess_net
31
32 vttablet-zone1-1:
33 image: vitess/lite:latest
34 command:
35 - vttablet
36 - --topo_implementation=etcd2
37 - --topo_global_server_address=etcd:2379
38 - --topo_global_root=/vitess/global
39 - --tablet-path=zone1-0000000001
40 - --init_keyspace=commerce
41 - --init_shard=0
42 - --init_tablet_type=replica
43 - --port=15001
44 - --grpc_port=16001
45 - --service_map=grpc-queryservice,grpc-tabletmanager,grpc-updatestream
46 volumes:
47 - vttablet1_data:/vt/vtdataroot
48 depends_on:
49 - vtctld
50 networks:
51 - vitess_net
52
53 vttablet-zone1-2:
54 image: vitess/lite:latest
55 command:
56 - vttablet
57 - --topo_implementation=etcd2
58 - --topo_global_server_address=etcd:2379
59 - --topo_global_root=/vitess/global
60 - --tablet-path=zone1-0000000002
61 - --init_keyspace=commerce
62 - --init_shard=0
63 - --init_tablet_type=replica
64 - --port=15002
65 - --grpc_port=16002
66 - --service_map=grpc-queryservice,grpc-tabletmanager,grpc-updatestream
67 volumes:
68 - vttablet2_data:/vt/vtdataroot
69 depends_on:
70 - vtctld
71 networks:
72 - vitess_net
73
74 vtgate:
75 image: vitess/lite:latest
76 command:
77 - vtgate
78 - --topo_implementation=etcd2
79 - --topo_global_server_address=etcd:2379
80 - --topo_global_root=/vitess/global
81 - --port=15001
82 - --grpc_port=15991
83 - --mysql_server_port=3306
84 - --mysql_auth_server_impl=none
85 - --cell=zone1
86 - --cells_to_watch=zone1
87 - --tablet_types_to_wait=PRIMARY,REPLICA
88 - --service_map=grpc-vtgateservice
89 ports:
90 - "3306:3306"
91 - "15001:15001"
92 - "15991:15991"
93 depends_on:
94 - vttablet-zone1-1
95 - vttablet-zone1-2
96 networks:
97 - vitess_net
98
99 prometheus:
100 image: prom/prometheus:latest
101 ports:
102 - "9090:9090"
103 volumes:
104 - prometheus_data:/prometheus
105 networks:
106 - vitess_net
107
108 grafana:
109 image: grafana/grafana:latest
110 ports:
111 - "3000:3000"
112 environment:
113 - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD}
114 volumes:
115 - grafana_data:/var/lib/grafana
116 networks:
117 - vitess_net
118
119volumes:
120 etcd_data:
121 vttablet1_data:
122 vttablet2_data:
123 prometheus_data:
124 grafana_data:
125
126networks:
127 vitess_net:
128EOF
129
130# 2. Create the .env file
131cat > .env << 'EOF'
132# Vitess MySQL Cluster
133GRAFANA_PASSWORD=secure_grafana_password
134
135# MySQL at localhost:3306
136# VTCtld at http://localhost:15000
137EOF
138
139# 3. Start the services
140docker compose up -d
141
142# 4. View logs
143docker compose logs -f

One-Liner

Run this command to download and set up the recipe in one step:

terminal
1curl -fsSL https://docker.recipes/api/recipes/vitess-mysql-cluster/run | bash

Troubleshooting

  • VTGate connection refused at port 3306: Ensure VTTablet instances are healthy and registered in etcd topology before VTGate starts accepting connections
  • Tablets stuck in 'NOT_SERVING' state: Check VTCtld logs for keyspace initialization errors and run 'vtctlclient InitShardPrimary' to assign primary tablets
  • Etcd cluster unhealthy warnings: Verify etcd data directory permissions and ensure no port conflicts with existing etcd instances on the host
  • VTCtld web interface shows empty topology: Confirm etcd connectivity and verify --topo_global_root path matches across all Vitess components
  • Query routing errors for cross-shard operations: Review VTGate logs for unsupported query patterns and consider query rewriting for complex joins
  • High memory usage in VTTablet containers: Adjust MySQL buffer pool settings or increase container memory limits based on dataset size

Community Notes

Loading...
Loading notes...

Download Recipe Kit

Get all files in a ready-to-deploy package

Includes docker-compose.yml, .env template, README, and license

Ad Space