TiDB 部署及数据同步
简介
TiDB 是 PingCAP 公司受 Google Spanner / F1 论文启发而设计的开源分布式 HTAP (Hybrid Transactional and Analytical Processing) 数据库, 结合了传统的 RDBMS 和 NoSQL 的最佳特性。TiDB 兼容 MySQL,支持无限的水平扩展,具备强一致性和高可用性。 TiDB 的目标是为 OLTP (Online Transactional Processing) 和 OLAP (Online Analytical Processing) 场景提供一站式的解决方案。
TiDB整体架构

TiDB 集群主要分为三个组件:
-
TiDB Server
TiDB Server 负责接收 SQL 请求,处理 SQL 相关的逻辑,并通过 PD 找到存储计算所需数据的 TiKV 地址, 与 TiKV 交互获取数据,最终返回结果。 TiDB Server 是无状态的,其本身并不存储数据,只负责计算,可以无限水平扩展, 可以通过负载均衡组件(如LVS、HAProxy 或 F5)对外提供统一的接入地址。
-
PD Server
Placement Driver (简称 PD) 是整个集群的管理模块,其主要工作有三个: 一是存储集群的元信息(某个 Key 存储在哪个 TiKV 节点); 二是对 TiKV 集群进行调度和负载均衡(如数据的迁移、Raft group leader 的迁移等);三是分配全局唯一且递增的事务 ID。
PD 是一个集群,需要部署奇数个节点,一般线上推荐至少部署 3 个节点。
-
TiKV Server
TiKV Server 负责存储数据,从外部看 TiKV 是一个分布式的提供事务的 Key-Value 存储引擎。存储数据的基本单位是 Region, 每个 Region 负责存储一个 Key Range (从 StartKey 到 EndKey 的左闭右开区间)的数据, 每个 TiKV 节点会负责多个 Region 。TiKV 使用 Raft 协议做复制,保持数据的一致性和容灾。 副本以 Region 为单位进行管理,不同节点上的多个 Region 构成一个 Raft Group,互为副本。 数据在多个 TiKV 之间的负载均衡由 PD 调度,这里也是以 Region 为单位进行调度。
安装与部署
单节点方式快速部署(适用于功能测试,预览)
执行步骤:
# 下载压缩包
wget http://download.pingcap.org/tidb-latest-linux-amd64.tar.gz
wget http://download.pingcap.org/tidb-latest-linux-amd64.sha256
# 检查文件完整性,返回 ok 则正确
sha256sum -c tidb-latest-linux-amd64.sha256
# 解开压缩包
tar -xzf tidb-latest-linux-amd64.tar.gz
cd tidb-latest-linux-amd64
在获取 TiDB 二进制文件包后,我们可以在单机上面,运行和测试 TiDB 集群,请按如下步骤依次启动 PD,TiKV,TiDB。
注意:以下启动各个应用程序组件实例的时候,请选择后台启动,避免前台失效后程序自动退出。
- 步骤一,启动 PD
./bin/pd-server --data-dir=pd \
--log-file=pd.log
- 步骤二,启动 TiKV
./bin/tikv-server --pd="127.0.0.1:2379" \
--data-dir=tikv \
--log-file=tikv.log
- 步骤三,启动 TiDB
./bin/tidb-server --store=tikv \
--path="127.0.0.1:2379" \
--log-file=tidb.log
- 步骤四,使用 MySQL 客户端连接 TiDB:
mysql -h 127.0.0.1 -P 4000 -u root -D test
Ansible 部署集群(强烈推荐)
准备机器
测试部署,下列所有机器均由
Virtual Box生成的虚拟环境,生产环境中请参考官方文档配置。 注意开启虚拟机的 specific IP,eg:config.vm.network "private_network", ip: "192.168.12.10"。
- 部署目标机器若干
- 建议 4 台及以上,TiKV 至少 3 实例(本教程 3 实例),且与 TiDB、PD 模块不位于同一主机,详见部署建议
-
推荐安装 CentOS 7.3 及以上版本 Linux 操作系统(本教程使用 ubuntu 16.04),x86_64 架构(amd64), 数据盘请使用 ext4 文件系统,挂载 ext4 文件系统时请添加 nodelalloc 挂载参数
编辑
/etc/fstab文件,添加nodelalloc挂载参数:# vi /etc/fstab /dev/nvme0n1 /data1 ext4 defaults,nodelalloc,noatime 0 2使用以下命令 umount 挂载目录并重新挂载:
# umount /data1 # mount -a通过以下命令确认是否生效:
# mount -t ext4 /dev/nvme0n1 on /data1 type ext4 (rw,noatime,nodelalloc,data=ordered) - 机器之间内网互通,防火墙如 iptables 等请在部署时关闭
-
机器的时间、时区设置一致,开启 NTP 服务且在正常同步时间
注: Ubuntu 系统请安装 ntpstat 软件包
$ ntpstat unsynchronised # NTP 服务未正常同步 $ ntpstat Unable to talk to NTP daemon. Is it running? # NTP 服务未正常运行 sudo systemctl status ntp.service # 查看 ntp 服务运行状态 -
创建 tidb 普通用户 (本教程使用 vagrant 用户)作为程序运行用户,tidb 用户可以免密码 sudo 到 root 用户
# useradd tidb # passwd tidb # visudo tidb ALL=(ALL) NOPASSWD: ALL本教程中
vagrant用户默认免密 sudo 到 root 用户
- 部署中控机器一台
- 中控机可以是部署目标机器中的某一台。
- 推荐安装 CentOS 7.3 及以上版本 Linux 操作系统(默认包含 Python 2.7,本教程使用 ubuntu 16.04)。
- 该机器需开放外网访问,用于下载 TiDB 及相关软件安装包。
-
配置 ssh authorized_key 互信,在中控机上可以使用 tidb 用户(本教程使用 vagrant 用户)免密码 ssh 登录到部署目标机器
# vagrant 用户 $ ssh-keygen -t rsa Generating public/private rsa key pair. Enter file in which to save the key (/home/tidb/.ssh/id_rsa): Created directory '/home/tidb/.ssh'. Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/tidb/.ssh/id_rsa. Your public key has been saved in /home/tidb/.ssh/id_rsa.pub. The key fingerprint is: SHA256:eIBykszR1KyECA/h0d7PRKz4fhAeli7IrVphhte7/So tidb@172.16.10.49 The key's randomart image is: +---[RSA 2048]----+ |=+o+.o. | |o=o+o.oo | | .O.=.= | | . B.B + | |o B * B S | | * + * + | | o + . | | o E+ . | |o ..+o. | +----[SHA256]-----+ sudo cat ~/.ssh/id_rsa.pub authorized_keys # 依次执行以下命令,将 192.168.12.10 替换成目标机器的ip,按提示输入部署目标机器 vagrant 用户密码, # 执行成功后即创建好 ssh 互信,其他机器同理。 ssh-copy-id -i ~/.ssh/id_rsa.pub 192.168.12.10 # 验证 ssh 互信 ssh 192.168.12.10 # 不需要输入密码并登录成功
在中控机上下载 TiDB-Ansible
以 vagrant 用户登录中控机并进入 /home/vagrant 目录,使用以下命令从 Github TiDB-Ansible 项目 上下载 TiDB-Ansible 相应版本, 默认的文件夹名称为 tidb-ansible,以下为各版本下载示例,版本选择可以咨询官方。
# 下载 2.0 GA 版本:
git clone -b release-2.0 https://github.com/pingcap/tidb-ansible.git
# 下载 master 版本:
git clone https://github.com/pingcap/tidb-ansible.git
本教程为master版本
在中控机上安装 Ansible 及其依赖
$ sudo apt-get install python-pip curl
$ cd tidb-ansible
$ sudo pip install -r ./requirements.txt
pip install 时可能会报Python locale error: unsupported locale setting,执行下列命令:
export LC_ALL="en_US.UTF-8"
export LC_CTYPE="en_US.UTF-8"
sudo dpkg-reconfigure locales
分配机器资源,编辑 inventory.ini 文件
sudo vim ~/tidb-ansible/inventory.ini
配置如下:(更换ip为你的目标机器ip,192.168.12.22为中控机器ip,其他为目标机器ip)
## TiDB Cluster Part
[tidb_servers]
192.168.12.22
[tikv_servers]
192.168.12.10
192.168.12.2
192.168.12.3
[pd_servers]
192.168.12.22
[spark_master]
[spark_slaves]
## Monitoring Part
# prometheus and pushgateway servers
[monitoring_servers]
192.168.12.22
[grafana_servers]
192.168.12.22
# node_exporter and blackbox_exporter servers
[monitored_servers]
192.168.12.22
192.168.12.10
192.168.12.2
192.168.12.3
[alertmanager_servers]
## Binlog Part
[pump_servers:children]
tidb_servers
## Group variables
[pd_servers:vars]
# location_labels = ["zone","rack","host"]
## Global variables
[all:vars]
deploy_dir = /home/vagrant/deploy
## Connection
# ssh via normal user
ansible_user = vagrant
cluster_name = test-cluster
tidb_version = latest
# process supervision, [systemd, supervise]
process_supervision = systemd
# timezone of deployment region
timezone = Asia/Shanghai
set_timezone = True
enable_firewalld = False
# check NTP service
enable_ntpd = True
set_hostname = False
## binlog trigger
enable_binlog = False
# zookeeper address of kafka cluster, example:
# zookeeper_addrs = "192.168.0.11:2181,192.168.0.12:2181,192.168.0.13:2181"
zookeeper_addrs = ""
# store slow query log into seperate file
enable_slow_query_log = False
# enable TLS authentication in the TiDB cluster
enable_tls = False
# KV mode
deploy_without_tidb = False
# Optional: Set if you already have a alertmanager server.
# Format: alertmanager_host:alertmanager_port
alertmanager_target = ""
grafana_admin_user = "admin"
grafana_admin_password = "admin"
部署任务
-
确认
tidb-ansible/inventory.ini文件中ansible_user = vagrant,本例使用vagrant用户作为服务运行用户,配置如下:## Connection # ssh via normal user ansible_user = vagrant执行以下命令如果所有 server 返回 vagrant 表示 ssh 互信配置成功。
ansible -i inventory.ini all -m shell -a 'whoami'执行以下命令如果所有 server 返回 root 表示 vagrant 用户 sudo 免密码配置成功。
ansible -i inventory.ini all -m shell -a 'whoami' -b -
执行
local_prepare.ymlplaybook,联网下载 TiDB binary 到中控机:ansible-playbook local_prepare.yml -
初始化系统环境,修改内核参数
ansible-playbook bootstrap.yml -
部署 TiDB 集群软件
ansible-playbook deploy.yml -
启动 TiDB 集群
ansible-playbook start.yml# 返回下列字段时,表示启动成功 Congrats! All goes well. :-)
测试集群
测试连接 TiDB 集群,推荐在 TiDB 前配置负载均衡来对外统一提供 SQL 接口。
-
使用 MySQL 客户端连接测试,TCP 4000 端口是 TiDB 服务默认端口。
mysql -u root -h 192.168.12.22 -P 4000# eg vagrant@vagrant [09:48:48 PM] [~/tidb-ansible] [master *] -> % mysql -h192.168.12.22 -uroot -P 4000 Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 1 Server version: 5.7.10-TiDB-v2.0.0-rc.4-147-g00d4831 MySQL Community Server (Apache License 2.0) Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> -
通过浏览器访问监控平台。
地址:
http://192.168.12.22:3000默认帐号密码是:admin/admin![]()
Docker Compose 部署方案
待补充…
数据同步
由于 TiDB 本身兼容绝大多数的 MySQL 语法,所以对于绝大多数业务来说,最安全的切换数据库方式就是将 TiDB 作为现有数据库的从库接在主 MySQL 库的后方, 这样对业务方实现完全没有侵入性下使用 TiDB 对现有的业务进行备份,应对未来数据量或者并发量增长带来的单点故障风险,如需上线 TiDB, 也只需要简单的将业务的主 MySQL 地址指向 TiDB 即可。
下面我们详细介绍了如何将 MySQL 的数据迁移到 TiDB,并将 TiDB 作为 MySQL 的 Slave 进行数据同步。
这里我们假定 MySQL 以及 TiDB 服务信息如下:
+------------------+-----------------+----------------------------------------+
| Name | Address | Port | User | Password |
+------------------+-----------------+----------------------------------------+
| MySQL | 127.0.0.1 | 3306 | root | |
| TiDB | 192.168.12.22 | 4000 | vagrant | |
+------------------+-------------+--------+-----------+-----------------------+
下载 TiDB 企业版工具集 (Linux)
注:普通工具集中,无
syncer,mydumper等工具
# 下载 tool 压缩包
wget http://download.pingcap.org/tidb-enterprise-tools-latest-linux-amd64.tar.gz
wget http://download.pingcap.org/tidb-enterprise-tools-latest-linux-amd64.sha256
# 检查文件完整性,返回 ok 则正确
sha256sum -c tidb-enterprise-tools-latest-linux-amd64.sha256
# 解开压缩包
tar -xzf tidb-enterprise-tools-latest-linux-amd64.tar.gz
cd tidb-enterprise-tools-latest-linux-amd64
使用 checker 进行 Schema 检查
在迁移之前,我们可以使用 TiDB 的 checker 工具,checker 是我们开发的一个小工具,用于检测目标 MySQL 库中的表的表结构是否支持无缝的迁移到 TiDB, TiDB 支持绝大多数的 MySQL 常用的原生数据类型,所以大多数情况 checker 的返回应该是 ok。如果 check 某个 table schema 失败,表明 TiDB 当前并不支持, 我们不能对该 table 里面的数据进行迁移。checker 包含在 TiDB 工具集里面。
./bin/checker -host 127.0.0.1 -port 3306 -user root -password password db_name
2016/10/27 13:11:49 checker.go:48: [info] Checking database db_name
2016/10/27 13:11:49 main.go:37: [info] Database DSN: root:@tcp(127.0.0.1:3306)/db_name?charset=utf8
2016/10/27 13:11:49 checker.go:63: [info] Checking table t1
2016/10/27 13:11:49 checker.go:69: [info] Check table t1 succ
2016/10/27 13:11:49 checker.go:63: [info] Checking table t2
2016/10/27 13:11:49 checker.go:69: [info] Check table t2 succ
使用 mydumper/myloader 全量导入数据
我们使用 mydumper 从 MySQL 导出数据,然后用 myloader 将其导入到 TiDB 里面。
注意,虽然我们也支持使用 MySQL 官方的 mysqldump 工具来进行数据的迁移工作,但相比于 mydumper/myloader,性能会慢很多, 对于大量数据的迁移会花费很多时间,这里我们并不推荐。
mydumper/myloader是一个更强大的数据迁移工具,具体可以参考https://github.com/maxbube/mydumper。
# 下载 mydumper 压缩包
wget http://download.pingcap.org/mydumper-linux-amd64.tar.gz
wget http://download.pingcap.org/mydumper-linux-amd64.sha256
# 检查文件完整性,返回 ok 则正确
sha256sum -c mydumper-linux-amd64.sha256
# 解开压缩包
tar -xzf mydumper-linux-amd64.tar.gz
cd mydumper-linux-amd64
从 MySQL 导出数据
我们使用 mydumper 从 MySQL 导出数据,如下:
./bin/mydumper -h 127.0.0.1 -P 3306 -u root -t 16 -F 128 -B test -T t1,t2 -o ./guopisql
上面,我们使用-B test表明是对test这个database操作,然后用-T t1,t2表明只导出t1,t2两张表。 -t 16表明使用16个线程去导出数据。-F 128是将实际的table切分成多大的chunk,这里就是128MB一个chunk。
注意:在阿里云一些需要super privilege的云上面,mydumper需要加上--no-locks参数,否则会提示没有权限操作。
给 TiDB 导入数据
我们使用 myloader 将之前导出的数据导入到 TiDB。
./bin/myloader -h 192.168.12.22 -P 4000 -u vagrant -p password -t 16 -q 100 -d ./guopisql
这里-q 100表明每个事务包含多少个query,默认是1000,我们这里使用100就可以了(数据多的话,可以加大)。
导入成功之后,我们可以用 MySQL 官方客户端进入 TiDB,查看:
vagrant@vagrant [09:48:48 PM] [~/tidb-ansible] [master *]
-> % mysql -h192.168.12.22 -uroot -P 4000
mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| t1 |
| t2 |
+----------------+
使用 syncer 增量导入数据实现数据和 MySQL 实时同步
上面我们介绍了如何使用mydumper/myloader将 MySQL 的数据全量导入到 TiDB,但如果后续 MySQL 的数据有更新,我们仍然希望快速导入, 使用全量的方式就不合适了。
TiDB 提供syncer工具能方便的将 MySQL 的数据增量的导入到 TiDB 里面。
syncer也属于 TiDB 企业工具集。
假设我们之前已经使用mydumper/myloader导入了t1和t2两张表的一些数据,现在我们希望这两张表的任何更新, 都是实时的同步到 TiDB 上面。
MySQL 开启 binlog
在使用 syncer 之前,我们必须保证:
- MySQL 开启 binlog 功能,参考Setting the Replication Master Configuration
- Binlog 格式必须使用
row format,这也是 MySQL 5.7 之后推荐的binlog格式
# sudo vi /etc/mysql/my.cnf
[mysqld]
log-bin=mysql-bin
server-id=1
binlog-format=ROW
重启mysql服务
sudo service mysql restart
获取同步 position
我们通过show master status得到当前binlog的position,syncer的初始同步位置就是从这个地方开始。
show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 | 154 | | | |
+------------------+----------+--------------+------------------+-------------------+
我们将position相关的信息保存到一个syncer.meta文件里面,用于syncer的同步:
# vim syncer.meta
binlog-name = "mysql-bin.000001"
binlog-pos = 154
启动 syncer
syncer的配置文件config.toml:
log-level = "info"
server-id = 1
# meta 文件地址
meta = "./syncer.meta"
worker-count = 1
batch = 1
pprof-addr = ":10081"
[from]
host = "127.0.0.1"
user = "root"
password = "your password"
port = 3306
[to]
host = "192.168.12.22"
user = "root"
password = ""
port = 4000
启动syncer
# 后台运行
vagrant@vagrant [10:10:07 PM] [~/tidb-enterprise-tools-latest-linux-amd64]
-> % nohup ./bin/syncer -config config.toml &
[1] 4193
syncer每隔30s会输出当前的同步统计,如下:
# cat nohub.out
2018/05/08 15:04:25 syncer.go:821: [info] [syncer]total events = 2, total tps = 0, recent tps = 0, master-binlog = (mysql-bin.000001, 574), master-binlog-gtid=, syncer-binlog = (mysql-bin.000001, 574), syncer-binlog-gtid =
2018/05/08 15:04:55 syncer.go:821: [info] [syncer]total events = 2, total tps = 0, recent tps = 0, master-binlog = (mysql-bin.000001, 574), master-binlog-gtid=, syncer-binlog = (mysql-bin.000001, 574), syncer-binlog-gtid =
2018/05/08 15:05:25 syncer.go:821: [info] [syncer]total events = 2, total tps = 0, recent tps = 0, master-binlog = (mysql-bin.000001, 574), master-binlog-gtid=, syncer-binlog = (mysql-bin.000001, 574), syncer-binlog-gtid =
2018/05/08 15:05:55 syncer.go:821: [info] [syncer]total events = 2, total tps = 0, recent tps = 0, master-binlog = (mysql-bin.000001, 574), master-binlog-gtid=, syncer-binlog = (mysql-bin.000001, 574), syncer-binlog-gtid =
在 MySQL 插入新的数据
INSERT INTO t1 VALUES (4, 4), (5, 5);
登录到 TiDB 查看:
mysql -h127.0.0.1 -P4000 -uroot -p
mysql> select * from t1;
+----+------+
| id | age |
+----+------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | 4 |
| 5 | 5 |
+----+------+


浙公网安备 33010602011771号