輕鬆應對海量數據,TiDB 在車好多的實踐

車好多集團系國內領軍的汽車消費服務一站式平臺,旗下擁有瓜子二手車、毛豆新車、車好多車後三大核心業務。

業務挑戰

車好多集團關注 TiDB 始於 2018 年初,像大多數公司同樣,公司發展初期爲了快速適配業務開發,大部分數據都存儲在 MySQL 中。但隨着業務快速發展,存量數據愈來愈多,咱們在 MySQL 面臨着以下痛點:git

業務拆分複雜

公司業務發展快,單實例的 QPS 和數據存儲會超出預期,這時候須要對業務線實例進行拆分。 每次業務線拆分須要從數據產生端 (APP) 到數據流轉端 (CDC) 最後到數據倉庫(DW)一塊兒配合調整; 若是涉及到多方同時使用相同庫表,還須要多個應用的負責人協調; 同時一些腳本類程序可能在遷移時被忽略,部分業務數據會受到影響。 每次業務線拆分的週期大概在 2-4 周,耗費人力。github

分庫分表侵入業務

業務發展到必定程度以後,一些數據表的數據量超過千萬級別,常規作法是分庫分表。這裏有幾個可能遇到的問題:sql

  1. 分佈式事務很差處理;
  2. 二級索引沒法建立;
  3. 分庫分表的設計是否支持二次擴容;
  4. 跨庫 join 沒法操做;
  5. 結果集的排序合併難度大。

大表結構修改困難

咱們公司的業務模式變化快,爲了快速響應業務,表結構常常調整。在對一些數據在百萬級別以上的大表作 DDL 的時候,會藉助第三方工具,如 pt-osc。修改過程當中須要先複製一份臨時表,這種方式修改的時間較長,對存儲空間、IO、業務有必定的影響。數據庫

爲何選擇 TiDB

面對以上痛點,咱們開始考慮對數據庫的架構進行升級改造,咱們根據業務方的訴求,將一些常見數據庫技術方案,作了一些對比:後端

數據庫類型 優勢 缺點
MySQL 分庫分表 1. 根據 ID 查詢的層面基本上無多餘工做量。2. 短時間技術實現成本低。 1. 庫表數量線性增加,運維壓力大,按百萬級別數據量分表計算,每一年增加表的數量至少 30 張,且單表容量仍然較大。2. 分庫分表在代碼層實現需改動代碼。3. 如引入分庫分表中間件,則須要投入專門人員。
MongoDB 1. 技術比較成熟。2. 大數據量下,可經過分片進行擴展。 1. 業務須要所有重構,短時間內沒法實現。2. 文檔型數據庫,須要業務來控制數據較驗。
ElasticSearch 搜索功能強大(多二級索引)。 1. ElasticSearch 寫入性能稍差,遇到大量寫入操做時候,可能延遲。2. 無 schema 管理,長期維護成本較高。
HBase 1. 技術比較成熟。2. 普通根據 rowkey 查詢,無工做量。3. 可橫向擴展。 1. 沒法經過 rowkey 直接獲取數據的場景,都須要額外開發,接口通用性較低。2. 不支持二級索引。3. 協議與現有程序不一致,須要從新開發相關讀寫程序。
HBase+phoenix 1. 底層 kv 存儲複用 HBase,存儲引擎的穩定性強。2. 可橫向擴展。 1. SQL 語法小衆。好比只有 upsert,沒有單獨的 insert 和 update。2. Phoenix 的事務功能依賴開源的 percolator 實現,可信度略低。事務仍是一個比較嚴謹的技術,Phoenix 社區和 Google 也沒能查到太多事務相關的信息。
HBase+ES 1. HBase 做爲 OLTP 的記錄存儲,ES 做爲 HBase 的二級索引。2. 兼顧了 HBase 的優勢(快速的 kv 能力,海量存儲能力,可變字段能力)和 ES 的優勢(強大的二級索引能力)。 1. 不支持事務。2. HBase 和 ES 兩端的數據一致保障難度高。
TiDB 1. 徹底兼容 MySQL 協議,業務層幾乎不須要改動。2. 分佈式存儲,節點無限擴容,高可用。3. 完美替代 MySQL 分庫分表。4. 大表 DDL不影響業務。5. 支持事務,隔離級別爲'快照級別隔離' [見附錄]。6. 可兼容 CDC 鏈路。 1. 資源需求較高。2. 無觸發器、存儲過程、某些語法不兼容。

TiDB 具備水平彈性擴展,高度兼容 MySQL,在線 DDL,一致性的分佈式事務等特性,符合車好多部分數據量大,業務變動頻繁,數據保存週期長等場景。 咱們通過 TiDB 的內部測試後,確承認以知足現有業務需求。咱們最終選擇了 TiDB 作爲這類需求的數據存儲。架構

初次探索

業務場景

