劉寅:TiDB 工具鏈和生態

本文爲今年年初 PingCAP 商業產品團隊負責人劉寅在 TiDB DevCon2018 上分享的 《 TiDB 工具鏈和生態》實錄內容,詳細介紹了 TiDB 的周邊工具以及生態系統。

你們下午好,我叫劉寅。在 PingCAP 主要負責 TiDB 商業工具產品開發,也在作公司 SRE 方面的事情。今天下午我分享的主題是介紹下 TiDB 的周邊工具以及生態系統。php

今天要講的內容主要包含這幾方面,首先是關於 TiDB 的部署,這是不少使用 TiDB 的用戶首先關心的事情。接下來會介紹 TiDB 的數據導入工具和數據遷移同步工具,以及管理配置,數據可視化相關的工具。前端

TiDB 的架構可能你們都比較清楚了。TiDB 是一個由若干模塊組成的分佈式系統。這些模塊相互依賴協調工做組成一個集羣,總體構成了 TiDB 數據庫。這樣一個架構,對於用戶進行部署和運維,其複雜程度相對單機數據庫好比 MySQL 來講不那麼容易的事情。那讓咱們來看看如何快速部署一套 TiDB 集羣實例。最近咱們公開了一個項目 pingcap/tidb-docker-compose,這令咱們在一個本地的開發和測試環境上跑一套 TiDB 變得很是簡單。只須要用一個命令 docker-compose up 就能快速啓動起來。docker-compose 是 Docker 生態中的一個很是便利的工具,它能夠在本機方便的把 TiDB 的各個組件,包括它的監控,可視化工具,所有整合在一個 yaml 文件來描述,很是的方便。不只能夠經過咱們官方 docker image 鏡像啓動,也能夠支持從本地的 binary 啓動。好比當我本機編譯了一個特殊版本的 binary,我就能夠直接構建本地鏡像來啓動,甚至還能夠支持現場編譯源碼來啓動。因此這對於咱們本身開發和測試也是很是方便的。另外咱們也作了一個很簡化的配置文件,好比我不但願默認跑 3 個 TiKV,我想啓 5 個或者更多,簡單的改下配置就能夠搞定。git

對於生產環境的部署和運維,每每面對的是一個成規模的集羣,docker-compose 的部署方式就不夠了。咱們建議採用提供的 Ansible 部署方式。用戶首先在一個 Inventory 文件中描述和編排所需的 TiDB 集羣拓撲,而後執行咱們提供的 ansible-playbook 腳本,就能夠快速部署和運維一個生產環境下的 TiDB 集羣。咱們如今不少的線上用戶,也是用了這樣的部署方式。github

TiDB Ansible 不只實如今裸機上部署集羣,同時也支持 Cloud 的部署方式。好比說用 Ansible 提供的組件,咱們能夠基於 AWS / Azure / GCP 上一鍵建立 TiDB 的集羣,而未來也會支持國內的公有云平臺。其次能夠根據用戶需求,定製集羣的拓撲。這個比較細,也會包含 TiDB 的一些周邊工具的部署,好比說 TiDB Binlog 組件。第三,它提供一個配置管理的功能,包括 TiDB、TiKV 不少的參數配置。咱們也集成進去,能夠在一個地方統一管理整個集羣的配置。除此以外,咱們對運維操做的執行腳本作了一系列的優化。這樣對於在部署一個規模龐大的集羣會變得及其方便。另外這裏順便還要提一下,咱們在 Ansible 部署過程當中,咱們會對硬件和系統環境作一個嚴格的檢查。可能有些用戶出於測試的目的,使用較低速的機械硬盤,而達不到跑 TiDB 的最低要求。因此這裏,咱們會有限定要求,會在安裝過程當中交互提示出來。算法

TiDB 做爲一個能夠彈性水平擴展的分佈式數據庫,天生爲雲而設計,從初期咱們就和容器走的很是近。容器的優點,相信你們都很是瞭解。首先,它提供了一致化的環境,用戶不須要去適應各類不一樣的系統環境,而分別構建運行時 Binary。另外容器的啓動運行很是方便,能夠很快速的在開發環境運行或者生產環境部署。另外容器提供了資源隔離的特性,經過 Namespace 和 CGroups 這些現代操做系統提供的能力,來實現容器內部和外部的資源隔離和限制。docker

