TiDB概覽
先來一段官網(wǎng)的描述
TiDB server:無狀態(tài)SQL解析層,支持二級索引,在線ddl,兼容MySQL協(xié)議,數(shù)據(jù)轉(zhuǎn)儲
SQL輸入->解析語法樹(AST)->邏輯計劃分析->執(zhí)行計劃優(yōu)化
->cost-base model->物理計劃選擇->計算下推tikv->聚合tikv執(zhí)行結(jié)果
PD server: 協(xié)調(diào)層,存儲集群元數(shù)據(jù),region調(diào)度,事務(wù)時間戳TSO。存儲每個 TiKV 節(jié)點實時的數(shù)據(jù)分布情況和集群的整體拓撲結(jié)構(gòu),內(nèi)置儀表盤dashboard.
TiKV/TiFlash:存儲層,tikv行存儲引擎,事務(wù)類處理走tikv;tiFlash列存儲引擎,分析類處理走tiFlash。tikv,基于LSM算法的RocksDB單機Key-Value 存儲引擎,TiDB 的 SQL 層做完 SQL 解析后,會將 SQL 的執(zhí)行計劃轉(zhuǎn)換為對 TiKV API 的實際調(diào)用。
tikv存儲單位為region,關(guān)于region的介紹可以參考這里同時里面還有raft的相關(guān)介紹,目前最主要記住TIKV以 Region 為單位做 Raft 的復(fù)制和成員管理同時只需要同步復(fù)制到多數(shù)節(jié)點,即可安全地認為數(shù)據(jù)寫入成功
特性:
易拓展:計算能力(TiDB)和存儲能力(TiKV)均可水平拓展,但集群中只有一個PD能被選舉為leader
高可用:TiDB/TiKV/PD 三大組件均可cluster模式部署
高效存儲:基于LSM算法的RocksDB單機存儲引擎,lz4、zstd等高效壓縮算法,除了 RocksDB之外,TiDB 還支持一些流行的單機存儲引擎,比如 GolevelDB、BoltDB 等
安全存儲:采用Raft 協(xié)議復(fù)制數(shù)據(jù),多副本防止單機失效
分布式事務(wù):支持ACID事務(wù),不同于XA,客戶端調(diào)用無需設(shè)置數(shù)據(jù)源為xa,天然分布式事務(wù)
易用性:支持MySQL協(xié)議,使用MySQL語法,MySQL客戶端均可直接連接登陸
因測試環(huán)境受限,我們的環(huán)境較多軟硬件都不符合官方配置要求,啊哈哈哈。。。但這并不影響我們對技術(shù)的研究和使用,再窮也要創(chuàng)造條件頂硬上。
一、部署環(huán)境
| 對比項 | 官方配置 | 實際配置 |
|---|---|---|
| 操作系統(tǒng) | Red Hat Enterprise Linux7.3 及以上 | Red Hat 4.8.5-36 |
| 硬盤 | 部分組件ssd,部分組件sas | 機械硬盤raid |
其余硬件,實際部署環(huán)境CPU 8核,內(nèi)存16G,千兆網(wǎng)卡。


TiDB 和 PD 可以部署在同一臺服務(wù)器上。
如對性能和可靠性有更高的要求,應(yīng)盡可能分開部署。
官網(wǎng)參考
雖然實際測試環(huán)境,使用的raid掛載的是機械硬盤,但是讀寫能力并不弱,dd指令數(shù)據(jù)如下:
本次使用主機11臺(10.248.7.154-164)
二、拓撲

