簡介
TiDB 是 PingCAP 公司受 Google Spanner / F1 論文啟發而設計的開源分布式 HTAP (Hybrid Transactional and Analytical Processing) 數據庫,結合了傳統的 RDBMS 和 NoSQL 的最佳特性。TiDB 兼容 MySQL,支持無限的水平擴展,具備強一致性和高可用性。TiDB 的目標是為 OLTP (Online Transactional Processing) 和 OLAP (Online Analytical Processing) 場景提供一站式的解決方案。
特性
1)高度兼容 MySQL
大多數情況下,無需修改代碼即可從 MySQL 輕松遷移至 TiDB,分庫分表后的 MySQL 集群亦可通過 TiDB 工具進行實時遷移。
2)水平彈性擴展
通過簡單地增加新節點即可實現 TiDB 的水平擴展,按需擴展吞吐或存儲,輕松應對高並發、海量數據場景。
3)分布式事務
TiDB 100% 支持標准的 ACID 事務。
4)真正金融級高可用
相比於傳統主從 (M-S) 復制方案,基於 Raft 的多數派選舉協議可以提供金融級的 100% 數據強一致性保證,且在不丟失大多數副本的前提下,可以實現故障的自動恢復 (auto-failover),無需人工介入。
5)一站式 HTAP 解決方案
TiDB 作為典型的 OLTP 行存數據庫,同時兼具強大的 OLAP 性能,配合 TiSpark,可提供一站式 HTAP 解決方案,一份存儲同時處理 OLTP & OLAP,無需傳統繁瑣的 ETL 過程。
6)雲原生 SQL 數據庫
TiDB 是為雲而設計的數據庫,同 Kubernetes 深度耦合,支持公有雲、私有雲和混合雲,使部署、配置和維護變得十分簡單。
兼容性
不支持的特性:視圖、存儲過程、觸發器、自定義函數、外鍵約束、全文索引、空間索引、非UTF-8字符集。與我們實際應用不沖突。
與Mysql差異
1)TiDB 的自增 ID (Auto Increment ID) 只保證自增且唯一,並不保證連續分配。TiDB 目前采用批量分配的方式,所以如果在多台 TiDB 上同時插入數據,分配的自增 ID 會不連續
2)TiDB 支持常用的 MySQL 內建函數,但是不是所有的函數都已經支持,具體請參考語法文檔
3)TiDB 實現了 F1 的異步 Schema 變更算法,DDL 執行過程中不會阻塞線上的 DML 操作。目前支持的DDL包括數據庫、表、索引、列的創建和刪除操作以及列的修改操作。TiDB對列的修改有限制,如不支持從null改成not null,不支持對enum列修改等
事務
TiDB 使用樂觀事務模型,在執行 Update、Insert、Delete 等語句時,只有在提交過程中才會檢查寫寫沖突,而不是像 MySQL 一樣使用行鎖來避免寫寫沖突。所以業務端在執行 SQL 語句后,需要注意檢查 commit 的返回值,即使執行時沒有出錯,commit的時候也可能會出錯。
文檔
在使用TiDB時,可以參照官方文檔進行查閱,地址:https://www.pingcap.com/docs-cn/
架構
1)TiDB Server
TiDB Server 負責接收 SQL 請求,處理 SQL 相關的邏輯,並通過 PD 找到存儲計算所需數據的 TiKV 地址,與 TiKV 交互獲取數據,最終返回結果。 TiDB Server 是無狀態的,其本身並不存儲數據,只負責計算,可以無限水平擴展,可以通過負載均衡組件(如LVS、HAProxy 或 F5)對外提供統一的接入地址
2)Placement Driver
Placement Driver (簡稱 PD) 是整個集群的管理模塊,其主要工作有三個: 一是存儲集群的元信息(某個 Key 存儲在哪個 TiKV 節點);二是對 TiKV 集群進行調度和負載均衡(如數據的遷移、Raft group leader 的遷移等);三是分配全局唯一且遞增的事務 ID。PD 是一個集群,需要部署奇數個節點,一般線上推薦至少部署 3 個節點
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 為單位進行調度
解決問題
1)水平擴展
無限水平擴展是 TiDB 的一大特點,這里說的水平擴展包括兩方面:計算能力和存儲能力。TiDB Server 負責處理 SQL 請求,隨着業務的增長,可以簡單的添加 TiDB Server 節點,提高整體的處理能力,提供更高的吞吐。TiKV 負責存儲數據,隨着數據量的增長,可以部署更多的 TiKV Server 節點解決數據量的問題(自動分庫)。PD 會在 TiKV 節點之間以 Region 為單位做調度,將部分數據遷移到新加的節點上。所以在業務的早期,可以只部署少量的服務實例(推薦至少部署 3 個 TiKV, 3 個 PD,2 個 TiDB),隨着業務量的增長,按照需求添加 TiKV 或者 TiDB 實例
2)高可用
高可用是 TiDB 的另一大特點,TiDB/TiKV/PD 這三個組件都能容忍部分實例失效,不影響整個集群的可用性。下面分別說明這三個組件的可用性、單個實例失效后的后果以及如何恢復。
-
TiDB 是無狀態的,推薦至少部署兩個實例,前端通過負載均衡組件對外提供服務。當單個實例失效時,會影響正在這個實例上進行的 Session,從應用的角度看,會出現單次請求失敗的情況,重新連接后即可繼續獲得服務。單個實例失效后,可以重啟這個實例或者部署一個新的實例。
-
PD 是一個集群,通過 Raft 協議保持數據的一致性,單個實例失效時,如果這個實例不是 Raft 的 leader,那么服務完全不受影響;如果這個實例是 Raft 的 leader,會重新選出新的 Raft leader,自動恢復服務。PD 在選舉的過程中無法對外提供服務,這個時間大約是3秒鍾。推薦至少部署三個 PD 實例,單個實例失效后,重啟這個實例或者添加新的實例。
-
TiKV 是一個集群,通過 Raft 協議保持數據的一致性(副本數量可配置,默認保存三副本),並通過 PD 做負載均衡調度。單個節點失效時,會影響這個節點上存儲的所有 Region。對於 Region 中的 Leader 結點,會中斷服務,等待重新選舉;對於 Region 中的 Follower 節點,不會影響服務。當某個 TiKV 節點失效,並且在一段時間內(默認 10 分鍾)無法恢復,PD 會將其上的數據遷移到其他的 TiKV 節點上。
3)小彩蛋
兼容 MySQL 5.7 及以上,同時更好地支持文檔類型存儲,表中包含一個 JSON 字段來存儲復雜的信息
插入JSON數據
查詢JSON數據,和 MongoDB 等文檔數據庫相同,可以在服務端支持用戶各種復雜組合查詢條件
除了插入、查詢外,對 JSON 的修改也是支持的。目前支持的 MySQL 5.7 的 JSON 函數:JSON_EXTRACT、JSON_ARRAY、JSON_OBJECT、JSON_SET、JSON_REPLACE、JSON_INSERT、JSON_REMOVE、JSON_TYPE、JSON_UNQUOTE
軟硬件要求
參照:https://www.pingcap.com/docs-cn/op-guide/recommendation/
安裝
由於服務器數量個數限制,這里采用單台安裝測試,具體安裝步驟如下:
1)下載官方Binary壓縮包,wget http://download.pingcap.org/tidb-latest-linux-amd64.tar.gz,wget http://download.pingcap.org/tidb-latest-linux-amd64.sha256
2)檢查文件完整性,sha256sum -c tidb-latest-linux-amd64.sha256
3)解壓文件,tar -xzf tidb-latest-linux-amd64.tar.gz && cd tidb-latest-linux-amd64
啟動
1)啟動pd-server,./bin/pd-server --data-dir=pd
2)啟動tikv-server,./bin/tikv-server --pd="127.0.0.1:2379" -store=tikv
3)啟動tidb-server,./bin/tidb-server --store=tikv --path="127.0.0.1:2379"
注:此三項啟動順序不能變更
連接
啟動成功后,可以通過Navicat等工具連接,TiDB對外的連接方式與Mysql一樣,對於用戶來說,根本感受不到使用的是TiDB還是Mysql。這里需要設置一下Centos的防火牆,Centos7防火牆的設置與Centos6不同,可以關閉防火牆或者開放端口
1)關閉防火牆
systemctl stop firewalld.service #停止firewall
systemctl disable firewalld.service #禁止firewall開機啟動
兩者可以同時使用,避免每次重啟都得重新關閉防火牆
2)開放端口
firewall-cmd --zone=public --add-port=4000/tcp --permanent #開放4000端口
firewall-cmd --reload #重新加載防火牆配置,此時4000端口才真正的開放
其他功能可以使用firewall-cmd --help查看
開始
1)創建表
CREATE TABLE `test_user` (
`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'id',
`name` varchar(32) NOT NULL COMMENT '名字',
`age` tinyint(3) UNSIGNED DEFAULT NULL COMMENT '年紀',
`summary` json DEFAULT NULL COMMENT '簡介',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=30001 COMMENT='測試用戶表';
2)數據庫連接
連接池依然使用原有的com.alibaba.druid.pool.DruidDataSource,不需要修改原有任何類,只需要修改數據庫連接地址及端口等配置信息即可
jdbc.url=jdbc:mysql://192.168.32.129:4000/test?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true
jdbc.username=root
jdbc.password=
druid.timeBetweenEvictionRunsMillis=60000
druid.minEvictableIdleTimeMillis=300000
druid.maxActive=60
druid.initialSize=2
druid.maxWait=200
druid.minIdle=30
druid.maxOpenPreparedStatements=30
3)用例測試
進行了簡單的CURD操作,都可以滿足,嘗試了一下JSON數據的查詢,可以准確的查詢到結果,后期可以進行壓力測試,甚至代替mongo
集群
由於TiDB的pd、tikv和tidb三部分都可以搭建集群,滿足了高可用性,由於自己的虛擬機目前只有一台,暫未做測試,后續補上。
測試
1)基礎功能測試
進行了簡單的CURD操作,基本功能得以滿足,對於mysql的函數及關鍵字的支持未測試
2)寫入測試
為方便下面的查詢測試,這里通過for循環為數據庫添加了10萬條數據,整個過程耗時18分鍾,沒有遇到錯誤,寫入可用性不錯
3)查詢測試
這里以10萬條數據做了簡單的查詢測試,由於目前只有單台服務,可能對實際結果有所偏差
條件 | 耗時(毫秒) |
查詢主鍵 | 82 |
查詢普通索引列(varchar) | 86 |
查詢普通列(varchar) | 505 |
查詢JSON數據 | 729 |
總結
綜上所述,TiDB可以滿足mysql既有的功能需求,能夠達到線上使用的要求,但線上若想使用TiDB,需要開發、運維和DBA協調,包括軟硬件是否能夠滿足,DBA維護工作是否可行等等。