圖片描述

說到容器就不得不提容器編排,TiDB 在與 K8s 的整合方面咱們作了很是多的事情。好比在 K8s 之上實現對 TiDB 集羣的自動化管理,快速部署、擴縮容、以及故障的自動癒合。同時更好的支持雲平臺下的多租戶管理,經過限制單個租戶的資源的使用,利用容器完成隔離。來保證租戶之間不會相互影響。不至於說一個用戶執行高負載的查詢或者寫入,對同一臺宿主機上的其餘用戶實例形成影響。然而 TiDB 存儲自己是有狀態的,在 K8s 上部署的時候,如何管理好有狀態的服務,而且保證存儲的 iops 和延遲方面苛刻的要求,同時還要保證服務的高可用性就成爲一個難題。數據庫

若是採用 K8s 提供的 native 存儲解決方案,外掛 PV,也就是掛網絡存儲。可是這樣對於數據庫系統來講,尤爲是大量的隨機讀和順序寫的場景下,網絡盤的性能是達不到要求的。因此說從最開始咱們設計 TiDB 上雲解決方案,其實主要就是探索 K8s 的本地 PV 解決方案。固然如今 K8s 1.9 已經開始對 Local PV 有必定支持,而咱們在 1.7 的時候就實現了一個 Local Storage Manager。咱們如今作的一些工做,也逐漸在和社區 K8s 主版本進行整合。另外 TiDB 自己是一個複雜集羣,除了存儲還有網絡,以及周邊工具的管理都須要考慮。爲了實現將專業領域的運維管理變的更加自動化,咱們造了 TiDB Operator。Operator 這個 pattern 實際上是最初借鑑 CoreOS 的 Etcd Operator。TiDB Operator 就是下降 TiDB 部署和運維的複雜度,實現自動化的擴縮容和故障轉移。同時 Operator 在 K8s 上同時管理多套 TiDB 集羣,像在騰訊雲和 UCloud 兩個公有云上,就是用這種方式來實現多租戶統一化管理。咱們實現的 Local PV 管理機制,實質上是對集羣中全部本地磁盤的統一管理,並賦予他們生命週期,從而做爲 K8s 中的一類資源參與調度。同時新版本 K8s 的趨勢上,在往雲上的操做系統方向上發展,自身的資源以及 API 變的更加開放。咱們不須要去改動 K8s 自己的代碼,而是去作更好的擴展,來實現知足本身的調度功能。好比說咱們利用 K8s 親和性的特色,讓同種類型的服務運行在同一臺物理機上,更充分的利用硬件資源。再好比說 PD 和 TiKV 這兩種服務,你不能在一塊兒混部使用同一塊 SSD,不然 IO 會相互影響。因此咱們利用反親和的特性,讓 PD 和 TiKV 調度的時候儘可能分開。另外再舉一個調度的例子,TiDB 集羣自己是支持區分節點的地域屬性的,PD 根據地域屬性來實現數據層面的調度,而且儘可能保證同一份數據的多個副本儘量按地域分散開。那麼 K8s 部署 TiDB 節點的時候,也須要考慮地域特徵來進行調度。好比按照跨 Region、跨可用區將一個集羣的節點分散部署,而且把地域的信息傳遞給 TiKV 和 PD,使數據副本儘可能分散。而這個知識自己 K8s 是不具有的,咱們須要擴展 K8s 的調度器把經驗和原則傳遞進去。小程序

Operator 包含一些 TiDB 擴展的 Controller 和 Scheduler,但還不夠,咱們須要在上面包裝一層,以暴露出來統一的運維和管理接口,這就是 Cloud Manager。Cloud Manager 對外暴露標準化的接口,用於和雲平臺的前端控制檯對接,這樣就經過前臺能夠完成 K8s 以及 TiDB 集羣的相關資源的綜合管理。後端

1-daas-1.png

DBaaS 結構圖能夠看到 Cloud TiDB 的分層架構。最下層是容器雲,中間一層是 K8s 自身的服務管理和 API Server。咱們在此基礎上進行擴展,實現各類 Controller 和調度器,本身本地存儲管理 Volume Manager,最終經過 Cloud Manager 提供的 RESTful API 進行暴露。能夠很容易接一個前端的 Dashboard,或者直接使用 CLI 命令行工具,完成 TiDB 集羣實例的統一化管理。安全

