TiDB 在小米的應用實踐

作者:張良,小米 DBA 負責人;潘友飛,小米 DBA;王必文,小米開發工程師。

一、應用場景介紹

MIUI 是小米公司旗下基於 Android 系統深度優化、定製、開發的第三方手機操作系統,也是小米的第一個產品。MIUI 在 Android 系統基礎上,針對中國用戶進行了深度定製,在此之上孕育出了一系列的應用,比如主題商店、小米音樂、應用商店、小米閱讀等。

圖 1  MIUI Android 系統界面圖

<center>圖 1  MIUI Android 系統界面圖</center>

目前 TiDB 主要應用在:

  • 小米手機桌面負一屏的快遞業務
  • 商業廣告交易平臺素材抽審平臺

這兩個業務場景每天讀寫量均達到上億級,上線之後,整個服務穩定運行;接下來我們計劃逐步上線更多的業務場景,小米閱讀目前正在積極的針對訂單系統做遷移測試。

二、TiDB 特點

TiDB 結合了傳統的 RDBMS 和 NoSQL 的最佳特性,兼容 MySQL 協議,支持無限的水平擴展,具備強一致性和高可用性。

具有如下的特性:

  • 高度兼容 MySQL,大多數情況下無需修改代碼即可從 MySQL 輕鬆遷移至 TiDB,即使已經分庫分表的 MySQL 集羣亦可通過 TiDB 提供的遷移工具進行實時遷移。

  • 水平彈性擴展,通過簡單地增加新節點即可實現 TiDB 的水平擴展,按需擴展吞吐或存儲,輕鬆應對高併發、海量數據場景。

  • 分佈式事務,TiDB 100% 支持標準的 ACID 事務。

  • 真正金融級高可用,相比於傳統主從(M-S)複製方案,基於 Raft 的多數派選舉協議可以提供金融級的 100% 數據強一致性保證,且在不丟失大多數副本的前提下,可以實現故障的自動恢復(auto-failover),無需人工介入。

TiDB 的架構及原理在 官網 裏有詳細介紹,這裏不再贅述。

圖 2  TiDB 基礎架構圖

<center>圖 2  TiDB 基礎架構圖</center>

三、背景

跟絕大數互聯網公司一樣,小米關係型存儲數據庫首選 MySQL,單機 2.6T 磁盤。由於小米手機銷量的快速上升和 MIUI 負一屏用戶量的快速增加,導致負一屏快遞業務數據的數據量增長非常快,**每天的讀寫量級均分別達到上億級別,數據快速增長導致單機出現瓶頸,比如性能明顯下降、可用存儲空間不斷降低、大表 DDL 無法執行等,不得不面臨數據庫擴展的問題。**比如,我們有一個業務場景(智能終端),需要定時從幾千萬級的智能終端高頻的向數據庫寫入各種監控及採集數據,MySQL 基於 Binlog 的單線程複製模式,很容易造成從庫延遲,並且堆積越來越嚴重。

**對於 MySQL 來講,最直接的方案就是採用分庫分表的水平擴展方式,綜合來看並不是最優的方案,比如對於業務來講,對業務代碼的侵入性較大;對於 DBA 來講提升管理成本,後續需要不斷的拆分擴容,即使有中間件也有一定的侷限性。**同樣是上面的智能終端業務場景,從業務需求看,需要從多個業務維度進行查詢,並且業務維度可能隨時進行擴展,分表的方案基本不能滿足業務的需求。

瞭解到 TiDB 特點之後,DBA 與業務開發溝通確認當前 MySQL 的使用方式,並與 TiDB 的兼容性做了詳細對比,經過業務壓測之後,根據壓測的結果,決定嘗試將數據存儲從 MySQL 遷移到 TiDB。經過幾個月的線上考驗,TiDB 的表現達到預期。

四、兼容性對比

TiDB 支持包括跨行事務、JOIN、子查詢在內的絕大多數 MySQL 的語法,可以直接使用 MySQL 客戶端連接;對於已用 MySQL 的業務來講,基本可以無縫切換到 TiDB。