綜合 TiDB 的特性和車好多集團的業務場景,咱們比較適合引入 TiDB 的場景有: 工單分配 / 流轉、電話銷售系統、業務中臺-帳務系統等業務。首先這些業務積累的數據量比較大,在此基礎上一部分業務會有頻繁增長字段的需求,也有一部分業務會使用到事務,這些場景都很是適用於 TiDB。運維

面臨問題

與目標業務方進行了一輪溝通以後,業務方給咱們介紹了一些數據的現狀和業務上的需求:分佈式

  1. 上線以前存量數據接近 3 億條,每日新增 170 萬條,單月約 5000萬增量。MySQL 中熱數據即便只存儲最新 2 個月,也面臨單表數據破億的場景。
  2. 因爲車好多集團的業務特殊性,車的週轉週期比較長,一些冷數據可能會轉變爲熱數據,歸檔邏輯與業務需求強綁定,一些所謂的"冷數據"可能會有更新操做。
  3. 這些數據針對線上用戶提供服務,對數據庫的實時性讀寫性能要求較高。
  4. 同一份數據有多方在使用,針對不一樣需求查詢重點不一樣,業務查詢條件複雜。
  5. 當數據發生變動時,有相應的業務邏輯處理,須要配置 CDC 數據鏈路監控數據變化。

接入要求

因爲 TiDB 的資源要求較高,咱們對接入的業務提出瞭如下要求:工具

  1. 存量數據在千萬以上,將來 MySQL 的單機存儲和性能會成爲瓶頸。
  2. 業務涉及到事務 / 分庫分表 / 常常在線增長字段等特殊場景。
  3. 數據價值較高,提供針對用戶的在線服務。

接入過程

面對一個新的數據庫,大部分核心業務仍是擔憂數據庫的穩定性和數據的可靠性,不敢直接嘗試。咱們優先選擇一些數據量比較大而且實時性需求相對較低的場景進行試點,可是業務方仍然擔憂服務的穩定性和性能等諸多問題。咱們屢次與業務方溝通,制定和實施了分段落地的計劃:性能

第一步,將 TiDB 做爲 MySQL 的從庫使用,經過 DM 工具同步數據。業務方使用這套 TiDB 集羣做爲從庫,驗證數據的準確性 / 服務的穩定性 / 查詢的性能等是否符合業務需求,測試正常後灰度小比例的線上流量到該集羣上進行查詢,確認數據正常後逐步放大灰度的比例直至全流量。這一步充分的驗證了 TiDB 的數據同步和數據查詢,業務方對 TiDB 有了初步的認知,也逐漸積累了對 TiDB 和維護人員的信任。

第二步,業務方改造程序,對 MySQL 和 TiDB 進行雙寫,斷開 DM 同步。業務方將 TiDB 做爲主庫直接讀寫,但仍然保留了 MySQL 中的數據寫入,將 MySQL 做爲 TiDB 發生異常以後的降級方案。這個階段持續了 2 個季度左右。在這期間讀寫 TiDB 的程序運行正常,天天的數據校驗保持一致。

第三步,下線雙寫,僅保留直接操做 TiDB 的部分。經過第一步和第二步的驗證和積累的信任,TiDB 正式做爲獨立的數據庫投入到生產環境使用.

上圖: 上線一段時間後最近 7 天的查詢 duration

新車業務接入 TiDB 以後,業務上將原先只支持近期三個月的查詢擴展到支持全量查詢,這部分數據對用戶行爲精細化管理帶來了必定的幫助。隨着業務發展,存量數據從千萬級別逐步上升到億級別,到如今將近十億,在 1000 QPS 下查詢的 99.9th 延遲低於 128 毫秒,用戶體驗良好。通過了整個接入過程後,新車計劃將存在數據庫瓶頸的業務逐步遷移到 TiDB 中來。通過一年的發展,目前車好多的二手車收售車管理、臺帳、支付網關、用戶社羣等業務逐步嘗試 TiDB,而且在試用以後慢慢從 MySQL 中遷移更多的業務模塊到 TiDB 中。

遇到的問題

在推動 TiDB 的過程當中,咱們也遇到了各類問題,除了一些常見的慢 SQL、熱點讀寫、DM 同步數據異常等問題外,咱們在車好多的業務背景下,遇到了一些相對特殊的問題:

版本的選擇

TiDB 是一項比較新的技術,社區的版本在不斷的迭代更新,有不少 bugfix 和新特性在持續集成到 TiDB 中。咱們從開始調研到如今,經歷了 2.X 到 4.0.X 的多個版本。咱們選擇了一些比較關心的內容進行跟進,如: Lightning 導入數據 bug 修復、悲觀鎖、TiFlash、TiUP 管理工具、TiCDC 等等。有一次咱們從 2.1.x 的版本升級到 3.0.x 版本,未注意到 sql mode 變動,剛好業務上正好有 SQL 被 ONLY_FULL_GROUP_BY 規則影響,緊急修改 SQL 後從新上線。咱們增量的業務選擇版本的時候,一般會選擇一些已經平穩運行一段時間的版本,上線以後,若是沒有嚴重的 bug 或者急需的特性,一般再也不進行升級,以保障業務不由於數據庫的升級受到影響。