2-daas-2.png

這個圖就是前面講的一些細節。這裏面能夠看到,左半邊是 Kube 自己的組件,右側是咱們的擴展出來組件,另外,咱們也本身定義了一些 TiDB 的資源類型放在 CDR 裏面。好比說 TiDB Cluster,在這個資源對象上能夠描述要啓動多少個 TiKV,多少個 TiDB。另外還有 TiDB Set / TiKV Set / PD Set 等一系列對象,來分別描述某個服務的配置。

這是在騰訊雲上面的一個截圖,

3-tencent-cloud.png

這是UCloud的截圖

4-ucloud.png

如今這兩個產品都在公測,有興趣的同窗能夠關注一下。

此外,咱們提供了 Operator Chart 的安裝方式,使用 Helm 工具能夠一鍵經過 Operator 拉起來一套 TiDB 實例。

5-operator.png

這種方式在 K8s 上就更像是一個 RPM 包的方式部署服務,而且管理服務之間依賴。只須要一行命令,就能夠得到到官方的 Cloud TiDB 的核心組件。若是你有一個 K8s 集羣,或者你在使用一個公有云提供的 K8s 集羣,用上面的命令,就能夠快速運行 TiDB Operator 和 TiDB 集羣。

這是一個配置的例子,打開 charts 壓縮包能夠找到對應的配置 yaml 文件。

6-configuration.png

咱們對每一行的配置作了詳細的註釋。好比能夠設定一些參數:像副本數、CPU 內存使用限制、TiDB 起多少個、TiKV 起多少個,等等。

部署工具就先介紹這麼多。下一部分,咱們開始介紹一下 TiDB 周邊的工具,其實這裏面有一些你們已經接觸和使用過了。

首先是 Syncer,這個小工具在不少生產環境上已經用起來了。它是一個 MySQL 到 TiDB 間的實時同步工具。原理很簡單,就是把本身假裝成一個 MySQL 的 Slave 庫,從上游 MySQL 裏面把 binlog 實時 dump 出來,而且還原成 SQL 到下游(TiDB)回放。

這裏咱們支持簡單的規則過濾,也支持分庫分表的合併。咱們也能夠同時跑多個 Syncer 把多個上游 MySQL,按庫同步到一個大的 TiDB 集羣。Syncer 的主要一些特性,首先是要支持按 GTID 同步。GTID 是什麼?它是 MySQL 自身的 replication 機制提供的一種特性。MySQL 主從同步最先是以 binlog pos(文件名+offset)來描述同步位置,但這個設計有明顯的缺陷,好比說這樣一個場景,最初是 1 個 Master 帶 2 個 Slaves,當 Master 掛了這時須要把一個 Slave 升級爲 Master,另外一個 Slave 重新 Master 繼續同步。但這樣就要保證,新的 Master 和舊 Master 的 binlog pos 能接續上,可是 MySQL 不一樣實例的 binlog 記錄方式是不一樣的,所以必須有一個全局惟一 ID 來和 binlog 對應上,這就是 GTID。在 MySQL 5.6 以後 GTID 支持的就比較好了,生產環境大可能是開啓了這種方式。Syncer 除了支持按 pos 同步,也支持 GTID。Syncer 從公有云的 RDS 同步支持的都比較好,好比像阿里雲、騰訊雲咱們測的也比較多,由於雲平臺後端機器故障或者維護,主從切換比較頻繁,並且 Virtual IP 還保持不變對用戶無感知,因此假如 Syncer 不能很好支持 GTID 的話那切一次主從數據就會不一致了。第二是分庫分表合併。無論上游庫是按庫拆,按表拆,甚至混合拆分,Syncer 都能很好支持,經過配置文件描述出來。另外還有同步性能的問題,由於 binlog 是一個單向數據流,咱們同步的時候若是是單線程來作雖然比較簡單,但性能可能不好。使用多線程,就必須區分對同一行數據操做的因果順序,沒有關聯關係的行能夠並行執行,有關聯的行只能順序執行。對於 MySQL 每個 binlog event 都是一個事務,他裏面會包含對不一樣表,不一樣行的屢次操做。因此 Syncer 會對事務進行拆分,而後並行執行。這樣的代價是 Syncer 不保證按上游的事務原子性來同步,但最終一致性沒有問題。Syncer 也支持一些簡單的過濾規則,能夠選擇指定庫或者表同步,也能夠作排除。另外也支持一些簡單的表名映射變換。