二者簡單對比如下幾方面:

  • 功能支持

    • TiDB 尚不支持如下幾項:
      • 增加、刪除主鍵
      • 非 UTF8 字符集
      • 視圖(即將支持)、存儲過程、觸發器、部分內置函數
      • Event
      • 全文索引、空間索引
  • 默認設置

    • 字符集、排序規則、sql_mode、lower_case_table_names 幾項默認值不同。
  • 事務

    • TiDB 使用樂觀事務模型,提交後注意檢查返回值。
    • TiDB 限制單個事務大小,保持事務儘可能的小。
  • TiDB 支持絕大多數的 Online DDL。

  • 另,一些 MySQL 語法在 TiDB 中可以解析通過,不會產生任何作用,例如: create table 語句中 engine、partition 選項都是在解析後忽略。

  • 詳細信息可以訪問官網:https://pingcap.com/docs-cn/sql/mysql-compatibility/ 。

五、壓測

5.1 目的

通過壓測 TiDB 瞭解一下其 OLTP 性能,看是否滿足業務要求。

5.2 機器配置

組件實例數量CPU 型號內存磁盤版本操作系統
TiDB3Intel(R) Xeon(R) CPU E5-2620 v3 @ 2.40GHz128GSSD Raid 52.0.3CentOS Linux release 7.3.1611
PD3Intel(R) Xeon(R) CPU E5-2620 v3 @ 2.40GHz128GSSD Raid 52.0.3CentOS Linux release 7.3.1611
TiKV4Intel(R) Xeon(R) CPU E5-2620 v3 @ 2.40GHz128GSSD Raid 52.0.3CentOS Linux release 7.3.1611

5.3 壓測內容以及結果

5.3.1 標準 Select 壓測

ThreadsQPSLatency (avg / .95 / max)
812650.810.63 / 0.90 / 15.62
1621956.210.73 / 1.50 / 15.71
3231534.81.01 / 2.61 / 25.16
64382171.67 / 5.37 / 49.80
12839943.053.20 / 8.43 / 58.60
25640920.646.25 / 13.70 / 95.13

圖 3  標準 Select 壓測圖

<center>圖 3  標準 Select 壓測圖</center>

5.3.2 標準 OLTP 壓測

ThreadsTPSQPSLatency (avg / .95 / max)
8428.98578.0918.65 / 21.89 / 116.06
16731.6714633.3521.86 / 25.28 / 120.59
321006.4320128.5931.79 / 38.25 / 334.92
641155.4423108.955.38 / 71.83 / 367.53
1281121.5522431114.12 / 161.51 / 459.03
256941.2618825.1271.94 / 369.77 / 572.88

圖 4  標準 OLTP  壓測圖

<center>圖 4  標準 OLTP  壓測圖</center>

5.3.3 標準 Insert 壓測

ThreadsQPSLatency (avg / .95 / max)
83625.752.20 / 2.71 / 337.94
166527.242.45 / 3.55 / 160.84
3210307.663.10 / 4.91 / 332.41
6413662.834.68 / 7.84 / 467.56
12815100.448.47 / 16.41 / 278.23
25617286.8614.81 / 25.74 / 3146.52

圖 5  標準 Insert 壓測圖

<center>圖 5  標準 Insert 壓測圖</center>

通過壓測發現 TiDB 穩定性上與預期稍有差別,不過壓測的 Load 會明顯高於生產中的業務 Load,參考低 Threads 時 TiDB 的表現,基本可以滿足業務對 DB 的性能要求,決定灰度一部分 MySQL 從庫讀流量體驗一下實際效果。

六、遷移過程

整個遷移分爲 2 大塊:數據遷移、流量遷移。

6.1 數據遷移

數據遷移分爲增量數據、存量數據兩部分。

  • 對於存量數據,可以使用邏輯備份、導入的方式,除了傳統的邏輯導入外,官方還提供一款物理導入的工具 TiDB Lightning。

  • 對於增量備份可以使用 TiDB 提供的 Syncer (新版已經更名爲 DM - Data Migration)來保證數據同步。

Syncer 結構如圖 6,主要依靠各種 Rule 來實現不同的過濾、合併效果,一個同步源對應一個 Syncer 進程,同步 Sharding 數據時則要多個 Syncer 進程。

圖 6  Syncer 結構圖

<center>圖 6  Syncer 結構圖</center>

