最近研究分布式的关系型数据库扩展方案,vitess是youtube开源的中间件,基于mysql实现的分布式分库分表方案。相对于ShardingSphere,ProxySQL,maxscale,vitess的部署是最复杂的。本文经过实践,将vitess的集群部署过程记录下来。
一般vitess是通过k8s来部署,但是想了解细节,还是走一遍原生部署,会加深对整个架构的理解。
首先需要看懂 vitess的架构图,也和部署紧密相关。
关于vitess的这些概念,基本上都是全新的,可以参考官方文档:https://vitess.io/docs/concepts/,本文着重在部署实践,概念的翻译已经有很多博客了。
总共就5个服务:
- Topo Server
- vtctld
- VTGate
- VTTablet
- MySQL
其中 VTTablet和MySQL成对出现,需要部署多个实例。
部署参考官方文档:https://vitess.io/docs/user-guides/configuration-basic/,经过浓缩与简化,细节请阅读原文档。
准备
本次部署在一台叫 node02
的节点上进行,你可能会问,只有一台机器吗?是的,虽然是集群部署,在组件可以先部署一台机器,然后进行扩展,而扩展集群,请见下一篇博文。
包准备
下载vitess二进制包:https://github.com/vitessio/vitess/releases
在每台机器上都放上这个包,建立vitess的数据目录:
mkdir -p /extra/server/vitess
scp vitess-12.zip root@node01:/extra/server/vitess
cd /extra/server/vitess
unzip /extra/server/vitess/vitess-12.zip
mkdir -p /extra/vt-data/tmp
环境准备
使用非root用户
因为vitess命令不允许root用户运行,所以我们建立vitess用户来跑。
下面所有操作都在非root用户下,这里使用vitess。
chown -R vitess:vitess /extra/vt-data/
chown -R vitess:vitess /extra/server/vitess
一般机器上的mysql目录都是mysql用户权限的,所以将vitess用户加入mysql用户组,才能访问mysql的文件
# 将vitess用户加入mysql组,才能读取mysql目录
usermod -aG mysql vitess
注意:以下操作都是在vitess用户下进行的。
环境变量
- VTDATAROOT: mysql数据存储目录,默认
/vt
,需要改成挂载盘 - VT_MYSQL_ROOT:
mysqld
目录
全部机器上执行:
echo "export PATH=/extra/server/vitess/vitess-12/bin:\${PATH}" >> ~/.bashrc
echo "export VTDATAROOT=/extra/vt-data" >> ~/.bashrc
echo "export VT_MYSQL_ROOT=/opt/mysql/mysql-5.7.26-linux-glibc2.12-x86_64" >> ~/.bashrc
# 连接 vtctld 的客户端,不需要起服务,但最好配下别名简化命令。
echo 'alias vtctlclient="command vtctlclient -server node02:15999 -log_dir ${VTDATAROOT}/tmp -alsologtostderr"' >> ~/.bashrc
# 10.16.9.234:2379是etcd服务的地址,下面会提
echo "export TOPO_SERVER=10.16.9.234:2379" >> ~/.bashrc
source ~/.bashrc
备份参数
备份目录需要是个共享存储(S3,ceph,google云存储等),参考文档:https://vitess.io/docs/user-guides/operating-vitess/backup-and-restore/backup-and-restore/
-backup_storage_implementation file -file_backup_storage_root <mounted_path_dir>
后面简写为 <backup_flags>
.
生产环境肯定是需要备份的,我们这里暂时不要备份,如果需要,加上这段参数即可。
日志目录
每个vitess组件都配
-log_dir=${VTDATAROOT}/tmp
全局拓扑服务
支持ZK和etcd,我们选etcd,启用V2版本的API。
参数:
-topo_implementation=etcd2 -topo_global_server_address=$TOPO_SERVER -topo_global_root=/vitess/global
后面简写为:<topo_flags>
.
vtctld
管理服务后端进程,可以起多个。
vtctld -topo_implementation=etcd2 -topo_global_server_address=$TOPO_SERVER -topo_global_root=/vitess/global \
-log_dir=${VTDATAROOT}/tmp \
-port=15000 \
-grpc_port=15999 \
-service_map='grpc-vtctl' \
-pid_file $VTDATAROOT/tmp/vtctld.pid \
> $VTDATAROOT/tmp/vtctld.out 2>&1 &
15000
端口用于界面访问,15999
用于客户端访问。
cell
可以认为是牢房(地区、数据中心等可以建多个),用于隔离作用,我们这里用一个cell足够。
vtctlclient AddCellInfo \
-root /vitess/cell1 \
-server_address $TOPO_SERVER \
cell1
cell的注册中心目录是单独的,如果复用一个拓扑服务器,目录要区分
vttablet和MySQL
这俩配对出现,同一台机器部署。
table-uid 全局唯一的int32整数
mysql
很方便的起一个mysql
mysqlctl \
-log_dir=${VTDATAROOT}/tmp \
-tablet_uid=100 \
-mysql_port=17100 \
init
要设置额外的参数:
EXTRA_MY_CNF=”/path/to/common.cnf” mysqlctl \
-log_dir=${VTDATAROOT}/tmp \
-tablet_uid=100 \
-mysql_port=17100 \
init
测试mysql是否启动成功:
$ mysql -S ${VTDATAROOT}/vt_0000000100/mysql.sock -u vt_dba
[snip]
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| _vt |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.00 sec)
vttablet
-
table-path
: cell名字-table-uid
这里的一堆参数见:https://vitess.io/docs/user-guides/configuration-basic/vttablet-mysql/#starting-vttablet
vttablet -topo_implementation=etcd2 -topo_global_server_address=$TOPO_SERVER -topo_global_root=/vitess/global \
-log_dir=${VTDATAROOT}/tmp \
-tablet-path=cell1-100 \
-tablet_hostname=node02 \
-init_keyspace=commerce \
-init_shard=0 \
-init_tablet_type=replica \
-port=15100 \
-grpc_port=16100 \
-service_map 'grpc-queryservice,grpc-tabletmanager' \
-enable_semi_sync=false \
-enable_replication_reporter=false \
-restore_from_backup=false \
-queryserver-config-pool-size=16 \
-queryserver-config-transaction-cap=300 \
-queryserver-config-stream-pool-size=16 \
-pid_file $VTDATAROOT/tmp/vttablet.pid \
> $VTDATAROOT/tmp/vttablet.out 2>&1 &
查看所有 tablets
$ vtctlclient ListAllTablets
cell1-0000000100 commerce 0 replica node02:15100 node02:17100 [] <null>
删除tablet
vtctlclient DeleteTablet cell1-100
扩展
在多个节点都部署 mysql和vttablet, 方法是一样的, vitess的分布式就体现在这。
选主
vtctlclient \
InitShardPrimary \
-force \
commerce/0 \
cell1-100
然后再看现在的情况:
$ vtctlclient ListAllTablets
cell1-0000000100 commerce 0 primary node02:15100 node02:17100 [] 2021-11-22T03:53:59Z
vtgate
接收请求的入口服务,建议起多个,而且是一台机器上起多个(更好利用go的垃圾回收)。
在 /extra/server/vitess
下建立 mysql_creds.json
文件:
{
"test": [
{
"Password": "VitessDB2021",
"UserData": "test"
}
]
}
启动vtgate服务
vtgate -topo_implementation=etcd2 -topo_global_server_address=$TOPO_SERVER -topo_global_root=/vitess/global \
-log_dir=${VTDATAROOT}/tmp \
-cell=cell1 \
-cells_to_watch=cell1 \
-port=15001 \
-mysql_server_port=15306 \
-tablet_types_to_wait PRIMARY,REPLICA \
-mysql_auth_server_impl=static \
-mysql_auth_server_static_file=mysql_creds.json \
-grpc_port=15991 \
-service_map='grpc-vtgateservice' \
-vschema_ddl_authorized_users='%' \
-pid_file $VTDATAROOT/tmp/vtgate.pid \
> $VTDATAROOT/tmp/vtgate.out 2>&1 &
连接测试:
$ mysql -h 127.0.0.1 -P 15306 -utest -pVitessDB2021
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.9-vitess-12.0.0 Version: 12.0.0 (Git revision de06fca branch 'HEAD') built on Tue Oct 26 11:54:28 UTC 2021 by runner@fv-az198-353 using go1.17.2 linux/amd64
Copyright (c) 2000, 2017, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MySQL [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| commerce |
| information_schema |
| mysql |
| sys |
| performance_schema |
+--------------------+
5 rows in set (0.00 sec)
可以看到,有一个commerce
数据库,commerce
就是keyspace
,在vitess中,相当于一个逻辑数据库,下一篇扩展集群时,会根据 keyspace id
来划分数据。
至此,一个集群就搭建完了,目前只有一个mysql数据节点。访问入口是 vtgate服务,就和连接mysql一样连接。