摘要:本文為今年年初商業(yè)產(chǎn)品團(tuán)隊(duì)負(fù)責(zé)人劉寅在上分享的工具鏈和生態(tài)實(shí)錄內(nèi)容,詳細(xì)介紹了的周邊工具以及生態(tài)系統(tǒng)。大家下午好,我叫劉寅。部署工具就先介紹這么多。首先是,這個(gè)小工具在很多生產(chǎn)環(huán)境上已經(jīng)用起來了。它是一個(gè)到間的實(shí)時(shí)同步工具。
本文為今年年初 PingCAP 商業(yè)產(chǎn)品團(tuán)隊(duì)負(fù)責(zé)人劉寅在 TiDB DevCon2018 上分享的 《 TiDB 工具鏈和生態(tài)》實(shí)錄內(nèi)容,詳細(xì)介紹了 TiDB 的周邊工具以及生態(tài)系統(tǒng)。
大家下午好,我叫劉寅。在 PingCAP 主要負(fù)責(zé) TiDB 商業(yè)工具產(chǎn)品開發(fā),也在做公司 SRE 方面的事情。今天下午我分享的主題是介紹下 TiDB 的周邊工具以及生態(tài)系統(tǒng)。
今天要講的內(nèi)容主要包含這幾方面,首先是關(guān)于 TiDB 的部署,這是很多使用 TiDB 的用戶首先關(guān)心的事情。接下來會(huì)介紹 TiDB 的數(shù)據(jù)導(dǎo)入工具和數(shù)據(jù)遷移同步工具,以及管理配置,數(shù)據(jù)可視化相關(guān)的工具。
TiDB 的架構(gòu)可能大家都比較清楚了。TiDB 是一個(gè)由若干模塊組成的分布式系統(tǒng)。這些模塊相互依賴協(xié)調(diào)工作組成一個(gè)集群,整體構(gòu)成了 TiDB 數(shù)據(jù)庫。這樣一個(gè)架構(gòu),對(duì)于用戶進(jìn)行部署和運(yùn)維,其復(fù)雜程度相對(duì)單機(jī)數(shù)據(jù)庫比如 MySQL 來說不那么容易的事情。那讓我們來看看如何快速部署一套 TiDB 集群實(shí)例。最近我們公開了一個(gè)項(xiàng)目 pingcap/tidb-docker-compose,這令我們?cè)谝粋€(gè)本地的開發(fā)和測(cè)試環(huán)境上跑一套 TiDB 變得非常簡(jiǎn)單。只需要用一個(gè)命令 docker-compose up 就能快速啟動(dòng)起來。docker-compose 是 Docker 生態(tài)中的一個(gè)非常便利的工具,它可以在本機(jī)方便的把 TiDB 的各個(gè)組件,包括它的監(jiān)控,可視化工具,全部整合在一個(gè) yaml 文件來描述,非常的方便。不僅可以通過我們官方 docker image 鏡像啟動(dòng),也可以支持從本地的 binary 啟動(dòng)。比如當(dāng)我本機(jī)編譯了一個(gè)特殊版本的 binary,我就可以直接構(gòu)建本地鏡像來啟動(dòng),甚至還可以支持現(xiàn)場(chǎng)編譯源碼來啟動(dòng)。所以這對(duì)于我們自己開發(fā)和測(cè)試也是非常方便的。另外我們也做了一個(gè)很簡(jiǎn)化的配置文件,比如我不希望默認(rèn)跑 3 個(gè) TiKV,我想啟 5 個(gè)或者更多,簡(jiǎn)單的改下配置就可以搞定。
對(duì)于生產(chǎn)環(huán)境的部署和運(yùn)維,往往面對(duì)的是一個(gè)成規(guī)模的集群,docker-compose 的部署方式就不夠了。我們建議采用提供的 Ansible 部署方式。用戶首先在一個(gè) Inventory 文件中描述和編排所需的 TiDB 集群拓?fù)洌缓髨?zhí)行我們提供的 ansible-playbook 腳本,就可以快速部署和運(yùn)維一個(gè)生產(chǎn)環(huán)境下的 TiDB 集群。我們現(xiàn)在很多的線上用戶,也是用了這樣的部署方式。
TiDB Ansible 不僅實(shí)現(xiàn)在裸機(jī)上部署集群,同時(shí)也支持 Cloud 的部署方式。比如說用 Ansible 提供的組件,我們可以基于 AWS / Azure / GCP 上一鍵創(chuàng)建 TiDB 的集群,而將來也會(huì)支持國(guó)內(nèi)的公有云平臺(tái)。其次可以根據(jù)用戶需求,定制集群的拓?fù)洹_@個(gè)比較細(xì),也會(huì)包含 TiDB 的一些周邊工具的部署,比如說 TiDB Binlog 組件。第三,它提供一個(gè)配置管理的功能,包括 TiDB、TiKV 很多的參數(shù)配置。我們也集成進(jìn)去,可以在一個(gè)地方統(tǒng)一管理整個(gè)集群的配置。除此之外,我們對(duì)運(yùn)維操作的執(zhí)行腳本做了一系列的優(yōu)化。這樣對(duì)于在部署一個(gè)規(guī)模龐大的集群會(huì)變得及其方便。另外這里順便還要提一下,我們?cè)?Ansible 部署過程中,我們會(huì)對(duì)硬件和系統(tǒng)環(huán)境做一個(gè)嚴(yán)格的檢查。可能有些用戶出于測(cè)試的目的,使用較低速的機(jī)械硬盤,而達(dá)不到跑 TiDB 的最低要求。所以這里,我們會(huì)有限定要求,會(huì)在安裝過程中交互提示出來。
TiDB 作為一個(gè)可以彈性水平擴(kuò)展的分布式數(shù)據(jù)庫,天生為云而設(shè)計(jì),從初期我們就和容器走的非常近。容器的優(yōu)勢(shì),相信大家都非常了解。首先,它提供了一致化的環(huán)境,用戶不需要去適應(yīng)各種不同的系統(tǒng)環(huán)境,而分別構(gòu)建運(yùn)行時(shí) Binary。另外容器的啟動(dòng)運(yùn)行非常方便,可以很快速的在開發(fā)環(huán)境運(yùn)行或者生產(chǎn)環(huán)境部署。另外容器提供了資源隔離的特性,通過 Namespace 和 CGroups 這些現(xiàn)代操作系統(tǒng)提供的能力,來實(shí)現(xiàn)容器內(nèi)部和外部的資源隔離和限制。
說到容器就不得不提容器編排,TiDB 在與 K8s 的整合方面我們做了非常多的事情。比如在 K8s 之上實(shí)現(xiàn)對(duì) TiDB 集群的自動(dòng)化管理,快速部署、擴(kuò)縮容、以及故障的自動(dòng)愈合。同時(shí)更好的支持云平臺(tái)下的多租戶管理,通過限制單個(gè)租戶的資源的使用,利用容器完成隔離。來保證租戶之間不會(huì)相互影響。不至于說一個(gè)用戶執(zhí)行高負(fù)載的查詢或者寫入,對(duì)同一臺(tái)宿主機(jī)上的其他用戶實(shí)例造成影響。然而 TiDB 存儲(chǔ)本身是有狀態(tài)的,在 K8s 上部署的時(shí)候,如何管理好有狀態(tài)的服務(wù),并且保證存儲(chǔ)的 iops 和延遲方面苛刻的要求,同時(shí)還要保證服務(wù)的高可用性就成為一個(gè)難題。
如果采用 K8s 提供的 native 存儲(chǔ)解決方案,外掛 PV,也就是掛網(wǎng)絡(luò)存儲(chǔ)。但是這樣對(duì)于數(shù)據(jù)庫系統(tǒng)來說,尤其是大量的隨機(jī)讀和順序?qū)懙膱?chǎng)景下,網(wǎng)絡(luò)盤的性能是達(dá)不到要求的。所以說從最開始我們?cè)O(shè)計(jì) TiDB 上云解決方案,其實(shí)主要就是探索 K8s 的本地 PV 解決方案。當(dāng)然現(xiàn)在 K8s 1.9 已經(jīng)開始對(duì) Local PV 有一定支持,而我們?cè)?1.7 的時(shí)候就實(shí)現(xiàn)了一個(gè) Local Storage Manager。我們現(xiàn)在做的一些工作,也逐漸在和社區(qū) K8s 主版本進(jìn)行整合。另外 TiDB 本身是一個(gè)復(fù)雜集群,除了存儲(chǔ)還有網(wǎng)絡(luò),以及周邊工具的管理都需要考慮。為了實(shí)現(xiàn)將專業(yè)領(lǐng)域的運(yùn)維管理變的更加自動(dòng)化,我們?cè)炝?TiDB Operator。Operator 這個(gè) pattern 其實(shí)是最初借鑒 CoreOS 的 Etcd Operator。TiDB Operator 就是降低 TiDB 部署和運(yùn)維的復(fù)雜度,實(shí)現(xiàn)自動(dòng)化的擴(kuò)縮容和故障轉(zhuǎn)移。同時(shí) Operator 在 K8s 上同時(shí)管理多套 TiDB 集群,像在騰訊云和 UCloud 兩個(gè)公有云上,就是用這種方式來實(shí)現(xiàn)多租戶統(tǒng)一化管理。我們實(shí)現(xiàn)的 Local PV 管理機(jī)制,實(shí)質(zhì)上是對(duì)集群中所有本地磁盤的統(tǒng)一管理,并賦予他們生命周期,從而作為 K8s 中的一類資源參與調(diào)度。同時(shí)新版本 K8s 的趨勢(shì)上,在往云上的操作系統(tǒng)方向上發(fā)展,自身的資源以及 API 變的更加開放。我們不需要去改動(dòng) K8s 本身的代碼,而是去做更好的擴(kuò)展,來實(shí)現(xiàn)滿足自己的調(diào)度功能。比如說我們利用 K8s 親和性的特點(diǎn),讓同種類型的服務(wù)運(yùn)行在同一臺(tái)物理機(jī)上,更充分的利用硬件資源。再比如說 PD 和 TiKV 這兩種服務(wù),你不能在一起混部使用同一塊 SSD,否則 IO 會(huì)相互影響。所以我們利用反親和的特性,讓 PD 和 TiKV 調(diào)度的時(shí)候盡量分開。另外再舉一個(gè)調(diào)度的例子,TiDB 集群本身是支持區(qū)分節(jié)點(diǎn)的地域?qū)傩缘模琍D 根據(jù)地域?qū)傩詠韺?shí)現(xiàn)數(shù)據(jù)層面的調(diào)度,并且盡量保證同一份數(shù)據(jù)的多個(gè)副本盡可能按地域分散開。那么 K8s 部署 TiDB 節(jié)點(diǎn)的時(shí)候,也需要考慮地域特征來進(jìn)行調(diào)度。比如按照跨 Region、跨可用區(qū)將一個(gè)集群的節(jié)點(diǎn)分散部署,并且把地域的信息傳遞給 TiKV 和 PD,使數(shù)據(jù)副本盡量分散。而這個(gè)知識(shí)本身 K8s 是不具備的,我們需要擴(kuò)展 K8s 的調(diào)度器把經(jīng)驗(yàn)和原則傳遞進(jìn)去。
Operator 包含一些 TiDB 擴(kuò)展的 Controller 和 Scheduler,但還不夠,我們需要在上面包裝一層,以暴露出來統(tǒng)一的運(yùn)維和管理接口,這就是 Cloud Manager。Cloud Manager 對(duì)外暴露標(biāo)準(zhǔn)化的接口,用于和云平臺(tái)的前端控制臺(tái)對(duì)接,這樣就通過前臺(tái)可以完成 K8s 以及 TiDB 集群的相關(guān)資源的綜合管理。
DBaaS 結(jié)構(gòu)圖可以看到 Cloud TiDB 的分層架構(gòu)。最下層是容器云,中間一層是 K8s 自身的服務(wù)管理和 API Server。我們?cè)诖嘶A(chǔ)上進(jìn)行擴(kuò)展,實(shí)現(xiàn)各種 Controller 和調(diào)度器,自己本地存儲(chǔ)管理 Volume Manager,最終通過 Cloud Manager 提供的 RESTful API 進(jìn)行暴露。可以很容易接一個(gè)前端的 Dashboard,或者直接使用 CLI 命令行工具,完成 TiDB 集群實(shí)例的統(tǒng)一化管理。
這個(gè)圖就是前面講的一些細(xì)節(jié)。這里面可以看到,左半邊是 Kube 本身的組件,右側(cè)是我們的擴(kuò)展出來組件,另外,我們也自己定義了一些 TiDB 的資源類型放在 CDR 里面。比如說 TiDB Cluster,在這個(gè)資源對(duì)象上可以描述要啟動(dòng)多少個(gè) TiKV,多少個(gè) TiDB。另外還有 TiDB Set / TiKV Set / PD Set 等一系列對(duì)象,來分別描述某個(gè)服務(wù)的配置。
這是在騰訊云上面的一個(gè)截圖,
這是UCloud的截圖
現(xiàn)在這兩個(gè)產(chǎn)品都在公測(cè),有興趣的同學(xué)可以關(guān)注一下。
此外,我們提供了 Operator Chart 的安裝方式,使用 Helm 工具可以一鍵通過 Operator 拉起來一套 TiDB 實(shí)例。
這種方式在 K8s 上就更像是一個(gè) RPM 包的方式部署服務(wù),并且管理服務(wù)之間依賴。只需要一行命令,就可以獲得到官方的 Cloud TiDB 的核心組件。如果你有一個(gè) K8s 集群,或者你在使用一個(gè)公有云提供的 K8s 集群,用上面的命令,就可以快速運(yùn)行 TiDB Operator 和 TiDB 集群。
這是一個(gè)配置的例子,打開 charts 壓縮包可以找到對(duì)應(yīng)的配置 yaml 文件。
我們對(duì)每一行的配置做了詳細(xì)的注釋。比如可以設(shè)定一些參數(shù):像副本數(shù)、CPU 內(nèi)存使用限制、TiDB 起多少個(gè)、TiKV 起多少個(gè),等等。
部署工具就先介紹這么多。下一部分,我們開始介紹一下 TiDB 周邊的工具,其實(shí)這里面有一些大家已經(jīng)接觸和使用過了。
首先是 Syncer,這個(gè)小工具在很多生產(chǎn)環(huán)境上已經(jīng)用起來了。它是一個(gè) MySQL 到 TiDB 間的實(shí)時(shí)同步工具。原理很簡(jiǎn)單,就是把自己偽裝成一個(gè) MySQL 的 Slave 庫,從上游 MySQL 里面把 binlog 實(shí)時(shí) dump 出來,并且還原成 SQL 到下游(TiDB)回放。
這里我們支持簡(jiǎn)單的規(guī)則過濾,也支持分庫分表的合并。我們也可以同時(shí)跑多個(gè) Syncer 把多個(gè)上游 MySQL,按庫同步到一個(gè)大的 TiDB 集群。Syncer 的主要一些特性,首先是要支持按 GTID 同步。GTID 是什么?它是 MySQL 自身的 replication 機(jī)制提供的一種特性。MySQL 主從同步最早是以 binlog pos(文件名+offset)來描述同步位置,但這個(gè)設(shè)計(jì)有明顯的缺陷,比如說這樣一個(gè)場(chǎng)景,最初是 1 個(gè) Master 帶 2 個(gè) Slaves,當(dāng) Master 掛了這時(shí)需要把一個(gè) Slave 升級(jí)為 Master,另一個(gè) Slave 從新 Master 繼續(xù)同步。但這樣就要保證,新的 Master 和舊 Master 的 binlog pos 能接續(xù)上,但是 MySQL 不同實(shí)例的 binlog 記錄方式是不同的,因此必須有一個(gè)全局唯一 ID 來和 binlog 對(duì)應(yīng)上,這就是 GTID。在 MySQL 5.6 之后 GTID 支持的就比較好了,生產(chǎn)環(huán)境大多是開啟了這種方式。Syncer 除了支持按 pos 同步,也支持 GTID。Syncer 從公有云的 RDS 同步支持的都比較好,比如像阿里云、騰訊云我們測(cè)的也比較多,因?yàn)樵破脚_(tái)后端機(jī)器故障或者維護(hù),主從切換比較頻繁,而且 Virtual IP 還保持不變對(duì)用戶無感知,所以假如 Syncer 不能很好支持 GTID 的話那切一次主從數(shù)據(jù)就會(huì)不一致了。第二是分庫分表合并。不管上游庫是按庫拆,按表拆,甚至混合拆分,Syncer 都能很好支持,通過配置文件描述出來。另外還有同步性能的問題,因?yàn)?binlog 是一個(gè)單向數(shù)據(jù)流,我們同步的時(shí)候如果是單線程來做雖然比較簡(jiǎn)單,但性能可能很差。使用多線程,就必須區(qū)分對(duì)同一行數(shù)據(jù)操作的因果順序,沒有關(guān)聯(lián)關(guān)系的行可以并行執(zhí)行,有關(guān)聯(lián)的行只能順序執(zhí)行。對(duì)于 MySQL 每一個(gè) binlog event 都是一個(gè)事務(wù),他里面會(huì)包含對(duì)不同表,不同行的多次操作。所以 Syncer 會(huì)對(duì)事務(wù)進(jìn)行拆分,然后并行執(zhí)行。這樣的代價(jià)是 Syncer 不保證按上游的事務(wù)原子性來同步,但最終一致性沒有問題。Syncer 也支持一些簡(jiǎn)單的過濾規(guī)則,可以選擇指定庫或者表同步,也可以做排除。另外也支持一些簡(jiǎn)單的表名映射變換。
在一個(gè)公司初期,可能業(yè)務(wù)鋪的比較快,每塊業(yè)務(wù)用一個(gè) MySQL 庫,不同的業(yè)務(wù)之間數(shù)據(jù)是隔離的。后來業(yè)務(wù)復(fù)雜了,可能 MySQL 要掛從庫了。從庫專門用于一些數(shù)據(jù)分析的場(chǎng)景,而不能影響主庫支撐線上的讀寫。隨著進(jìn)一步的發(fā)展,數(shù)據(jù)分析可能要跨業(yè)務(wù)線,那么跨庫進(jìn)行統(tǒng)計(jì)查詢,比如 Join 和 Sub Query 這樣的操作基本上很難。這個(gè)場(chǎng)景下我們可以把一個(gè) TiDB 集群作為所有線上 MySQL 的 Slave,而使用 Syncer 完成同步。數(shù)據(jù)分析團(tuán)隊(duì)可以在 TiDB 中完成復(fù)雜的關(guān)聯(lián)查詢和分析,這跟使用 MySQL 沒有什么區(qū)別。而且 Syncer 同步的實(shí)時(shí)性很高,使后端的分析可以做到非常的實(shí)時(shí)。
接下來我們介紹一下 TiDB Binlog。TiDB Binlog 本質(zhì)上不同于 MySQL,這個(gè)要聲明一下,我們的 binlog 跟 MySQL 的 binlog 格式不同,TiDB 采用一種自描述的 protobuf 格式的 binlog。而每個(gè) TiDB Server,都會(huì)寫自己的 binlog,一個(gè)事務(wù)就是一個(gè) binlog event。然后通過一個(gè)叫作 Pump 的小程序,匯總寫入到 Kafka 集群。Pump 直接寫本地就好了,為什么還要用 Kafka?這是考慮到 log 落本地盤會(huì)有單點(diǎn)故障的風(fēng)險(xiǎn)。所以采用 Kafka 或者一個(gè)分布式文件系統(tǒng)來解決這個(gè)問題。在下游有一個(gè)叫 Drainer 的組件來消費(fèi) Kafka 的數(shù)據(jù)。Drainer 的職責(zé)是將 binlog 按照事務(wù)的順序還原成 SQL,同步到下游數(shù)據(jù)庫,比如 MySQL,也可能是另外一個(gè) TiDB 集群,還可以寫到文件流實(shí)現(xiàn)增量數(shù)據(jù)備份。
其實(shí) Drainer 做的事情是有一些難度的,因?yàn)?TiDB 不像 MySQL,他是一個(gè)分布式系統(tǒng),大家可以思考一下。首先,怎么保證事務(wù)的完整性,什么意思呢,因?yàn)?TiDB 的事務(wù)大家都知道是兩階段事務(wù)。那么有可能事務(wù)提交成功,但是 binlog 沒有寫成功;也有可能事務(wù)沒有寫成功但是 binlog 發(fā)出去了,這兩種情況都可能導(dǎo)致不一致。第二點(diǎn),如何來還原分布式事務(wù)之間的因果順序。TiDB 事務(wù)是提交到 TiKV 上來執(zhí)行,每個(gè)事務(wù)又是兩階段,事務(wù)的順序號(hào)是由 PD 產(chǎn)生,在同一個(gè) TiDB 節(jié)點(diǎn)上可能會(huì)并發(fā)執(zhí)行多個(gè)事務(wù),所以產(chǎn)生的 binlog 的事務(wù) seq 不能保證單調(diào)遞增,那如何還原順序并實(shí)時(shí)輸出。第三點(diǎn),網(wǎng)絡(luò)本身可能也是不可靠的,你可能寫到 TiDB 是前一個(gè)事務(wù)在前,一個(gè)在后。而在網(wǎng)絡(luò)傳輸?shù)倪^程中,順序可能變化。在多機(jī)都在產(chǎn)生 binlog 的情況下,最終落到 Drainer 的順序是錯(cuò)亂的,那么如何進(jìn)行順序還原。這個(gè)似乎跟 TCP 有點(diǎn)像,但又不太一樣。在 TiDB 里面事務(wù)的全局順序編號(hào)并不是連續(xù)遞增,所以說當(dāng) Drainer 收到了一個(gè) binlog 的時(shí)候,永遠(yuǎn)不知道下一個(gè) binlog 的事務(wù)編號(hào)是多少。至于實(shí)現(xiàn),我們?cè)O(shè)計(jì)了一個(gè)比較復(fù)雜的動(dòng)態(tài)窗口算法。時(shí)間關(guān)系我就不展開講,大家有興趣可以思考一下。
在場(chǎng)景方面,我們用 TiDB Binlog 可以做很多事兒。比如在 TiDB 集群上再掛一個(gè)從集群。也可以同步到 MySQL 做從庫。像一些客戶在線上初期開始使用 TiDB 可能會(huì)比較謹(jǐn)慎,開始把 TiDB 通過 Syncer 掛到 MySQL 的后面做一個(gè)從庫,跑一段時(shí)間驗(yàn)證覺得沒有問題,就可以把它調(diào)換一下。TiDB 成為主庫,用 binlog 去反向同步到 MySQL。再跑一段時(shí)間覺得 OK 了很安全,就可以把 MySQL 從庫摘下來,這樣就完成了一個(gè)灰度上線的過程。此外我們還可以用 binlog 去同步其他異構(gòu)數(shù)據(jù)庫,或者一些數(shù)據(jù)倉庫、或者分布式存儲(chǔ)產(chǎn)品。包括我們也在研發(fā)自己的 OLAP 的存儲(chǔ)引擎。將來都是通過 binlog 來完成數(shù)據(jù)實(shí)時(shí)同步。只需要給 Drainer 寫不同的 Adapter 插件即可。
TiDB Binlog 還可以用于數(shù)據(jù)增量備份,可以找到最近的一個(gè)全量備份點(diǎn),然后回放這段時(shí)間的 Binlog,就可以還原到任意時(shí)間點(diǎn)的數(shù)據(jù)狀態(tài)。另外還有一些場(chǎng)景,比如說有的公司業(yè)務(wù)希望在 binlog 基礎(chǔ)上實(shí)現(xiàn)事件訂閱。我們可以通過監(jiān)聽 binlog,當(dāng)監(jiān)測(cè)到某個(gè)業(yè)務(wù)數(shù)據(jù)發(fā)生變化的時(shí)候往 Kafka 里面觸發(fā)一條消息,類似實(shí)現(xiàn) trigger 的功能。binlog 本身是描述成一種通用的 protobuf 格式,也可以用來驅(qū)動(dòng)流式計(jì)算引擎,來實(shí)現(xiàn)一些異步/流式分析需求。Binlog 的使用場(chǎng)景非常廣泛,可以在實(shí)際業(yè)務(wù)中靈活發(fā)揮。
另外介紹一個(gè)工具就是 Lightning, Lightning可能大家都沒有用到過,因?yàn)槲覀冞€在最后的測(cè)試和優(yōu)化階段,這是一個(gè)快速的 TiDB 導(dǎo)入工具,之前我們提供的工具是 MyDumper,MyDumper 是 MySQL 通用的一個(gè)數(shù)據(jù)導(dǎo)出的工具。它同時(shí)還有一個(gè) MyLoader,我們?cè)谶@個(gè)基礎(chǔ)上又做了一個(gè) TiDB Loader,但這個(gè)東西本質(zhì)上還是去執(zhí)行 SQL。就是說 MyDumper 輸出的數(shù)據(jù)文件是很多的 SQL 文本。那么用 Loader 導(dǎo)入到 TiDB 這個(gè)過程中大家可能會(huì)覺得導(dǎo)數(shù)據(jù)比較慢。這是因?yàn)檫@種方式的數(shù)據(jù)導(dǎo)入,TiKV 底層存儲(chǔ)的 region 要不斷的分裂和搬移,而且一般順序?qū)憯?shù)據(jù),表的主鍵往往是遞增的,這樣會(huì)導(dǎo)致寫入熱點(diǎn),不能同時(shí)把所有 TiKV 節(jié)點(diǎn)都調(diào)動(dòng)起來,失去了分布式的優(yōu)勢(shì)。那么 Lightning 是怎么做的呢?首先我們會(huì)直接把輸入的數(shù)據(jù)格式繞過 SQL 解析器和優(yōu)化器直接轉(zhuǎn)換成有序的 KV 鍵值對(duì),并分批進(jìn)行處理,根據(jù) PD 預(yù)先計(jì)算好新插入數(shù)據(jù)的 Region 分布,然后直接生成 SST 文件 Ingest 到 TiKV 中,非常接近物理數(shù)據(jù)導(dǎo)入。我們?cè)趦?nèi)部測(cè)試比之前的 Loader 方式要快 7 到 10 倍,1T 的數(shù)據(jù)將近在 5 個(gè)小時(shí)之內(nèi)完成導(dǎo)入,預(yù)計(jì)很快會(huì)跟大家見面。
MyDumper 格式的文件作為輸入,首先完成 SQL 到 KV 的轉(zhuǎn)換,它是由若干分布式 worker 來完成,多機(jī)并行執(zhí)行。同時(shí)繞過了優(yōu)化器,生成連續(xù)的 KV 流,再通過一個(gè)專門的 Ingest Server 對(duì) KV 進(jìn)行全局排序。同時(shí)可以預(yù)計(jì)算 region,通過 PD 提前安排調(diào)度到哪個(gè)節(jié)點(diǎn),所以整個(gè)的流程是非常高效的。
接下來介紹一個(gè)我們商業(yè)化工具,叫作 Wormhole。這個(gè)可以理解為是一個(gè)帶控制面板的 Syncer,但比 Syncer 強(qiáng)大。它支持多源多目的地的數(shù)據(jù)同步。而且本身也是分布式結(jié)構(gòu),具有高可用、并行執(zhí)行的特點(diǎn)。另外它對(duì)于分庫分表支持的更好,配置可視化。在同步前檢查也更為嚴(yán)格,比如說同步 MySQL,會(huì)提前檢查表結(jié)構(gòu)和 TiDB 的兼容性,是否開啟 row 模式的 binlog 等等,避免在運(yùn)行過程中發(fā)現(xiàn)了再報(bào)異常。另外 Wormhole 也支持一些簡(jiǎn)單的 ETL 轉(zhuǎn)換規(guī)則,比如在同步過程中對(duì)表的某些字段進(jìn)行簡(jiǎn)單映射計(jì)算和 UDF。比如對(duì)于分庫分表的合并,如果每張分表都有自己的自增主鍵,合表之后插入 TiDB 就可能遇到主鍵沖突。Wormhole 通過配置就可以完成主鍵的合并,也可以新增一個(gè)字段作為真正的主鍵,原表的主鍵保留名字,去掉唯一性約束。
我截了一些界面的圖,可以看到整個(gè)數(shù)據(jù)同步過程中的進(jìn)度,包括全量、增量的同步速度,以及我隨時(shí)可以把它暫停下來,或者進(jìn)行一些特定的操作。對(duì)于多源/目的地這樣同步,像這個(gè)配置,我可以直接把數(shù)據(jù)庫里面的表結(jié)構(gòu)全部讀出來,用在界面上就可以決定同步表和數(shù)據(jù)庫以及字段映射關(guān)系。
接下來第三部分,說說 TiDB 的數(shù)據(jù)可視化。TiDB Vision 這個(gè)項(xiàng)目是開源的,我們會(huì)在 PD 提供的接口上,來實(shí)現(xiàn)數(shù)據(jù)可視化。
從圖中可以清楚的看到在不同節(jié)點(diǎn)上 region 的分布,以及 region leader 的關(guān)系。圖中環(huán)上的每一段,代表一個(gè) TiKV store。每個(gè) store 的每一個(gè)小格代表一個(gè) region,綠色代表是 leader ,中間的這些線段在運(yùn)行過程中是有動(dòng)畫效果的,當(dāng) Leader 發(fā)生分裂,遷移,還有 Leader transfer,都有不同顏色的動(dòng)畫來表示。從而反映一個(gè)真實(shí) PD 產(chǎn)生調(diào)度的過程,我們可以通過可視化很直觀的看到。另外就是熱點(diǎn),這個(gè)圖里可能沒有體現(xiàn),如果某一個(gè) region 出現(xiàn)熱點(diǎn),在界面上就可以看到一些紅色的點(diǎn)。另外,這個(gè)邊緣展示的是每個(gè) PD 調(diào)度的一些網(wǎng)絡(luò)流量,TiKV 的一些流量的信息我們也是實(shí)時(shí)的展示。如果某一個(gè)結(jié)點(diǎn)掛了,在這個(gè)邊緣,它會(huì)有一定的顏色表示,比如說 TiKV 下線,熟悉 TiDB 的人知道,下線 TiKV 并不是立即就下線了,它會(huì)先變成下線中,然后變成 Tombstone 的狀態(tài),這個(gè)在圖上都可以直觀的反映出來。這個(gè)工具非常簡(jiǎn)單,就在 TiDB Vision 開源項(xiàng)目,有興趣的同學(xué),可以給 TiDB 做更多的皮膚。讓這個(gè)展示更 cool,對(duì)業(yè)務(wù)監(jiān)控更有幫助。
這個(gè)是我們?cè)谧龅囊粋€(gè)企業(yè)版的 Dashboard ,這個(gè)可能跟大家看到的 Grafana 還有現(xiàn)有開源的界面不太相同,這里截了一些局部的圖。大家可以看到,每個(gè)節(jié)點(diǎn)上面每個(gè)進(jìn)程的狀態(tài),包括節(jié)點(diǎn)運(yùn)行時(shí)日志,和服務(wù)健康狀態(tài)。通過 Dashboard 就可以把整個(gè)的集群的拓?fù)浜瓦\(yùn)行狀態(tài),全部展示出來。在這個(gè)界面它可以選擇去創(chuàng)建多少個(gè) TiDB 多少個(gè) TiKV 節(jié)點(diǎn),并且選擇規(guī)格。左邊可以選擇升級(jí)的 TiDB 組件版本,完成滾動(dòng)升級(jí)這樣的事情。
最后說一下 TiDB 的監(jiān)控。監(jiān)控我們后臺(tái)用的 Prometheus 這個(gè)非常出名的項(xiàng)目,通過它來做存儲(chǔ)數(shù)據(jù)庫各個(gè)服務(wù)的 metrics。每個(gè) TiDB、TiKV 組件都會(huì)把自己的狀態(tài)上報(bào)到 Prometheus(實(shí)際是 pull 的模式),我們通過 Node Exporter 來采集每臺(tái)主機(jī)的狀態(tài)。而對(duì)于 K8s 集群,是通過 cAdvisor 進(jìn)行收集,把 metrics 在 Prometheus 進(jìn)行匯總。通過 Grafana 來做監(jiān)控和可視化。我們配置好的 Grafana 面板點(diǎn)擊編輯按鈕,都可以看到對(duì)應(yīng)的 Prometheus 查詢表達(dá)式,通過一種類似 SQL 的查詢語句,你就可以很方便的從 Prometheus 拉取監(jiān)控?cái)?shù)據(jù)然后對(duì)接到自己的監(jiān)控平臺(tái)。 Alert manager 也是 Prometheus 生態(tài)里面的一個(gè)工具,它可以去接受 Prometheus 發(fā)出的報(bào)警事件,然后通過各種報(bào)警方式推送出來。日志方面我們也是用比較流行的 EFK 套件。在 K8s 集群中,采集每個(gè) Pod 的日志,存放到 ES 里面再通過 Kibana 進(jìn)行展示。
這個(gè)是監(jiān)控的幾個(gè)截圖,這個(gè)大家可能都比較熟悉了。
最后簡(jiǎn)單聊一下 TiDB 生態(tài),因?yàn)?TiDB 最大的優(yōu)勢(shì)是兼容 MySQL 協(xié)議。所以不光是命令行工具,包括比如 MySQL 自己的 MySQL Workbench 這樣的工具,還有大家用傳統(tǒng)的 Navicat 這樣的產(chǎn)品工具,還有就是一個(gè)老牌的 phpMyAdmin 這樣的 Web 管理工具,都可以直接連到一個(gè) TiDB 實(shí)例。我們同時(shí)也在不斷的優(yōu)化 TiDB 兼容性,因?yàn)楫吘顾?MySQL 有些區(qū)別。像這些工具,它可能會(huì)去讀 MySQL 的一些系統(tǒng)表,我們會(huì)盡量會(huì)跟 MySQL 保持兼容。還有一些很方便的功能,比如把 schema 抓出來,繪制 ER 圖,其實(shí)我們也希望在 TiDB 上跑的很順暢。這樣習(xí)慣使用 MySQL 各種管理工具的用戶,可以非常平滑的切換到 TiDB。
我今天介紹的內(nèi)容主要就這些了,謝謝大家!
延展閱讀:
吳鏑:TiDB 在今日頭條的實(shí)踐
李雨來 :Query Cache in TiDB
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/17718.html
閱讀 1843·2021-09-22 15:55
閱讀 3533·2021-09-07 10:26
閱讀 638·2019-08-30 15:54
閱讀 694·2019-08-29 16:34
閱讀 848·2019-08-26 14:04
閱讀 3271·2019-08-26 11:47
閱讀 2142·2019-08-26 11:33
閱讀 2300·2019-08-23 15:17