使用 Syncer 需要注意:

  • 做好同步前檢查,包含 server-id、log_bin、binlog_format 是否爲 ROW、binlog_row_image 是否爲 FULL、同步相關用戶權限、Binlog 信息等。

  • 使用嚴格數據檢查模式,數據不合法則會停止。數據遷移之前最好針對數據、表結構做檢查。

  • 做好監控,TiDB 提供現成的監控方案。

  • 對於已經分片的表同步到同一個 TiDB 集羣,要做好預先檢查。確認同步場景是否可以用 route-rules 表達,檢查分表的唯一鍵、主鍵在數據合併後是否衝突等。

6.2 流量遷移

流量切換到 TiDB 分爲兩部分:讀、寫流量遷移。每次切換保證灰度過程,觀察週期爲 1~2 周,做好回滾措施。

  • 讀流量切換到 TiDB,這個過程中回滾比較簡單,灰度無問題,則全量切換。

  • 再將寫入切換到 TiDB,需要考慮好數據回滾方案或者採用雙寫的方式(需要斷掉 Syncer)。

七、集羣狀況

7.1 配置

集羣配置採用官方推薦的 7 節點配置,3 個 TiDB 節點,3 個 PD 節點,4 個 TiKV 節點,其中每個 TiDB 與 PD 爲一組,共用一臺物理機。後續隨着業務增長或者新業務接入,再按需添加 TiKV 節點。

7.2 監控

監控採用了 TiDB 的提供的監控方案,並且也接入了公司開源的 Falcon,目前整個集羣運行比較穩定,監控如圖 7。      

圖 7  監控圖

<center>圖 7  監控圖</center>

八、遇到的問題、原因及解決辦法

問題原因及解決辦法
在一個 DDL 裏不能對多個列或者多個索引做操作。ADD/DROP INDEX/COLUMN 操作目前不支持同時創建或刪除多個索引或列,需要拆分單獨執行,官方表示 3.0 版本有計劃改進。
部分操作符查詢優化器支持不夠好,比如 or 操作符會使用 TableScan,改寫成 union all 可避免。官方表示目前使用 or 操作符確實在執行計劃上有可能不準確,已經在改進計劃中,後續 3.0 版本會有優化。
重啓一個 PD 節點的時候,業務能捕捉到 PD 不可用的異常,會報 PD server timeout 。因爲重啓的是 Leader 節點,所以重啓之前需要手動切換 Leader,然後進行重啓。官方建議這裏可以通過重啓前做 Leader 遷移來減緩,另外後續 TiDB 也會對網絡通訊相關參數進行梳理和優化。
建表語句執行速度相比 MySQL 較慢多臺 TiDB 的時候,Owner 和接收 create table 語句的 TiDB Server 不在一臺 Server 上時,可能比 MySQL 慢一些,每次操作耗時在 0.5s 左右,官方表示會在後續的版本中不斷完善。
pd-ctl 命令行參數解析嚴格,多一個空格會提示語法錯誤。官方表示低版本中可能會有這個問題,在 2.0.8 及以上版本已經改進。
tikv-ctl 命令手動 compact region 失敗。在低版本中通常是因爲 tikv-ctl 與集羣版本不一致導致的,需要更換版本一致的 tikv-ctl,官方表示在 2.1 中已經修復。
大表建索引時對業務有影響官方建議在業務低峯期操作,在 2.1 版本中已經增加了操作優先級以及併發讀的控制,情況有改善。
存儲空間放大問題該問題屬於 RocksDB,RocksDB 的空間放大係數最理想的值爲 1.111,官方建議在某些場景下通過 TiKV 開啓 RocksDB 的 dynamic-level-bytes 以減少空間放大。

九、後續和展望

目前 TiDB 在小米主要提供 OLTP 服務,小米手機負一屏快遞業務爲使用 TiDB 做了一個良好的開端,而後商業廣告也有接入,2 個業務均已上線數月,TiDB 的穩定性經受住了考驗,帶來了很棒的體驗,對於後續大體的規劃如下:

  • MIUI 生態業務中存在大量的類似場景的業務,後續將會與業務開發積極溝通,從 MySQL 遷移到 TiDB。

  • 針對某些業務場景,以資源合理利用爲目標,推出歸檔集羣,利用 Syncer 實現數據歸檔的功能。

  • 數據分析,結合 TiDB 提供的工具,將支持離線、實時數據分析支持。

  • 將 TiDB 的監控融合到小米公司開源的監控系統 Falcon 中。

十、致謝

非常感謝 TiDB 官方在遷移及業務上線期間給予我們的支持,爲每一個 TiDB 人專業的精神、及時負責的響應點贊。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章