查看集群狀態(tài)
tiup cluster display tidb-test當然還有更直觀的儀表盤(PD內(nèi)置,訪問PD服務(wù)http:ip+port/dashboard).也可以先在部署TiUP的機器執(zhí)行 tiup cluster display tidb-test --dashboard得到,即使用數(shù)據(jù)庫用戶root登陸還可以使用額外部署的grafana:http://10.248.7.163:3000
三、測試與優(yōu)化
場景:大文件,多文件數(shù)據(jù)入庫,入庫首先保證速度,最終一致即可(CAP中的AP)文件有備份,可重新入庫。入庫后簡單OLAP操作。
測試準備:入庫應(yīng)用(可配置單次入庫記錄數(shù)),500萬行數(shù)據(jù)文件(寫成6個文件)
經(jīng)此兩次調(diào)整后,region leader熱點已分布比較均勻:這里先來說一個異常場景,這個場景剛好可以對比磁盤性能差異引起的tidb性能差異,同時對理解熱點問題和對應(yīng)調(diào)優(yōu)有一定幫助。
在最開始壓測的時候,tikv節(jié)點的三臺主機(raid 22塊磁盤),其中有兩臺主機raid cache電池故障,導致raid cache失效,這兩臺主機的IO性能嚴重受影響
當然,在測試的時候,事先是并不知道這個問題的,并在此基礎(chǔ)上做了一些研究和調(diào)優(yōu)。接下來簡要說下過程(以下過程均訪問單個TiDB-server):1、首次壓測(單批次5000行記錄,5線程)
由于擴展tikv前的圖已丟失(現(xiàn)raid電池問題已修復(fù),無法重現(xiàn)),只能貼上4tikv的圖了,不過除了加多一個節(jié)點,現(xiàn)象差不多,后面再做擴縮容的演示
由圖可以看出,除了正常的161外,其余的tikv節(jié)點,IO均已跑滿(163為應(yīng)用部署主機)??紤]兩點,磁盤性能差異、region分布不均勻。
再來看下熱點region的圖:可以看出,hot region leader的分布非常不均勻。以三副本(peer)為例,根據(jù)raft協(xié)議,當寫入時,首先寫入到region leader,寫完leader之后再同步拷貝到其余兩個節(jié)點的region follower 參考官網(wǎng)說明。這里就考慮兩個熱點部分不均勻的可能:1、單批次提交事務(wù)過大,導致同一時間內(nèi)數(shù)據(jù)集中在一個region,在未超過一定大小時(默認 96M)并沒有分裂region;2、主鍵有序程度高,導致排序分裂region時,數(shù)據(jù)在region中比較集中。
入庫結(jié)果:平均一百萬行需要6-7分鐘。從文件數(shù)據(jù)看,先慢后快,這跟初始化時只有單個region有關(guān),只有達到單個region限制后才會分裂。參考這里可先不對此過度優(yōu)化。2、第二次壓測(單批次2000行記錄,10線程)
基于第一次的壓測結(jié)果,修改單批次提交記錄數(shù),并加大線程分散提交的事務(wù)。修改后tikv節(jié)點的IO使用率并無太多變化。入庫速度略有上升:3、第三次壓測(單批次2000行記錄,10線程,亂序)
在修改了批次大小后,繼續(xù)修改使主鍵亂序,同上,IO使用率依舊沒有多大變化。不過入庫速度有較大提升(平均一百萬3分鐘):