在一個公司初期,可能業務鋪的比較快,每塊業務用一個 MySQL 庫,不一樣的業務之間數據是隔離的。後來業務複雜了,可能 MySQL 要掛從庫了。從庫專門用於一些數據分析的場景,而不能影響主庫支撐線上的讀寫。隨着進一步的發展,數據分析可能要跨業務線,那麼跨庫進行統計查詢,好比 Join 和 Sub Query 這樣的操做基本上很難。這個場景下咱們能夠把一個 TiDB 集羣做爲全部線上 MySQL 的 Slave,而使用 Syncer 完成同步。數據分析團隊能夠在 TiDB 中完成複雜的關聯查詢和分析,這跟使用 MySQL 沒有什麼區別。並且 Syncer 同步的實時性很高,使後端的分析能夠作到很是的實時。

接下來咱們介紹一下 TiDB Binlog。TiDB Binlog 本質上不一樣於 MySQL,這個要聲明一下,咱們的 binlog 跟 MySQL 的 binlog 格式不一樣,TiDB 採用一種自描述的 protobuf 格式的 binlog。而每一個 TiDB Server,都會寫本身的 binlog,一個事務就是一個 binlog event。而後經過一個叫做 Pump 的小程序,彙總寫入到 Kafka 集羣。Pump 直接寫本地就行了,爲何還要用 Kafka?這是考慮到 log 落本地盤會有單點故障的風險。因此採用 Kafka 或者一個分佈式文件系統來解決這個問題。在下游有一個叫 Drainer 的組件來消費 Kafka 的數據。Drainer 的職責是將 binlog 按照事務的順序還原成 SQL,同步到下游數據庫,好比 MySQL,也多是另一個 TiDB 集羣,還能夠寫到文件流實現增量數據備份。

其實 Drainer 作的事情是有一些難度的,由於 TiDB 不像 MySQL,他是一個分佈式系統,你們能夠思考一下。首先,怎麼保證事務的完整性,什麼意思呢,由於 TiDB 的事務你們都知道是兩階段事務。那麼有可能事務提交成功,可是 binlog 沒有寫成功;也有可能事務沒有寫成功可是 binlog 發出去了,這兩種狀況均可能致使不一致。第二點,如何來還原分佈式事務之間的因果順序。TiDB 事務是提交到 TiKV 上來執行,每一個事務又是兩階段,事務的順序號是由 PD 產生,在同一個 TiDB 節點上可能會併發執行多個事務,因此產生的 binlog 的事務 seq 不能保證單調遞增,那如何還原順序並實時輸出。第三點,網絡自己可能也是不可靠的,你可能寫到 TiDB 是前一個事務在前,一個在後。而在網絡傳輸的過程當中,順序可能變化。在多機都在產生 binlog 的狀況下,最終落到 Drainer 的順序是錯亂的,那麼如何進行順序還原。這個彷佛跟 TCP 有點像,但又不太同樣。在 TiDB 裏面事務的全局順序編號並非連續遞增,因此說當 Drainer 收到了一個 binlog 的時候,永遠不知道下一個 binlog 的事務編號是多少。至於實現,咱們設計了一個比較複雜的動態窗口算法。時間關係我就不展開講,你們有興趣能夠思考一下。

在場景方面,咱們用 TiDB Binlog 能夠作不少事兒。好比在 TiDB 集羣上再掛一個從集羣。也能夠同步到 MySQL 作從庫。像一些客戶在線上初期開始使用 TiDB 可能會比較謹慎,開始把 TiDB 經過 Syncer 掛到 MySQL 的後面作一個從庫,跑一段時間驗證以爲沒有問題,就能夠把它調換一下。TiDB 成爲主庫,用 binlog 去反向同步到 MySQL。再跑一段時間以爲 OK 了很安全,就能夠把 MySQL 從庫摘下來,這樣就完成了一個灰度上線的過程。此外咱們還能夠用 binlog 去同步其餘異構數據庫,或者一些數據倉庫、或者分佈式存儲產品。包括咱們也在研發本身的 OLAP 的存儲引擎。未來都是經過 binlog 來完成數據實時同步。只須要給 Drainer 寫不一樣的 Adapter 插件便可。

