Jiamei · 2019年12月06日

Vitess概述及其在arm上的依赖问题

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之间的对比。
image2019-8-5_13-53-23.png

支持的平台和数据库

支持的平台

官方对Ubuntu 14.04和debian 8做了持续性地测试。其它平台也应该能正常工作。

支持的数据库

Vitess支持MySQL 5.6, MariaDB 10.0及以上的版本和这些版本的变体Percona。

Vitess架构

下图阐述了vitess的主要组成部分:
VitessOverview.png

  • 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,这在数据迁移时非常有用。数据迁移的基本流程为:

  1. 创建new_keyspace时,并设置其ServedFrom指向old_keyspace.
  2. 更新app,查看要迁移到new_keyspace中的表,vitess会自动将其请求重定向到old_keyspace.
  3. 执行垂直分割,将数据拷贝到new_keyspace
  4. 移除serverFrom重定向,设置其ServerFrom指向new_keyspace
  5. 删除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由一个mysqldvttablet进程组成。每个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请求的大致流程为:
image2019-8-5_15-3-29.png

  1. 客户端向vtgate发送请求,vtgate根据请求路由到对应的vttablet上
  2. vttablet对查询进行一定的校验,并将请求发送给mysql
  3. mysql执行查询操作,并将结果返回给vttablet
  4. vttablet将结果返回给vtgate
  5. 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的依赖关系即可。

DokerfileDependencies don't work on arm64Dependencies can't be solved
Dockerfile.commonchromium=70.0.3538.110-1~deb9u1none
Dockerfile.mysql56mysql-server-5.6libmysqlclient-devpercona-xtrabackup-24_2.4.13none
Dockerfile.mysql57mysql-server-5.7libmysqlclient-dev percona-xtrabackup-24_2.4.13none
Dockerfile.mysql80mysql-server8.0libmysqlclient-devPercona-XtraBackup-8.0.4libmysqlclient-dev
Dockerfile.mariadbpercona-xtrabackup-24_2.4.13none
Dockerfile.mariadb103mariadb-server-10.3none
Dockerfile.perconapercona-server-server-5.6libperconaserverclient18.1-devlibperconaserverclient18.1-dev
Dockerfile.percona57percona-server-server-5.7libperconaserverclient18.1-devlibperconaserverclient18.1-dev
Dockerfile.percona80percona-server-serverlibperconaserverclient21percona-server-tokudbpercona-server-rocksdbpercona-xtrabackup-80_8.0.4-1libperconaserverclient21percona-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
推荐阅读
关注数
2440
内容数
14
介绍Arm相关的开源软件。
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息