vitess 简介
概述
Vitess为大规模MySQL集群实例管理/扩展/部署提供了解决方案。它结合了NoSQL的可扩展性和MySQL的很多重要功能,并且在裸机,公有云和私有云上都可以运行。有关其设计动机和愿景详见vitess/doc/Vision.md。Vitess可以解决下面的问题:
- 从裸机迁移到私有云或公共云
- 部署和管理大量MySQL实例
- 通过允许您对MySQL数据库进行分片来扩展规模,同时将应用程序更改降至最低
Vitess提供兼容的JDBC和Go数据库驱动程序。Planet Scale为Vitess提供商业支持和功能开发。自2011年以来,Vitess一直为YouTube所使用,现在已被许多企业采用。
MySQL 与 NoSQL权衡
下图是Vitess与MySQL/NoSQL之间的对比。
支持的平台和数据库
支持的平台
官方对Ubuntu 14.04和debian 8做了持续性地测试。其它平台也应该能正常工作。
支持的数据库
Vitess支持MySQL 5.6, MariaDB 10.0及以上的版本和这些版本的变体Percona。
Vitess架构
下图阐述了vitess的主要组成部分:
- Topology:拓扑服务存储元数据,包括集群中服务器,分片数据库,复制集的信息。Vitess支持三种拓扑服务:zookeeper,etcd,consul
- vtgate:vtgate是一个轻量级代理服务器。应用程序向其发送请求,其将请求路由到对应的vttablet,并合并的结果返回给客户端。
- vttablet:vttablet是位于mysql前面的代理服务器。每个MySQL实例都有对应一个vttablet。
- vtctl:vtctl是用于管理Vitess群集的命令行工具。
- vtctld:vtctld是一个HTTP服务器,是vitess web ui 集群管理工具,使您可以浏览存储在锁服务器中的信息。
- vtworker:vtworker托管运行时间较长的流程,它支持插件架构并提供库,以便您可以轻松选择要使用的tablet。
主要概念
shard
shard分片可以理解为按照表中的某字段,将表分成多个部分。一个shard存储 keyspace的一部分内容。一个shard由一个mysql 主机点和若干个mysql从节点组成。
cell
cell是某个区域的一组服务器和网络基础集合。某个cell出现故障,不会影响其它cell。其通常存储着整个数据中心的所有数据或者一个子集。每个cell包含一个本地拓扑服务,存储着该cell中所有tablet的信息。
Keyspace
keyspace是一个逻辑上数据库,如果有进行分片,keyspace对应多个mysql数据库,若没有分片,keyspace对应一个mysql数据库。
keyspace graph
keyspace图允许vitess决定某个keyspace,cell,tablet使用哪一个shard,这在数据迁移时非常有用。数据迁移的基本流程为:
- 创建
new_keyspace
时,并设置其ServedFrom
指向old_keyspace
. - 更新app,查看要迁移到
new_keyspace
中的表,vitess会自动将其请求重定向到old_keyspace
. - 执行垂直分割,将数据拷贝到
new_keyspace
- 移除
serverFrom
重定向,设置其ServerFrom
指向new_keyspace
- 删除
old_keyspace
中没用的数据
对于每一个(cell, tablet type)
对,可以设置不同的ServerFrom
.通常先迁移rdonly tablet的请求,然后replica tablet,最后才是master tablet,每次执行一个。
VSchema
VSchema描述数据在keyspace和shard中的分布情况。当有查询请求或重分片时,会用到这些信息。我们可以为keyspace选择是否分片。若分片,则可以为每一个表指定vindex索引。
VStream
VStream是一个VTGate上的变更通知系统。
Replication Graph
replication graph描述了主数据库和它们的副本的关系。当主数据库出现故障时,replication graph可以在所有副本中选一个成为新的主数据库,并使所有副本都指向新的主数据库,从而可以继续正常工作。
Tablet
tablet由一个mysqld
和vttablet
进程组成。每个tablet都有一个类型,表示其当前的角色,包含如下类型:
- master:被选为master的replica tablet
- replica:可以被提升为master的tablet
- rdonly:不能被提升为master的tablet,通常用来后台处理作业,例如备份,将数据导入到其它系统,繁重的分析查询,MapReduce,重新分片
- backup:在一致性快照时,tablet会停止复制,为其分片上传新的备份。完成之后,将回复复制,返回它的前一个类型
- restore:一个启动时没有数据的tablet,会从最新的备份中恢复数据。完成后,会复制备份的GTID位置,成为replica或rdonly
- drained:被Vitess后台进程保留(reserved)的tablet(例如分片时的rdonly tablet)
模式管理
Vitess支持的数据定义语句,包括创建,修改,删除表。模式更改(schema changes)会在每个shard的主tablet上执行,这些更改通过复制集传播到子vttablet上,Vitess不支持DDL语句。
在执行schema changes前,Vitess会进行语法校验,并决定其影响范围。Vitess进行预检查,以确保更新可以在数据库上执行,减少系统的冗余度,同时vitess也可以拒绝超过某个范围的更新操作。
sql请求的生命周期
Vitess处理sql请求的大致流程为:
- 客户端向vtgate发送请求,vtgate根据请求路由到对应的vttablet上
- vttablet对查询进行一定的校验,并将请求发送给mysql
- mysql执行查询操作,并将结果返回给vttablet
- vttablet将结果返回给vtgate
- vtgate接收到所有vttablet的结果,将其合并,返回给客户端,若vttablet出现错误,vtgate会重新尝试从vttablet获取结果,除非已经达到最大尝试次数或者出现不可恢复的错误。
Vitess在aarch64上的依赖问题
官方的vitess目前只支持x86_64. 依赖主要包含两部分:bootstrap.sh和dockerfile中的所安装的软件。
bootstrap.sh
二进制包安装软件
protoc
Protocol Buffer(也称为protobuf)由google研发,用来高效存储和读取序列化结构数据的工具。
# Install protoc.
function install_protoc() {
local version="$1"
local dist="$2"
case $(uname) in
Linux) local platform=linux;;
Darwin) local platform=osx;;
esac
case $(arch) in
aarch64) local target=aarch_64;;
x86_64) local target=x86_64;;
*) echo "ERROR: unsupported architecture"; exit 1;;
esac
wget https://github.com/protocolbuffers/protobuf/releases/download/v$version/protoc-$version-$platform-${target}.zip
unzip "protoc-$version-$platform-${target}.zip"
ln -snf "$dist/bin/protoc" "$VTROOT/bin/protoc"
}
etcd
etcd 是具有一致性,高可用性的键值存储系统。它是vitess支持的的拓扑服务之一。
# Download and install etcd, link etcd binary into our root.
function install_etcd() {
local version="$1"
local dist="$2"
case $(uname) in
Linux) local platform=linux; local ext=tar.gz;;
Darwin) local platform=darwin; local ext=zip;;
esac
case $(arch) in
aarch64) local target=arm64;;
x86_64) local target=amd64;;
*) echo "ERROR: unsupported architecture"; exit 1;;
esac
download_url=https://github.com/coreos/etcd/releases/download
file="etcd-${version}-${platform}-${target}.${ext}"
wget "$download_url/$version/$file"
if [ "$ext" = "tar.gz" ]; then
tar xzf "$file"
else
unzip "$file"
fi
rm "$file"
ln -snf "$dist/etcd-${version}-${platform}-${target}/etcd" "$VTROOT/bin/etcd"
}
consul
consul是一个用于服务发现和配置的工具。consul具有分布式,高可用,极易扩展的特性。是Vitess支持的拓扑服务之一。
# Download and install consul, link consul binary into our root.
function install_consul() {
local version="$1"
local dist="$2"
case $(uname) in
Linux) local platform=linux;;
Darwin) local platform=darwin;;
esac
case $(arch) in
aarch64) local target=arm64;;
x86_64) local target=amd64;;
*) echo "ERROR: unsupported architecture"; exit 1;;
esac
download_url=https://releases.hashicorp.com/consul
wget "${download_url}/${version}/consul_${version}_${platform}_${target}.zip"
unzip "consul_${version}_${platform}_${target}.zip"
ln -snf "$dist/consul" "$VTROOT/bin/consul"
}
chromedriver
Chromedriver是实现了W3C web Driver标准的独立服务器。当执行测试时,Vitess可能会用到它。
# Download chromedriver (necessary to run test/vtctld_web_test.py).
function install_chromedriver() {
local version="$1"
local dist="$2"
if [ "$(arch)" == "aarch64" ] ; then
os=$(cat /etc/*release | grep "^ID=" | cut -d '=' -f 2)
if [ "$os" == ubuntu ] ; then
sudo apt-get update -y && sudo apt install -y --no-install-recommends chromium-browser chromium-chromedriver
ln -nsf /usr/bin/chromedriver $VTROOT/dist/chromedriver/chromedriver
elif [ "$os" == debian ] ; then
sudo apt-get update -y && sudo apt install -y --no-install-recommends chromium chromedriver
ln -nsf /usr/bin/chromedriver $VTROOT/dist/chromedriver/chromedriver
else
echo "ERROR: For aarch64, this script only supports chromedriver for ubuntu/debian"
exit 1
fi
else
curl -sL "https://chromedriver.storage.googleapis.com/$version/chromedriver_linux64.zip" > chromedriver_linux64.zip
unzip -o -q chromedriver_linux64.zip -d "$dist"
rm chromedriver_linux64.zip
fi
}
Go 软件包
go软件是通过“go get ”或“goverdor”安装的。“govendor sync”会根据vitess/vendor/vendor.json安装go软件包。软件包会被下载在vendor目录下,运行bootstrap.sh之后才能看到这些软件包。其中有一些软件包不支持aarch64。
github.com/aws/aws-sdk-go/service/ec2
亚马逊弹性计算云(Amazon EC2)是一个提供安全,容量可变的云web服务。 版本v1.15.83之后才有对aarch64的支持。
github.com/klauspost/cpuid
cpuid 可以为当前运行程序,提供CPU信息,包括SIMD,cache信息,其不支持aarch64.
google.golang.org/grpc
grpc是一个开源的高性能rpc框架。在这个包中的vet.sh脚本会下载 protoc-3.3.0-linux-x86_64.zip 。我们可以设置环境变量 VET_SKIP_PROTO 避免其下载。因为bootstrap.sh会安装protoc。
Dockerfile
在vitess.io/vitess/docker中,有一个bootstrap目录,其它目录中的dockerfile的基础镜像都是由bootstrap中dockerfile所产生。因此只要解决bootstrap中dockerfile的依赖关系即可。
Dokerfile | Dependencies don't work on arm64 | Dependencies can't be solved |
---|---|---|
Dockerfile.common | chromium=70.0.3538.110-1~deb9u1 | none |
Dockerfile.mysql56 | mysql-server-5.6libmysqlclient-devpercona-xtrabackup-24_2.4.13 | none |
Dockerfile.mysql57 | mysql-server-5.7libmysqlclient-dev percona-xtrabackup-24_2.4.13 | none |
Dockerfile.mysql80 | mysql-server8.0libmysqlclient-devPercona-XtraBackup-8.0.4 | libmysqlclient-dev |
Dockerfile.mariadb | percona-xtrabackup-24_2.4.13 | none |
Dockerfile.mariadb103 | mariadb-server-10.3 | none |
Dockerfile.percona | percona-server-server-5.6libperconaserverclient18.1-dev | libperconaserverclient18.1-dev |
Dockerfile.percona57 | percona-server-server-5.7libperconaserverclient18.1-dev | libperconaserverclient18.1-dev |
Dockerfile.percona80 | percona-server-serverlibperconaserverclient21percona-server-tokudbpercona-server-rocksdbpercona-xtrabackup-80_8.0.4-1 | libperconaserverclient21percona-server-tokudbpercona-server-rocksdb |
mysql 5.6
apt-get
update -y && \
DEBIAN_FRONTEND=noninteractive \
apt-get install -y init-system-helpers libaio1 libc6 libdbi-perl init-system-helpers bsdutils debconf libgcc1 libstdc++6 libdbd-mysql-perl libterm-readkey-perl initscripts psmisc libdbd-mysql-perl rsync libev4 apparmor
wget http://launchpadlibrarian.net/247515101/mysql-client-core-5.6_5.6.28-1ubuntu3_arm64.deb && \
dpkg -i mysql-client-core-5.6_5.6.28-1ubuntu3_arm64.deb && \
rm mysql-client-core-5.6_5.6.28-1ubuntu3_arm64.deb
wget http://launchpadlibrarian.net/247515100/mysql-client-5.6_5.6.28-1ubuntu3_arm64.deb && \
dpkg -i mysql-client-5.6_5.6.28-1ubuntu3_arm64.deb && \
rm mysql-client-5.6_5.6.28-1ubuntu3_arm64.deb
wget http://launchpadlibrarian.net/235784975/mysql-common_5.6.28-1ubuntu2_all.deb && \
dpkg -i mysql-common_5.6.28-1ubuntu2_all.deb && \
rm mysql-common_5.6.28-1ubuntu2_all.deb
wget http://launchpadlibrarian.net/247515103/mysql-server-core-5.6_5.6.28-1ubuntu3_arm64.deb && \
dpkg -i mysql-server-core-5.6_5.6.28-1ubuntu3_arm64.deb && \
rm mysql-server-core-5.6_5.6.28-1ubuntu3_arm64.deb
wget http://launchpadlibrarian.net/247515102/mysql-server-5.6_5.6.28-1ubuntu3_arm64.deb && \
DEBIAN_FRONTEND=noninteractive dpkg -i mysql-server-5.6_5.6.28-1ubuntu3_arm64.deb && \
rm mysql-server-5.6_5.6.28-1ubuntu3_arm64.deb
libmysqlclient-dev(mysql 5.6)
wget http://launchpadlibrarian.net/212189001/libmysqlclient18_5.6.25-0ubuntu1_arm64.deb && \
dpkg -i libmysqlclient18_5.6.25-0ubuntu1_arm64.deb && \
rm libmysqlclient18_5.6.25-0ubuntu1_arm64.deb
wget http://launchpadlibrarian.net/212188993/libmysqlclient-dev_5.6.25-0ubuntu1_arm64.deb && \
dpkg -i libmysqlclient-dev_5.6.25-0ubuntu1_arm64.deb && \
rm libmysqlclient-dev_5.6.25-0ubuntu1_arm64.deb
mysql 5.7 和 libmysqlclient-dev(mysql 5.7)
add-apt-repository 'deb http://ftp.debian.org/debian sid main' && \
apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends libmysqlclient-dev mysql-client-5.7 mysql-server-5.7
mysql 8.0
apt-get update
apt install make cmake gcc libncurses5-dev
git clone https://github.com/mysql/mysql-server.git
cd mysql-server/
git checkout 8.0
mkdir bld
cd bld
groupadd mysql
useradd -r -g mysql -s /bin/false mysql
cmake .. -DDOWNLOAD_BOOST=1 -DWITH_BOOST=/usr/local/boost
make
make install
cd /usr/local/mysql/
mkdir mysql-files
chown mysql:mysql mysql-files
chmod 750 mysql-files
bin/mysqld --initialize --user=mysql
bin/mysql_ssl_rsa_setup
bin/mysqld_safe --user=mysql &
cp support-files/mysql.server /etc/init.d/mysql.server
apt install -y libdbd-mysql-perl rsync libev4
mariadb 10.3
apt-get install software-properties-common
apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0xF1656F24C74CD1D8
echo "# MariaDB 10.3 Repository
deb [arch=amd64,arm64,ppc64el] http://sfo1.mirrors.digitalocean.com/mariadb/repo/10.3/ubuntu bionic main
deb-src http://sfo1.mirrors.digitalocean.com/mariadb/repo/10.3/ubuntu bionic main" > /etc/apt/sources.list.d/mariadb.list
wget http://launchpadlibrarian.net/365857916/libc6_2.27-3ubuntu1_arm64.deb && \
dpkg -i libc6_2.27-3ubuntu1_arm64.deb && \
rm libc6_2.27-3ubuntu1_arm64.deb
wget http://launchpadlibrarian.net/365857922/libc-dev-bin_2.27-3ubuntu1_arm64.deb && \
dpkg -i libc-dev-bin_2.27-3ubuntu1_arm64.deb && \
rm libc-dev-bin_2.27-3ubuntu1_arm64.deb
wget http://launchpadlibrarian.net/365857912/libc6-dev_2.27-3ubuntu1_arm64.deb && \
dpkg -i libc6-dev_2.27-3ubuntu1_arm64.deb && \
rm libc6-dev_2.27-3ubuntu1_arm64.deb
wget http://launchpadlibrarian.net/365857921/libc-bin_2.27-3ubuntu1_arm64.deb && \
dpkg -i libc-bin_2.27-3ubuntu1_arm64.deb && \
rm libc-bin_2.27-3ubuntu1_arm64.deb
apt update -y && DEBIAN_FRONTEND=noninteractive apt install -y
--no-install-recommends \
mariadb-server-core-10.3 \
mariadb-server-10.3 \
libmariadb-dev
percona
apt-get update
apt-get install -y make cmake gcc libncurses-dev bison libssl-dev libreadline-dev libaio-dev libnuma-dev libboost-tools-dev libboost-thread1.62-dev magics++
git clone https://github.com/percona/percona-server.git
cd percona-server
git checkout 5.6
git submodule init
git submodule update
cmake . -DCMAKE_BUILD_TYPE=RelWithDebInfo -DBUILD_CONFIG=mysql_release -DFEATURE_SET=community
make
make install
percona 5.7
apt-get update
apt-get install -y make cmake gcc libncurses-dev bison libssl-dev libreadline-dev libaio-dev libnuma-dev
apt -y install libboost-tools-dev libboost-thread1.62-dev magics++
git clone https://github.com/percona/percona-server.git
cd percona-server
git checkout 5.7
git submodule init
git submodule update
##-DWITH_ROCKSDB=1 will occur error.make
cmake . -DCMAKE_BUILD_TYPE=RelWithDebInfo -DBUILD_CONFIG=mysql_release -DFEATURE_SET=community
make
make install
percona 8.0
apt-get update
apt install -y git cmake g++ build-essential libssl-dev libreadline-dev pkg-config libcurl4-openssl-dev bison
git clone https://github.com/percona/percona-server.git
cd percona-server/
git checkout 8.0
git submodule init
git submodule update
cmake . -DFORCE_INSOURCE_BUILD=1 -DDOWNLOAD_BOOST=1 -DWITH_BOOST=/usr/local/boost
make
make install
percona-xtrabackup-2.4.13
wget https://github.com/percona/percona-xtrabackup/archive/percona-xtrabackup-2.4.13.tar.gz
tar zxf percona-xtrabackup-2.4.13.tar.gz
cd percona-xtrabackup-2.4.13
mkdir bld
cd bld/
cmake .. -DBUILD_CONFIG=xtrabackup_release -DWITH_MAN_PAGES=OFF -DDOWNLOAD_BOOST=1 -DWITH_BOOST=/usr/local && make -j4
make install
Percona-XtraBackup-8.0
git clone https://github.com/percona/percona-xtrabackup.git
cd percona-xtrabackup
git checkout 8.0
apt-get update
apt-get install build-essential flex bison automake autoconf libtool cmake libaio-dev mysql-client libncurses-dev zlib1g-dev libgcrypt11-dev libev-dev libcurl4-gnutls-dev vim-common libssl-dev
mkdir bld
cd bld/
cmake .. -DBUILD_CONFIG=xtrabackup_release -DWITH_MAN_PAGES=OFF -DDOWNLOAD_BOOST=1 -DWITH_BOOST=/usr/local && make -j4
make install