TiDB Binlog 還能夠用於數據增量備份,能夠找到最近的一個全量備份點,而後回放這段時間的 Binlog,就能夠還原到任意時間點的數據狀態。另外還有一些場景,好比說有的公司業務但願在 binlog 基礎上實現事件訂閱。咱們能夠經過監聽 binlog,當監測到某個業務數據發生變化的時候往 Kafka 裏面觸發一條消息,相似實現 trigger 的功能。binlog 自己是描述成一種通用的 protobuf 格式,也能夠用來驅動流式計算引擎,來實現一些異步/流式分析需求。Binlog 的使用場景很是普遍,能夠在實際業務中靈活發揮。

另外介紹一個工具就是 Lightning, Lightning可能你們都沒有用到過,由於咱們還在最後的測試和優化階段,這是一個快速的 TiDB 導入工具,以前咱們提供的工具是 MyDumper,MyDumper 是 MySQL 通用的一個數據導出的工具。它同時還有一個 MyLoader,咱們在這個基礎上又作了一個 TiDB Loader,但這個東西本質上仍是去執行 SQL。就是說 MyDumper 輸出的數據文件是不少的 SQL 文本。那麼用 Loader 導入到 TiDB 這個過程當中你們可能會以爲導數據比較慢。這是由於這種方式的數據導入,TiKV 底層存儲的 region 要不斷的分裂和搬移,並且通常順序寫數據,表的主鍵每每是遞增的,這樣會致使寫入熱點,不能同時把全部 TiKV 節點都調動起來,失去了分佈式的優點。那麼 Lightning 是怎麼作的呢?首先咱們會直接把輸入的數據格式繞過 SQL 解析器和優化器直接轉換成有序的 KV 鍵值對,並分批進行處理,根據 PD 預先計算好新插入數據的 Region 分佈,而後直接生成 SST 文件 Ingest 到 TiKV 中,很是接近物理數據導入。咱們在內部測試比以前的 Loader 方式要快 7 到 10 倍,1T 的數據將近在 5 個小時以內完成導入,預計很快會跟你們見面。

7-tools-lightning.png

MyDumper 格式的文件做爲輸入,首先完成 SQL 到 KV 的轉換,它是由若干分佈式 worker 來完成,多機並行執行。同時繞過了優化器,生成連續的 KV 流,再經過一個專門的 Ingest Server 對 KV 進行全局排序。同時能夠預計算 region,經過 PD 提早安排調度到哪一個節點,因此整個的流程是很是高效的。

接下來介紹一個咱們商業化工具,叫做 Wormhole。這個能夠理解爲是一個帶控制面板的 Syncer,但比 Syncer 強大。它支持多源多目的地的數據同步。並且自己也是分佈式結構,具備高可用、並行執行的特色。另外它對於分庫分表支持的更好,配置可視化。在同步前檢查也更爲嚴格,好比說同步 MySQL,會提早檢查表結構和 TiDB 的兼容性,是否開啓 row 模式的 binlog 等等,避免在運行過程當中發現了再報異常。另外 Wormhole 也支持一些簡單的 ETL 轉換規則,好比在同步過程當中對錶的某些字段進行簡單映射計算和 UDF。好比對於分庫分表的合併,若是每張分表都有本身的自增主鍵,合表以後插入 TiDB 就可能遇到主鍵衝突。Wormhole 經過配置就能夠完成主鍵的合併,也能夠新增一個字段做爲真正的主鍵,原表的主鍵保留名字,去掉惟一性約束。

8-tools-wormhole.png

我截了一些界面的圖,能夠看到整個數據同步過程當中的進度,包括全量、增量的同步速度,以及我隨時能夠把它暫停下來,或者進行一些特定的操做。對於多源/目的地這樣同步,像這個配置,我能夠直接把數據庫裏面的表結構所有讀出來,用在界面上就能夠決定同步表和數據庫以及字段映射關係。

接下來第三部分,說說 TiDB 的數據可視化。TiDB Vision 這個項目是開源的,咱們會在 PD 提供的接口上,來實現數據可視化。

