TiDB 是 PingCAP 公司受 Google Spanner / F1 论文启发而设计的开源分布式 HTAP (Hybrid Transactional and Analytical Processing) 数据库, 结合了传统的 RDBMS 和 NoSQL 的最佳特性。TiDB 兼容 MySQL,支持无限的水平扩展,具有强一致性和高可用性。 TiDB 的目标是为 OLTP (Online Transactional Processing) 和 OLAP (Online Analytical Processing) 场景提供一站式的解决方案。javascript
TiDB 集群主要分为三个组件:php
TiDB Servercss
TiDB Server 负责接收 SQL 请求,处理 SQL 相关的逻辑,并经过 PD 找到存储计算所需数据的 TiKV 地址, 与 TiKV 交互获取数据,最终返回结果。 TiDB Server 是无状态的,其自己并不存储数据,只负责计算,能够无限水平扩展, 能够经过负载均衡组件(如LVS、HAProxy 或 F5)对外提供统一的接入地址。html
PD Serverjava
Placement Driver (简称 PD) 是整个集群的管理模块,其主要工做有三个: 一是存储集群的元信息(某个 Key 存储在哪一个 TiKV 节点); 二是对 TiKV 集群进行调度和负载均衡(如数据的迁移、Raft group leader 的迁移等);三是分配全局惟一且递增的事务 ID。node
PD 是一个集群,须要部署奇数个节点,通常线上推荐至少部署 3 个节点。python
TiKV Servermysql
TiKV Server 负责存储数据,从外部看 TiKV 是一个分布式的提供事务的 Key-Value 存储引擎。存储数据的基本单位是 Region, 每一个 Region 负责存储一个 Key Range (从 StartKey 到 EndKey 的左闭右开区间)的数据, 每一个 TiKV 节点会负责多个 Region 。TiKV 使用 Raft 协议作复制,保持数据的一致性和容灾。 副本以 Region 为单位进行管理,不一样节点上的多个 Region 构成一个 Raft Group,互为副本。 数据在多个 TiKV 之间的负载均衡由 PD 调度,这里也是以 Region 为单位进行调度。linux
执行步骤:nginx
# 下载压缩包 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。
注意:如下启动各个应用程序组件实例的时候,请选择后台启动,避免前台失效后程序自动退出。
./bin/pd-server --data-dir=pd \
--log-file=pd.log
./bin/tikv-server --pd="127.0.0.1:2379" \ --data-dir=tikv \ --log-file=tikv.log
./bin/tidb-server --store=tikv \
--path="127.0.0.1:2379" \ --log-file=tidb.log
mysql -h 127.0.0.1 -P 4000 -u root -D test
测试部署,下列全部机器均由
Virtual Box
生成的虚拟环境,生产环境中请参考官方文档配置。 注意开启虚拟机的 specific IP,eg:config.vm.network "private_network", ip: "192.168.12.10"
。
推荐安装 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)
机器的时间、时区设置一致,开启 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 用户
配置 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 # 不须要输入密码并登陆成功
以 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
版本
$ 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
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.yml
playbook,联网下载 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
待补充…
因为 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 | | +------------------+-------------+--------+-----------+-----------------------+
注:普通工具集中,无
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
在迁移以前,咱们可使用 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 从 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
咱们使用 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
参数,不然会提示没有权限操做。
咱们使用 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 | +----------------+
上面咱们介绍了如何使用mydumper/myloader
将 MySQL 的数据全量导入到 TiDB,但若是后续 MySQL 的数据有更新,咱们仍然但愿快速导入, 使用全量的方式就不合适了。
TiDB 提供syncer
工具能方便的将 MySQL 的数据增量的导入到 TiDB 里面。
syncer
也属于 TiDB 企业工具集。
假设咱们以前已经使用mydumper/myloader
导入了t1
和t2
两张表的一些数据,如今咱们但愿这两张表的任何更新, 都是实时的同步到 TiDB 上面。
在使用 syncer 以前,咱们必须保证:
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
咱们经过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
的配置文件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 =
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 | +----+------+