作者:張良,小米 DBA 負責人;潘友飛,小米 DBA;王必文,小米開發工程師。
一、應用場景介紹
MIUI 是小米公司旗下基於 Android 系統深度優化、定製、開發的第三方手機作業系統,也是小米的第一個產品。MIUI 在 Android 系統基礎上,針對中國使用者進行了深度定製,在此之上孕育出了一系列的應用,比如主題商店、小米音樂、應用商店、小米閱讀等。
目前 TiDB 主要應用在:
- 小米手機桌面負一屏的快遞業務
- 商業廣告交易平臺素材抽審平臺
這兩個業務場景每天讀寫量均達到上億級,上線之後,整個服務穩定執行;接下來我們計劃逐步上線更多的業務場景,小米閱讀目前正在積極的針對訂單系統做遷移測試。
二、TiDB 特點
TiDB 結合了傳統的 RDBMS 和 NoSQL 的最佳特性,相容 MySQL 協議,支援無限的水平擴充套件,具備強一致性和高可用性。
具有如下的特性:
-
高度相容 MySQL,大多數情況下無需修改程式碼即可從 MySQL 輕鬆遷移至 TiDB,即使已經分庫分表的 MySQL 叢集亦可通過 TiDB 提供的遷移工具進行實時遷移。
-
水平彈性擴充套件,通過簡單地增加新節點即可實現 TiDB 的水平擴充套件,按需擴充套件吞吐或儲存,輕鬆應對高併發、海量資料場景。
-
分散式事務,TiDB 100% 支援標準的 ACID 事務。
-
真正金融級高可用,相比於傳統主從(M-S)複製方案,基於 Raft 的多數派選舉協議可以提供金融級的 100% 資料強一致性保證,且在不丟失大多數副本的前提下,可以實現故障的自動恢復(auto-failover),無需人工介入。
TiDB 的架構及原理在 官網 裡有詳細介紹,這裡不再贅述。
三、背景
跟絕大數網際網路公司一樣,小米關係型儲存資料庫首選 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
- 全文索引、空間索引
- TiDB 尚不支援如下幾項:
-
預設設定
- 字符集、排序規則、sql_mode、lower_case_table_names 幾項預設值不同。
-
事務
- TiDB 使用樂觀事務模型,提交後注意檢查返回值。
- TiDB 限制單個事務大小,保持事務儘可能的小。
-
TiDB 支援絕大多數的 Online DDL。
-
另,一些 MySQL 語法在 TiDB 中可以解析通過,不會產生任何作用,例如: create table 語句中 engine、partition 選項都是在解析後忽略。
-
詳細資訊可以訪問官網:pingcap.com/docs-cn/sql… 。
五、壓測
5.1 目的
通過壓測 TiDB 瞭解一下其 OLTP 效能,看是否滿足業務要求。
5.2 機器配置
元件 | 例項數量 | CPU 型號 | 記憶體 | 磁碟 | 版本 | 作業系統 |
---|---|---|---|---|---|---|
TiDB | 3 | Intel(R) Xeon(R) CPU E5-2620 v3 @ 2.40GHz | 128G | SSD Raid 5 | 2.0.3 | CentOS Linux release 7.3.1611 |
PD | 3 | Intel(R) Xeon(R) CPU E5-2620 v3 @ 2.40GHz | 128G | SSD Raid 5 | 2.0.3 | CentOS Linux release 7.3.1611 |
TiKV | 4 | Intel(R) Xeon(R) CPU E5-2620 v3 @ 2.40GHz | 128G | SSD Raid 5 | 2.0.3 | CentOS Linux release 7.3.1611 |
5.3 壓測內容以及結果
5.3.1 標準 Select 壓測
Threads | QPS | Latency (avg / .95 / max) |
---|---|---|
8 | 12650.81 | 0.63 / 0.90 / 15.62 |
16 | 21956.21 | 0.73 / 1.50 / 15.71 |
32 | 31534.8 | 1.01 / 2.61 / 25.16 |
64 | 38217 | 1.67 / 5.37 / 49.80 |
128 | 39943.05 | 3.20 / 8.43 / 58.60 |
256 | 40920.64 | 6.25 / 13.70 / 95.13 |
5.3.2 標準 OLTP 壓測
Threads | TPS | QPS | Latency (avg / .95 / max) |
---|---|---|---|
8 | 428.9 | 8578.09 | 18.65 / 21.89 / 116.06 |
16 | 731.67 | 14633.35 | 21.86 / 25.28 / 120.59 |
32 | 1006.43 | 20128.59 | 31.79 / 38.25 / 334.92 |
64 | 1155.44 | 23108.9 | 55.38 / 71.83 / 367.53 |
128 | 1121.55 | 22431 | 114.12 / 161.51 / 459.03 |
256 | 941.26 | 18825.1 | 271.94 / 369.77 / 572.88 |
5.3.3 標準 Insert 壓測
Threads | QPS | Latency (avg / .95 / max) |
---|---|---|
8 | 3625.75 | 2.20 / 2.71 / 337.94 |
16 | 6527.24 | 2.45 / 3.55 / 160.84 |
32 | 10307.66 | 3.10 / 4.91 / 332.41 |
64 | 13662.83 | 4.68 / 7.84 / 467.56 |
128 | 15100.44 | 8.47 / 16.41 / 278.23 |
256 | 17286.86 | 14.81 / 25.74 / 3146.52 |
通過壓測發現 TiDB 穩定性上與預期稍有差別,不過壓測的 Load 會明顯高於生產中的業務 Load,參考低 Threads 時 TiDB 的表現,基本可以滿足業務對 DB 的效能要求,決定灰度一部分 MySQL 從庫讀流量體驗一下實際效果。
六、遷移過程
整個遷移分為 2 大塊:資料遷移、流量遷移。
6.1 資料遷移
資料遷移分為增量資料、存量資料兩部分。
-
對於存量資料,可以使用邏輯備份、匯入的方式,除了傳統的邏輯匯入外,官方還提供一款物理匯入的工具 TiDB Lightning。
-
對於增量備份可以使用 TiDB 提供的 Syncer (新版已經更名為 DM - Data Migration)來保證資料同步。
Syncer 結構如圖 6,主要依靠各種 Rule 來實現不同的過濾、合併效果,一個同步源對應一個 Syncer 程式,同步 Sharding 資料時則要多個 Syncer 程式。
使用 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。
八、遇到的問題、原因及解決辦法
問題 | 原因及解決辦法 |
---|---|
在一個 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 人專業的精神、及時負責的響應點贊。
更多 TiDB 使用者實踐: www.pingcap.com/cases-cn/