作者:孫玄,轉轉公司首席架構師;陳東,轉轉公司資深工程師;冀浩東,轉轉公司資深 DBA。
公司及業務架構介紹
轉轉二手交易網 —— 把家裡不用的東西賣了變成錢,一個幫你賺錢的網站。由騰訊與 58 集團共同投資。為海量使用者提供一個有擔保、便捷的二手交易平臺。轉轉是 2015 年 11 月 12 日正式推出的 APP,遵循“使用者第一”的核心價值觀,以“讓資源重新配置,讓人與人更信任”為企業願景,提倡真實個人交易。
轉轉二手交易涵蓋手機、3C 數碼、母嬰用品等三十餘個品類。在系統設計上,轉轉整體架構採用微服務架構,首先按照業務領域模型垂直拆分成使用者、商品、交易、搜尋、推薦微服務。對每一個功能單元(商品等),繼續進行水平拆分,分為商品閘道器層、商品業務邏輯層、商品資料訪問層、商品 DB / Cache,如下圖所示:
專案背景
- 面臨的問題
轉轉後端業務現階段主要使用 MySQL 資料庫儲存資料,還有少部分業務使用 MongoDB。雖然目前情況下使用這兩種儲存基本可以滿足我們的需求,但隨著業務的增長,公司的資料規模逐漸變大,為了應對大資料量下業務服務訪問的效能問題,MySQL 資料庫常用的分庫、分表方案會隨著 MySQL Sharding(分片)的增多,業務訪問資料庫邏輯會越來越複雜。而且對於某些有多維度查詢需求的表,我們總需要引入額外的儲存或犧牲效能來滿足我們的查詢需求,這樣會使業務邏輯越來越重,不利於產品的快速迭代。
從資料庫運維角度講,大資料量的情況下,MySQL 資料庫在每次 DDL 都會對運維人員造成很大的工作量,當節點故障後,由於資料量較大,恢復時間較長。但這種 M - S 架構只能通過主從切換並且需要額外的高可用元件來保障高可用,同時在切換過程由於需要確定主庫狀態、新主庫選舉、新路由下發等原因,還是會存在短暫的業務訪問中斷的情況。 綜上所述,我們面臨的主要問題可歸納為:
-
資料量大,如何快速水平擴充套件儲存;
-
大資料量下,如何快速 DDL;
-
分庫分表造成業務邏輯非常複雜;
-
常規 MySQL 主從故障轉移會導致業務訪問短暫不可用。
- 為什麼選擇 TiDB
針對上章提到的問題,轉轉基礎架構部和 DBA 團隊考慮轉轉業務資料增速,定位簡化業務團隊資料庫使用方案,更好的助力業務發展,決定啟動新型儲存服務(NewSQL)的選型調研工作。
TiDB 資料庫,結合了關係庫與 KV 儲存的優點,對於使用方,完全可以當做 MySQL 來用,而且不用考慮資料量大了後的分庫分表以及為了支援分庫分表後的多維度查詢而建立的 Mapping 表,可以把精力全部放在業務需求上。所以我們把 TiDB 作為選型的首選物件展開了測試和試用。
TiDB 測試
- 功能測試
TiDB 支援絕大多數 MySQL 語法,業務可以將基於 MySQL 的開發,無縫遷移至 TiDB。不過目前 TiDB 不支援部分 MySQL 特性,如:儲存過程、自定義函式、觸發器等。
- TiDB 壓力測試
通過測試工具模擬不同的場景的請求,對 TiDB 資料庫進行壓力測試,通過壓力測試結果的對比,可以提供 RD 使用 TiDB 的合適業務場景以及 TiDB 的使用建議。 此次壓力測試,總共使用 6 臺物理伺服器,其中 3 臺 CPU 密集型伺服器,用於啟動 TiDB - Server、PD 服務;另外 3 臺為 IO / CPU 密集型的PCIE 伺服器,用於啟動 TiKV 服務。 使用 sysbench - 1.0.11 測試資料大小為 200G 的 TiDB 叢集,在不同場景下 TiDB 的響應時間(95th per):
- 結果整理
-
順序掃描的效率是比較高的,連續的行大概率會儲存在同一臺機器的鄰近位置,每次批量的讀取和寫入的效率會高;
-
控制併發執行的執行緒數,會減少請求響應時間,提高資料庫的處理效能。
- 場景建議
-
適合線上業務混合讀寫場景;
-
適合順序寫的場景,比如:資料歸檔、操作日誌、攤銷流水。
- TiDB 預上線
將 TiDB 掛載到線上 MySQL,作為 MySQL 從庫同步線上資料,然後業務將部分線上讀流量切換到 TiDB,可以對 TiDB 叢集是否滿足業務訪問做好預判。
業務接入
- 遷移過程
我們第一個接入 TiDB 的業務線是轉轉訊息服務。訊息作為轉轉最重要的基礎服務之一,是保證平臺上買賣雙方有效溝通、促進交易達成的重要元件,其資料量和訪問量都非常大。起初我們使用的是 MySQL 資料庫,對其所有的業務都做了庫的垂直拆分以及表的水平拆分。目前線上有幾十 TB 的資料,記錄資料達到了幾百億。雖對 MySQL 做了分庫分表,但例項已經開始又有偶發的效能問題,需要馬上對資料進行二次拆分,而二次拆分的執行成本也比較高,這也是我們首先遷移訊息資料庫的原因之一。
訊息服務有幾個核心業務表:聯絡人列表、訊息表、系統訊息表等等。聯絡人列表作為整個訊息系統的樞紐,承載著巨大的訪問壓力。業務場景相對其他表最複雜的,也是這個表的例項出現了效能問題,所以我們決定先遷移聯絡人列表。
整個遷移過程分三步:測試(判斷 TiDB 是否滿足業務場景,效能是否 OK)、同步資料、切流量。
**(1)測試:**首先我們模擬線上的資料和請求對“聯絡人列表”做了大量功能和效能的驗證,而且還將線上的資料和流量引到線下,對資料庫做了真實流量的驗證,測試結果證明 TiDB 完全滿足訊息業務的需求。引流工作,我們是通過轉轉自研的訊息佇列,將線上資料庫的流量引一份到測試環境。測試環境消費訊息佇列的資料,轉換成資料庫訪問請求傳送到 TiDB 測試叢集。通過分析線上和測試環境兩個資料訪問模組的日誌可以初步判斷 TiDB 資料庫是否可以正常處理業務請求。當然僅僅這樣是不夠的,DBA 同學還需要校驗 TiDB 資料的正確性(是否與線上 MySQL 庫一致)。驗證思路是抽樣驗證 MySQL 庫表記錄和 TiDB 的記錄 Checksum 值是否一致。
**(2)同步資料:**DBA 同學部署 TiDB 叢集作為 MySQL 例項的從庫,將 MySQL 例項中的聯絡人列表(單例項分了 1024 個表)的資料同步到 TiDB 的一張大表中。
**(3)切流量:**切流量分為三步,每兩步之間都有一週左右的觀察期。
-
第一步將讀流量灰度切到 TiDB 上;
-
第二步斷開 TiDB 與 MySQL 的主從同步,業務開雙寫(同時寫 MySQL 和 TiDB,保證兩庫資料一致)確保業務流量可以隨時回滾到 MySQL;
-
第三步停止 MySQL 寫入,到此業務流量完全切換到 TiDB 資料庫上。
遷移過程中最重要的點就是確保兩個資料庫資料一致,這樣讀寫流量隨時可以切回 MySQL,業務邏輯不受任何影響。資料庫雙寫的方案與上文提到的引流測試類似,使用訊息佇列引一份寫入流量,TiDB 訪問模組消費訊息佇列資料,寫庫。但僅僅這樣是不能保證兩個庫資料一致的,因為這個方案無法保證兩個寫庫操作的原子性。所以我們需要一個更嚴謹的方案,轉轉的訊息佇列還提供了事務訊息的支援,可以保證本地操作和傳送訊息的原子性。利用這一特性再加上非同步補償策略(離線掃描日誌,如果有失敗的寫入請求,修正資料)保證每個訊息都被成功消費且兩個庫每次寫入結果都是一致的,從而保證了 MySQL 與 TiDB 兩個庫的資料一致。
- 遇到問題
按照上述的方案,我們已經將訊息所有的業務都切到 TiDB 資料庫上。遷移過程中也不都是順風順水,也遇到了問題,過程中也得到了 TiDB 官方團隊的大力支援。這裡主要介紹兩個問題:
(1)TiDB 作為分散式儲存,其鎖機制和 MySQL 有很大不同。我們有一個併發量很大,可能同時更新一條記錄的場景,我們用了 MySQL 的唯一索引保證了某個 Key 值的唯一性,但如果業務請求使用預設值就會大量命中唯一索引,會造成 N 多請求都去更新統一同一條記錄。在 MySQL 場景下,沒有效能問題,所以業務上也沒做優化。但當我們用這個場景測試 TiDB 時,發現 TiDB 處理不太好,由於其使用的樂觀鎖,資料庫輸出大量的重試的日誌。業務出現幾十秒的請求延遲,造成佇列中大量請求被拋棄。PingCAP 的同學建議調整 retry_limit 但也沒有完全生效**(該 BUG 已經在 2.0 RC 5 已經修復)**,最後業務進行優化(過濾使用預設值的請求)後問題得到解決。
(2)第二個問題是運維方面的,DBA 同學按照使用 MySQL 的運維經驗,對一個上近 T 的表做了 Truncate操作,操作後,起初資料庫表現正常,但幾分鐘後,開始出現超時,TiKV 負載變高。最後請教 PingCAP 同學分析,定位是操作觸發了頻繁回收 Region 的 BUG**(該 BUG TiDB 2.0 版本已經修復)**。
線上效果對比*
- 佇列等待情況對比
使用 TiDB 資料庫,業務模組佇列請求數基本保持 1 個,MySQL 會有較大抖動。
- 請求延遲情況對比
使用 TiDB 資料庫,整體響應延時非常穩定,不受業務流量高峰影響,但 MySQL 波動很大。 另外在擴充套件性方面,我們可以通過無縫擴充套件 TiDB 和 TiKV 例項提升系統的吞吐量,這個特性 MySQL 是不具備的。
- 業務延遲和錯誤量對比
接入 TiDB 資料庫後業務邏輯層服務介面耗時穩定無抖動,且沒有發生丟棄的情況(上圖錯誤大多由資料訪問層服務佇列堆積發生請求丟棄造成)。
TiDB 線上規模及後續規劃
目前轉轉線上已經接入訊息、風控兩套 OLTP 以及一套風控 OLAP 叢集。
叢集架構如下:目前轉轉線上 TiDB 叢集的總容量幾百 TB,線上 TiDB 表現很穩定,我們會繼續接入更多的業務(留言,評論、搜尋、商品、交易等等)。
1. 後續規劃
- 多個正在開發的新業務在開發和測試環境中使用 TiDB,線上會直接使用 TiDB;
- 轉轉核心的留言、評論、搜尋、商品、交易訂單庫計劃遷移到 TiDB,已經開始梳理業務,準備展開測試;
- 計劃在後續 TiDB 的使用中,TiKV 伺服器池化,按需分配 TiKV 節點。
2. TiDB 使用成果
- 利用 TiDB 水平擴充套件特性,避免分庫分錶帶來的問題,使得業務快速迭代;
- TiDB 相容 MySQL 語法和協議,按照目前線上 MySQL 使用規範,可以無縫的遷移過去,無需 RD 做調整,符合預期;
- 在資料量較大的情況下,TiDB 響應較快,優於 MySQL;
- 叢集出現故障對使用者無感知;
- TiDB 自帶了完善的監控系統,使得運維成本大大降低。