在美團,基於 MySQL 構建的傳統關係型數據庫服務已經難於支撐公司業務的爆發式增加,促使咱們去探索更合理的數據存儲方案和實踐新的運維方式。隨着近一兩年來分佈式數據庫大放異彩,美團 DBA 團隊聯合架構存儲團隊,於 2018 年初啓動了分佈式數據庫項目。git
圖 1 美團點評產品展現圖github
立項之初,咱們進行了大量解決方案的對比,深刻了解了業界多種 scale-out、scale-up 方案,考慮到技術架構的前瞻性、發展潛力、社區活躍度、以及服務自己與 MySQL 的兼容性,最終敲定了基於 TiDB 數據庫進行二次開發的總體方案,並與 PingCAP 官方和開源社區進行深刻合做的開發模式。算法
美團業務線衆多,咱們根據業務特色及重要程度逐步推動上線,到截稿爲止,已經上線 10 個集羣,近 200 個物理節點,大部分是 OLTP 類型的應用,除了上線初期遇到了一些小問題,目前均已穩定運行。初期上線的集羣,已經分別服務於配送、出行、閃付、酒旅等業務。數據庫
TiDB 架構分層清晰,服務平穩流暢,但在美團當前的數據量規模和已有穩定的存儲體系的基礎上,推廣新的存儲服務體系,須要對周邊工具和系統進行一系列改造和適配,從初期探索到整合落地須要走很遠的路。下面從幾個方面分別介紹:安全
咱們對於 TiDB 的定位,前期在於重點解決 MySQL 的單機性能和容量沒法線性和靈活擴展的問題,與 MySQL 造成互補。業界分佈式方案不少,咱們爲什麼選擇了 TiDB 呢?考慮到公司業務規模的快速增加,以及公司內關係數據庫以 MySQL 爲主的現狀,所以咱們在調研階段,對如下技術特性進行了重點考慮:多線程
業界的一些傳統方案雖然支持分片,但沒法自動分裂、遷移,不支持分佈式事務,還有一些在傳統 MySQL 上開發一致性協議的方案,但它沒法實現線性擴展,最終咱們選擇了與咱們的需求最爲接近的 TiDB。與 MySQL 語法和特性高度兼容,具備靈活的在線擴容縮容特性,支持 ACID 的強一致性事務,能夠跨機房部署實現跨機房容災,支持多節點寫入,對業務又能像單機 MySQL 同樣使用。架構
針對官方聲稱的以上優勢,咱們進行了大量的研究、測試和驗證。併發
首先,咱們須要知道擴容、Region 分裂轉移的細節、Schema 到 kv 的映射、分佈式事務的實現原理。而 TiDB 的方案,參考了較多的 Google 論文,咱們進行了閱讀,這有助於咱們理解 TiDB 的存儲結構、事務算法、安全性等,包括:負載均衡
咱們也進行了常規的性能和功能測試,用來與 MySQL 的指標進行對比,其中一個比較特別的測試,是證實 3 副本跨機房部署,確實能保證每一個機房分佈一個副本,從而保證任何一個機房宕機不會致使丟失超過半數副本。從如下幾個點進行測試:運維
從測試結果來看,一切都符合預期。
美團的產品線豐富,業務體量大,業務對在線存儲的服務質量要求也很是高。所以,從早期作好服務體系的規劃很是重要。下面從業務接入層、監控報警、服務部署,來分別介紹一下咱們所作的工做。
當前 MySQL 的業務接入方式主要有兩種,DNS 接入和 Zebra 客戶端接入。在前期調研階段,咱們選擇了 DNS + 負載均衡組件的接入方式,TiDB-Server 節點宕機,15s 能夠被負載均衡識別到,簡單有效。業務架構如圖 2。
圖 2 業務架構圖
後面咱們會逐漸過渡到當前大量使用的 Zebra 接入方式來訪問 TiDB,從而保持與訪問 MySQL 的方式一致,一方面減小業務改造的成本,另外一方面儘可能實現從 MySQL 到 TiDB 的透明遷移。
美團目前使用 Mt-Falcon 平臺負責監控報警,經過在 Mt-Falcon 上配置不一樣的插件,能夠實現對多種組件的自定義監控。另外也會結合 Puppet 識別不一樣用戶的權限、文件的下發。這樣,只要咱們編寫好插件腳本、須要的文件,裝機和權限控制就能夠完成了。監控架構如圖 3。
圖 3 監控架構圖
而 TiDB 有豐富的監控指標,使用流行的 Prometheus + Grafana,一套集羣有 700+ 的 Metric。從官方的架構圖能夠看出,每一個組件會推送本身的 Metric 給 PushGateWay,Prometheus 會直接到 PushGateWay 去抓數據。
因爲咱們須要組件收斂,原生的 TiDB 每一個集羣一套 Prometheus 的方式不利於監控的彙總、分析、配置,而報警已經在 Mt-Falcon 上實現的比較好了,在 AlertManager 上再造一個也沒有必要。所以咱們須要想辦法把監控和報警彙總到 Mt-Falcon 上面,有以下幾種方式:
咱們最終選擇了方案三。該方案的難點是須要把 Prometheus 的數據格式轉化爲 Mt-Falcon 可識別的格式,由於 Prometheus 支持 Counter、Gauge、Histogram、Summary 四種數據類型,而 Mt-Falcon 只支持基本的 Counter 和 Gauge,同時 Mt-Falcon 的計算表達式比較少,所以須要在監控腳本中進行轉換和計算。
TiDB 使用 Ansible 實現自動化部署。迭代快,是 TiDB 的一個特色,有問題快速解決,但也形成 Ansible 工程、TiDB 版本更新過快,咱們對 Ansible 的改動,也只會增長新的代碼,不會改動已有的代碼。所以線上可能同時須要部署、維護多個版本的集羣。若是每一個集羣一個 Ansible 目錄,形成空間的浪費。咱們採用的維護方式是,在中控機中,每一個版本一個 Ansible 目錄,每一個版本中經過不一樣 inventory 文件來維護。這裏須要跟 PingCAP 提出的是,Ansible 只考慮了單集羣部署,大量部署會有些麻煩,像一些依賴的配置文件,都不能根據集羣單獨配置(諮詢官方得知,PingCAP 目前正在基於 Cloud TiDB 打造一站式 HTAP 平臺,會提供批量部署、多租戶等功能,能比較好的解決這個問題)。
隨着線上集羣數量的增長,打造運維平臺提上了日程,而美團對 TiDB 和 MySQL 的使用方式基本相同,所以 MySQL 平臺上具備的大部分組件,TiDB 平臺也須要建設。典型的底層組件和方案:SQL 審覈模塊、DTS、數據備份方案等。自動化運維平臺展現如圖 4。
TiDB 是在線存儲體系中的一環,它同時也須要融入到公司現有的數據流中,所以須要一些工具來作銜接。PingCAP 官方標配了相關的組件。
公司目前 MySQL 和 Hive 結合的比較重,而 TiDB 要代替 MySQL 的部分功能,須要解決 2 個問題:
MySQL to TiDB
Hive to TiDB & TiDB to Hive
圖 5 TiDB to Hive 方案圖
對於初期上線的業務,咱們比較謹慎,基本的原則是:離線業務 -> 非核心業務 -> 核心業務。TiDB 已經發布兩年多,且前期經歷了大量的測試,咱們也深刻了解了其它公司的測試和使用狀況,能夠預期的是 TiDB 上線會比較穩定,但依然遇到了一些小問題。整體來看,在安全性、數據一致性等關鍵點上沒有出現問題。其餘一些性能抖動問題,參數調優的問題,也都獲得了快速妥善的解決。這裏給 PingCAP 的同窗點個大大的贊,問題響應速度很是快,與咱們內部研發的合做也很是融洽。
咱們上線的最大的一個業務,天天有數百 G 的寫入量,前期遇到了較多的問題,咱們重點說說。
業務場景:
以前使用 MySQL 做爲存儲,但 MySQL 到達了容量和性能瓶頸,而業務的容量將來會 10 倍的增加。初期調研測試了 ClickHouse,知足了容量的需求,測試發現運行低頻 SQL 沒有問題,但高頻 SQL 的大併發查詢沒法知足需求,只在 ClickHouse 跑全量的低頻 SQL 又會 overkill,最終選擇使用 TiDB。
測試期間模擬寫入了一天的真實數據,很是穩定,高頻低頻兩種查詢也都知足需求,定向優化後 OLAP 的 SQL 比 MySQL 性能提升四倍。但上線後,陸續發現了一些問題,典型的以下:
TiKV 底層有 2 個 RocksDB 做爲存儲。新寫的數據寫入 L0 層,當 RocksDB 的 L0 層數量達到必定數量,就會發生減速,更高則發生 Stall,用來自我保護。TiKV 的默認配置:
遇到過的,發生 L0 文件過多可能的緣由有 2 個:
圖 6 TiKV 發生 Write Stall 監控展現圖
咱們經過如下措施,解決了 Write Stall 的問題:
如今 TiDB 的 GC 對於每一個 kv-instance 是單線程的,當業務刪除數據的量很是大時,會致使 GC 速度較慢,極可能 GC 的速度跟不上寫入。
目前能夠經過增多 TiKV 個數來解決,長期須要靠 GC 改成多線程執行,官方對此已經實現,即將發佈。
業務上線初期,insert 的響應時間 80 線(Duration 80 By Instance)在 20ms 左右,隨着運行時間增長,發現響應時間逐步增長到 200ms+。期間排查了多種可能緣由,定位在因爲 Region 數量快速上漲,Raftstore 裏面要作的事情變多了,而它又是單線程工做,每一個 Region 按期都要 heartbeat,帶來了性能消耗。tikv-raft propose wait duration 指標持續增加。
解決問題的辦法:
臨時解決
圖 7 insert 響應時間優化先後對比圖
完全解決
DBA Truncate 一張大表後,發現 2 個現象,一是空間回收較慢,二是最終也沒有徹底回收。
因爲 Truncate 使用 delete_files_in_range 接口,發給 TiKV 去刪 SST 文件,這裏只刪除不相交的部分,而以前判斷是否相交的粒度是 Region,所以致使了大量 SST 沒法及時刪除掉。
爲了解決 region 過多的問題,咱們在升級 2.1 版本後,開啓了 region merge 功能,可是 TiDB 的響應時間 80 線(Duration 80 By Instance)依然沒有恢復到當初,保持在 50ms 左右,排查發現 KV 層返回的響應時間還很快,和最初接近,那麼就定位了問題出如今 TiDB 層。研發人員和 PingCAP 定位在產生執行計劃時行爲和 2.0 版本不一致了,目前已經優化。
除了分析查詢量大的離線業務場景,美團還有不少分庫分表的場景,雖然業界有不少分庫分表的方案,解決了單機性能、存儲瓶頸,可是對於業務仍是有些不友好的地方:
所以不少分庫分表的業務,以及即將沒法在單機承載而正在設計分庫分表方案的業務,主動找到了咱們,這和咱們對於 TiDB 的定位是相符的。這些業務的特色是 SQL 語句小而頻繁,對一致性要求高,一般部分數據有時間屬性。在測試及上線後也遇到了一些問題,不過目前基本都有了解決辦法。
業務偶爾報出 privilege check fail。
是因爲業務在 JDBC 設置了 QueryTimeout,SQL 運行超過這個時間,會發行一個 「kill query」 命令,而 TiDB 執行這個命令須要 Super 權限,業務是沒有權限的。
其實 kill 本身的查詢,並不須要額外的權限,目前已經解決了這個問題,再也不須要 Super 權限,已在 2.0.5 上線。
TiDB 的物理優化階段須要依靠統計信息。在 2.0 版本統計信息的收集從手動執行,優化爲在達到必定條件時能夠自動觸發:
可是在沒有達到這些條件以前統計信息是不許的,這樣就會致使物理優化出現誤差,在測試階段(2.0 版本)就出現了這樣一個案例:業務數據是有時間屬性的,業務的查詢有 2 個條件,好比:時間+商家 ID,但天天上午統計信息可能不許,當天的數據已經有了,但統計信息認爲沒有。這時優化器就會建議使用時間列的索引,但實際上商家 ID 列的索引更優化。這個問題能夠經過增長 Hint 解決。
在 2.1 版本對統計信息和執行計劃的計算作了大量的優化,也穩定了基於 Query Feedback 更新統計信息,也用於更新直方圖和 Count-Min Sketch,很是期待 2.1 的 GA。
通過前期的測試、各方的溝通協調,以及近半年對 TiDB 的使用,咱們看好 TiDB 的發展,也對將來基於 TiDB 的合做充滿信心。
接下來,咱們會加速推動 TiDB 在更多業務系統中的使用,同時也將 TiDB 歸入了美團新一代數據庫的戰略選型中。當前,咱們已經全職投入了 3 位 DBA 同窗和多位存儲計算專家,從底層的存儲,中間層的計算,業務層的接入,到存儲方案的選型和佈道,進行全方位和更深刻的合做。
長期來看,結合美團不斷增加的業務規模,咱們將與 PingCAP 官方合做打造更強大的生態體系:
圖 8 TiDB HTAP Platform 總體架構圖
後續的物理備份方案,跨機房多寫等也是咱們接下來逐步推動的場景,總之咱們堅信將來 TiDB 在美團的使用場景會愈來愈多,發展也會愈來愈好。
TiDB 在業務層面、技術合做層面都已經在美團揚帆起航,美團點評將攜手 PingCAP 開啓新一代數據庫深度實踐、探索之旅。後續,還有美團點評架構存儲團隊針對 TiDB 源碼研究和改進的系列文章,敬請期待!
做者介紹趙應鋼,美團點評研究員
李坤,美團點評數據庫專家
樸昌俊,美團點評數據庫專家