SQL 執行計劃 & SQL binding

使用 TiDB 一段時間後,某個業務線單表存量數據數據已經超過 5 億,QPS 也超過了 200。某天業務方反饋,線上系統發生大量查詢超時,結果無返回,TiDB-admin 協助排查問題。觀察監控數據,發現 CPU 被打滿,IO 上升明顯。繼續觀察慢 SQL 日誌,發如今 analyze 收集統計信息的末尾階段,有一類 SQL 索引的選擇發生了改變,每次掃描的 key 從正常索引下的百級別到異常索引下的百萬到千萬的級別。爲了快速恢復業務,結合 TiDB 承載的業務的特性,將影響優化器選擇的未使用到的索引刪除,同時將自動 analyze 操做設置爲業務低谷時間段執行。

咱們以這個案例諮詢了 PingCAP 官方,由於 TiDB 使用的是基於成本的優化器(CBO),在統計信息變動的時候,有可能選擇與以前不一致的索引,建議經過 SQL binding 解決此類問題。不久時間後,另外一條業務線的 SQL 由於相似問題,使用了 SQL binding 進行了綁定,在程序使用到 prepare statement 的時候遇到了另外一個 bug [見附錄] ,上報社區後已經加入到修復計劃中。

資源隔離

隨着 TiDB 技術在車好多集團的推動,和第一批吃了螃蟹的業務方的推薦,愈來愈多的業務線但願嘗試 TiDB。受機房設備採購週期的限制,咱們很難短時間內湊出多套獨立的 TiDB 集羣,服務忽然上升的需求量。結合這些新增需求的業務特性: 大部分是增量比較高可是沒有存量數據的業務,前期對資源的需求並非很是高,因而咱們 TiDB-admin 開始調研在同一組機器中混和部署多套集羣,而且進行進程之間的資源隔離。TiDB 分爲多個組件,PD 對資源的需求不高,暫時忽略;TiKV 能夠經過軟件層配置最大的 CPU 和內存,IO 的隔離咱們選擇在同一臺機器部署多塊 SSD 進行物理隔離,也比較好控制;TiDB 雖然能夠經過軟件層配置最大的 CPU 和內存,可是沒法阻止瞬時的內存暴增,調研後發如今經過 TiUP 部署的時候,能夠設置 systemd 的參數 memory_limit,經過系統的 cgroup 限制最大使用內存,這也催生了咱們經過 K8s+Docker 來全面控制資源的想法。咱們在混合部署以後,提供給了業務方進行驗證,確承認以隔離某一方的異常 SQL 對通物理機下其餘TiDB 集羣的影響,新業務逐步用上了 TiDB。

TiDB 將來工做

  1. 嘗試 TiDB 在車好多雲上的實踐:隨着雲原生技術的不斷髮展,TiDB 做爲一款爲雲原生設計的分佈式數據庫,能夠經過 TiDB Operator 在雲上工具化部署,自動化處理資源分配,提高 TiDB 的資源利用率,同時也下降了 TiDB 的維護成本。
  2. 探索 TiKV 覆蓋到的場景:廣告投放的業務對服務的訪問延遲時間很是敏感,若是延遲太高用戶的體檢會大大降低,伴隨車好多五年來的數據積累,咱們用做廣告投放所積累的數據量也很是大,所以咱們將 TiKV 做爲可持久化的低延遲的 KV 服務,提供給廣告投放的業務來使用,技術方案已經通過了線上流量的考驗,因爲汽車的交易週期較長,該項目仍然處於業務初期階段。在將來咱們將探索更多的TiKV的使用場景,提供可持久化的、低延遲的KV服務。
  3. CDC 的應用:車好多的數據流服務在 MySQL 數據庫上是基於 Binlog 進行建設的,切換到 TiDB 後,使用過 Pump+drainer 的方式同步 binlog。在 TiDB 4.0 版本後加入了 CDC 服務,能夠更方便的部署和集成多數據格式的輸出,將來咱們會逐步接入 CDC 的數據到現有系統中。
  4. 接入車好多數據庫運維平臺:伴隨車好多的成長,咱們的 DBA 團隊開發並維護了一套管理 MySQL 的系統,管理員和開發的同事均可以很方便的在此係統上完成平常工做,爲了維護入口的統一,TiDB 將逐步接入該系統,便於 TiDB 運維的自動化。
  5. 提供更方便的接入方式:咱們現有的幾條業務線的接入,大可能是先經過 DM 同步數據,而後與業務方一塊兒配合作一次遷移。咱們但願將來能夠更方便地服務業務方,經過一個 SQL proxy 的代理層輔助,業務方只須要鏈接到 proxy 層,後端是 MySQL 或者 TiDB 對於業務方不須要關心,真正作到對業務 0 侵入。

附錄:

  1. TiDB 事務隔離級別 :

https://docs.pingcap.com/zh/t...

  1. prepare statement 方式 + limit 致使 SQL binding 失敗:

https://github.com/pingcap/ti...

相關文章
相關標籤/搜索