到目前為止,一直忽略了一個事情,沒有觀察總的region leader情況:從圖看,總的leader分布是很均勻的,且寫入字節(jié)總量各個tikv節(jié)點也大致相同,但是hot leader為什么這么不均勻而且為什么其中一個tikv IO使用率低這么多呢,矛頭指向了磁盤性能問題,經(jīng)排查后發(fā)現(xiàn),磁盤電池故障,raid cache失效。
4、第四次壓測(單批次2000行記錄,10線程,亂序,sync-log = false)
在磁盤問題修復(fù)前,我們找到一處關(guān)于sync-log的說明
以三副本為例,需要至少寫完兩個副本之后,才能向客戶端返回ack。因此關(guān)閉同步日志,異步寫follower的副本,相當于寫單機的時間。這里犧牲了CAP中的C,只需最終一致即可。我們的應(yīng)用場景適用,同時我們文件有備份,即便出錯可以重新導入。但是對于實時性較強,對一致性要求較高的金融場景,不建議關(guān)閉同步日志。
操作需使用Tiup:
執(zhí)行tiup cluster edit-config tidb-test修改完成后執(zhí)行:tiup cluster reload tidb-test -R tikv 重啟tikv
修改后入庫效率如下:一百萬行記錄入庫時間優(yōu)化到2分鐘。
不過在修復(fù)磁盤后發(fā)現(xiàn),這個參數(shù)在我們的場景影響并不是很大,良好的io性能使得這個參數(shù)設(shè)置變得不那么重要,因此在修復(fù)磁盤后的測試中,我們都是基于開啟同步日志的場景
修復(fù)磁盤后測試
修復(fù)后的tikv 磁盤性能均有如下表現(xiàn):
修復(fù)磁盤后,我們測試的條件為:3TiKV3副本,單批次2000行記錄,10線程,亂序。恢復(fù)同步日志配置的修改。
來看下修復(fù)后的TiDB表現(xiàn):hot region leader 均勻分布,peer(副本)也是均勻分布入庫效率如下(平均100萬行記錄1.5分鐘):直覺告訴我們,事情肯定還沒有結(jié)束,應(yīng)該還有優(yōu)化的空間。似乎到目前為止,我們都沒有好好看看TiDB-server的情況:到目前為止,我們都是直接訪問單個的TiDB-server。因此出現(xiàn)了如圖的CPU負載情況,只有157的tidb CPU快到7個核的使用率。由于tidb-server是無狀態(tài)的,可以通過負載來給另外兩個tidb-server分活了。本例使用NGINX,配置如下:
修改訪問地址,客戶端通過連接NGINX訪問tidb 10.248.7.154:4000
通過NGINX負載后,每個tidb-server的cpu都得到了利用,同時平均一百萬行記錄入庫時間優(yōu)化到1分鐘。
按照對官方文檔的理解,tidb的計算能力和存儲能力都可以擴展,目前我們通過NGINX負載實現(xiàn)了tidb-server計算能力的負載。但是計算不僅僅在tidb-server。tidb-server 解析SQL生成執(zhí)行計劃之后,會有一部分的計算下推到tikv。這也是為何tikv和tidb 這兩個組件的實例不能部署在同一臺主機。那么擴充tikv節(jié)點后,性能會有多大程度提高?另外擴充的節(jié)點會不會自動協(xié)調(diào)原有節(jié)點的region呢?
擴展tikv節(jié)點
擴展前,肯定要先看看原有的磁盤占用情況:擴容過程中,正逐漸轉(zhuǎn)移數(shù)據(jù)到新的tikv節(jié)點。穩(wěn)定后如下圖:不過在入庫效率上,提升并不明顯,時間上和擴容前相差不多。有以下原因,原本的三節(jié)點并行入庫性能還有較多可利用空間,相當于只是把部分處理遷移到新節(jié)點,單原先節(jié)點的處理能力還有很多富余,需要原先的節(jié)點IO和CPU有較高使用率時,擴充節(jié)點才能有較多的性能提升region調(diào)度策略CPU和IO使用率都不大。
同等主機環(huán)境的MySQL入庫情況如下:在主鍵無序的情況下,隨著數(shù)據(jù)量的增大,入庫性能急劇下滑,這跟索引樹葉子節(jié)點在主鍵無序時,頻繁分裂調(diào)整樹結(jié)構(gòu)有關(guān)。主鍵有序時,入庫性能中 規(guī)中矩,不過即便是有序,在數(shù)據(jù)量多了以后,入庫性能也會下滑。所以MySQL單表有大小要求,超過一定大小之后最好選擇分庫分表,但是這也會引入另外的問題,業(yè)務(wù)應(yīng)用測也要對此做大量的改造。
同等主機環(huán)境MySQL與tidb查詢性能對比:
當前分區(qū)500萬行記錄查詢,查詢SQL
select SETTLE_DATE AS "賬期日",COUNT(0) AS 成功條數(shù),SUM(JSON_EXTRACT(JSON,'$.Payment')) AS 成功總金額(分)
FROM BL_BATCH_TEST TDP
WHERE TDP.SETTLE_DATE = '20201201' and JSON_EXTRACT(JSON,'$.IsSuccess') = '0' and JSON_EXTRACT(JSON,'$.Result') = '0' group by SETTLE_DATE;

