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 | +----+------+