手把手部署原生vitess集群(非k8s部署)

最近研究分布式的关系型数据库扩展方案,vitess是youtube开源的中间件,基于mysql实现的分布式分库分表方案。相对于ShardingSphere,ProxySQL,maxscale,vitess的部署是最复杂的。本文经过实践,将vitess的集群部署过程记录下来。
一般vitess是通过k8s来部署,但是想了解细节,还是走一遍原生部署,会加深对整个架构的理解。

首先需要看懂 vitess的架构图,也和部署紧密相关。
关于vitess的这些概念,基本上都是全新的,可以参考官方文档:https://vitess.io/docs/concepts/,本文着重在部署实践,概念的翻译已经有很多博客了。
手把手部署原生vitess集群(非k8s部署)
总共就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一样连接。

上一篇:【题解】[HNOI2015]菜肴制作(贪心+topo序)


下一篇:配置frp报错start error: type [http] not support when vhost_http_port is not set