TIDB
mysql(mysql的數(shù)據(jù)同事幫我跑的,啊哈哈)
對比來看,tidb查詢性能較為穩(wěn)定,即便重啟所有組件清楚緩存后(圖中第二次查詢 ),單個分區(qū)500萬行記錄,查詢8s,再次查詢時間減半,MySQL第一次查詢耗時80+s,第二次查詢也能維持較好的性能。通常業(yè)務(wù)查詢(OLAP),最重要的是首次時間,第二次的查詢時間參考意義不大,因此穩(wěn)定的查詢時間尤為重要。MySQL和tidb在重啟后,首次查詢時間都相對要久一點,這跟加載磁盤數(shù)據(jù)到內(nèi)存耗費有關(guān),tikv幾個節(jié)點堆起來的內(nèi)存跟MySQL單機的內(nèi)存比,是不太公平的,但這也正是tidb的優(yōu)勢。
總結(jié):
1、TiDB-server是計算密集型組件,同時也會將部分計算下推到TiKV,而TiKV是IO密集型組件,因此TiDB和TiKV不能在同一臺主機部署。PD存儲元數(shù)據(jù)會頻繁寫磁盤,對磁盤IO要求高,因此也不能和TiKV同部署,PD可以和TiDB-server同主機部署。
2、TiKV (集成raft協(xié)議)以region為存儲單位,超過默認96M后會分裂,通過raft協(xié)議做leader選舉和副本(即peer)復(fù)制,每個region都會有l(wèi)eader 副本,其余的副本為follower,客戶端讀寫只會通過region的leader節(jié)點,寫入時,寫完leader后再復(fù)制到follower,超半數(shù)以上副本寫入完成即認為寫入成功。
增減tikv節(jié)點,或者修改replication.max-replicas后,PD會通過region的心跳判斷當前副本情況,從而調(diào)度副本到新節(jié)點或者增減副本。
3、通過grafana和PD自帶的dashBoard可以實時查看當前系統(tǒng)的問題,比如TIDB節(jié)點的CPU使用率、QPS;TIKV節(jié)點的CPU、IO使用率;通過PD查看熱點分布和region分布于調(diào)度情況;通過PD 的dashBoard查看慢sql,集群狀態(tài),調(diào)用?;鹧鎴D等等。
CPU使用率單核不要超過80%,超過不管是TIDB節(jié)點和TIKV都要考慮擴容
tikv節(jié)點內(nèi)存不要超過60%使用率,IO達到80%可視為到達瓶頸
4、region數(shù)量單個tikv小于50K, grpc延遲盡可能小于100ms。過多的region會導致調(diào)度頻繁影響性能,grpc延遲增大??煽紤]設(shè)置region合并參數(shù)
以下配置意為:key數(shù)目小于200000,region大小小于20M的合并(默認)
set config pd `schedule.max-merge-region-keys`=200000;
set config pd `schedule.max-merge-region-size`=20;
5、當TIDB節(jié)點CPU過高時,如是正常SQL執(zhí)行需要,可考慮增加TIDB節(jié)點,并通過Nginx,HaProxy等負載工具分發(fā)到不同節(jié)點執(zhí)行。當Tikv 出現(xiàn)較高水平的cpu使用率或者IO使用率,可考慮增加TiKV節(jié)點。TiKV對磁盤要求較高,盡量使用SSD磁盤,或者多磁盤raid。
6、出現(xiàn)熱點region的時候,有幾個地方可以查看,比如grafana監(jiān)控中的PD可以看相關(guān)的hot region分布情況,這是最直觀的方式;還可以通過監(jiān)控中的tikv,查看各節(jié)點CPU和IO使用情況,當出現(xiàn)熱點問題是,這兩個指標在各個節(jié)點時很不均勻的,尤其THread cpu的corprocessor 或 scheduler(負責讀/寫模塊的線程)。
7、解決熱點region的問題,主要在于分散region數(shù)據(jù)的分布,減少頻繁讀寫同一個region。通過減少單批次提交記錄數(shù)(小事務(wù)),非自增亂序的主鍵(官網(wǎng)要求int類型的主鍵。5.0之后將支持vchar),頻繁訪問相同數(shù)據(jù)通過內(nèi)存訪問,從業(yè)務(wù)層面拆分熱點數(shù)據(jù)等手段減少熱點。但在所有的tikv都出現(xiàn)較多熱點region時,這時應(yīng)考慮擴充tikv節(jié)點。當tikv節(jié)點region分布不均勻,CPU和IO使用率不均勻時,還應(yīng)考慮硬件性能問題,部分硬件性能會影響整體系統(tǒng)性能。
8、RocksDB默認使用snappy壓縮算法,不過TiKV有分層使用壓縮算法,默認["no", "no", "lz4", "lz4", "lz4", "zstd", "zstd"]當數(shù)據(jù)量超過 500G 時 RocksDB 的層數(shù)才會超過 4, 超過 500G 部分的數(shù)據(jù)才會啟動 ZSTD 壓縮算法。lz4解壓縮速度及壓縮比都優(yōu)于snappy;ZSTD壓縮比更高,解壓縮比lz4慢,適合層級高的老數(shù)據(jù)。
9、RocksDB的LSM樹,如圖:wal相當于MySQL 的redo log。從wal->menorytable(可修改Memtable--》不可修改immutable Memtable)->SST,讀放大和寫放大問題都會存在,寫放大在于sst逐漸往下compact(異步線程);而讀放大在于需要逐層查找,且層數(shù)越往下,壓縮率越高,效率越低。
10、理論上,tidb-server節(jié)點和tikv節(jié)點都可以無限擴充,但是PD整個集群只能有一個leader,因此擴充能力受限于PD節(jié)點的處理能力,此外網(wǎng)絡(luò)帶寬也是限制因素之一。
未完待續(xù)......
raft算法與分布式事務(wù)percolator、兩階段提交
為何使用kv存儲引擎
兩個tidb集群間實時同步(異地雙中心雙活)
參考資料
TiDB官網(wǎng)
官網(wǎng)FAQ
TiDB in action
在線修改配置,非持久化配置
LSM && RocksDB compaction策略
RocksDB解析
region調(diào)度策略
TiDB 高并發(fā)寫入場景最佳實踐
TiDB 熱點問題處理
海量 Region 集群調(diào)優(yōu)
Percolator 和 TiDB 事務(wù)算法
TiDB 集群推薦使用 SSD 的原因



