9-tools-insight.png

從圖中能夠清楚的看到在不一樣節點上 region 的分佈,以及 region leader 的關係。圖中環上的每一段,表明一個 TiKV store。每一個 store 的每個小格表明一個 region,綠色表明是 leader ,中間的這些線段在運行過程當中是有動畫效果的,當 Leader 發生分裂,遷移,還有 Leader transfer,都有不一樣顏色的動畫來表示。從而反映一個真實 PD 產生調度的過程,咱們能夠經過可視化很直觀的看到。另外就是熱點,這個圖裏可能沒有體現,若是某一個 region 出現熱點,在界面上就能夠看到一些紅色的點。另外,這個邊緣展現的是每一個 PD 調度的一些網絡流量,TiKV 的一些流量的信息咱們也是實時的展現。若是某一個結點掛了,在這個邊緣,它會有必定的顏色表示,好比說 TiKV 下線,熟悉 TiDB 的人知道,下線 TiKV 並非當即就下線了,它會先變成下線中,而後變成 Tombstone 的狀態,這個在圖上均可以直觀的反映出來。這個工具很是簡單,就在 TiDB Vision 開源項目,有興趣的同窗,能夠給 TiDB 作更多的皮膚。讓這個展現更 cool,對業務監控更有幫助。

這個是咱們在作的一個企業版的 Dashboard ,這個可能跟你們看到的 Grafana 還有現有開源的界面不太相同,這裏截了一些局部的圖。你們能夠看到,每一個節點上面每一個進程的狀態,包括節點運行時日誌,和服務健康狀態。經過 Dashboard 就能夠把整個的集羣的拓撲和運行狀態,所有展現出來。在這個界面它能夠選擇去建立多少個 TiDB 多少個 TiKV 節點,而且選擇規格。左邊能夠選擇升級的 TiDB 組件版本,完成滾動升級這樣的事情。

10-tools-dashboard.png

最後說一下 TiDB 的監控。監控咱們後臺用的 Prometheus 這個很是出名的項目,經過它來作存儲數據庫各個服務的 metrics。每一個 TiDB、TiKV 組件都會把本身的狀態上報到 Prometheus(實際是 pull 的模式),咱們經過 Node Exporter 來採集每臺主機的狀態。而對於 K8s 集羣,是經過 cAdvisor 進行收集,把 metrics 在 Prometheus 進行彙總。經過 Grafana 來作監控和可視化。咱們配置好的 Grafana 面板點擊編輯按鈕,均可以看到對應的 Prometheus 查詢表達式,經過一種相似 SQL 的查詢語句,你就能夠很方便的從 Prometheus 拉取監控數據而後對接到本身的監控平臺。 Alert manager 也是 Prometheus 生態裏面的一個工具,它能夠去接受 Prometheus 發出的報警事件,而後經過各類報警方式推送出來。日誌方面咱們也是用比較流行的 EFK 套件。在 K8s 集羣中,採集每一個 Pod 的日誌,存放到 ES 裏面再經過 Kibana 進行展現。

11-monitor-alerting.png

這個是監控的幾個截圖,這個你們可能都比較熟悉了。

12-monitor-alerting.png

最後簡單聊一下 TiDB 生態,由於 TiDB 最大的優點是兼容 MySQL 協議。因此不光是命令行工具,包括好比 MySQL 本身的 MySQL Workbench 這樣的工具,還有你們用傳統的 Navicat 這樣的產品工具,還有就是一個老牌的 phpMyAdmin 這樣的 Web 管理工具,均可以直接連到一個 TiDB 實例。咱們同時也在不斷的優化 TiDB 兼容性,由於畢竟它跟 MySQL 有些區別。像這些工具,它可能會去讀 MySQL 的一些系統表,咱們會盡可能會跟 MySQL 保持兼容。還有一些很方便的功能,好比把 schema 抓出來,繪製 ER 圖,其實咱們也但願在 TiDB 上跑的很順暢。這樣習慣使用 MySQL 各類管理工具的用戶,能夠很是平滑的切換到 TiDB。

我今天介紹的內容主要就這些了,謝謝你們!

延展閱讀:
吳鏑:TiDB 在今日頭條的實踐
李雨來 :Query Cache in TiDB

相關文章
相關標籤/搜索