做者:汽車之家技術學院-技術架構組git
SQL Server + .Net 是不少早期互聯網企業的標配技術棧,雖然 TiDB 是兼容 MySQL 協議和生態的數據庫,可是 TiDB 適用的業務場景是通用的。在開源新技術大行其道的今天,如何從 SQL Server 無縫遷移至 TiDB,汽車之家作了一個創新的示範。github
本文將從業務背景、遷移方案、同步、業務改造、上線效果、周邊建設等多個角度,詳細介紹瞭如何從 SQL Server 數據庫遷移至 TiDB 數據庫。相信不管你是架構師、業務開發、仍是 DBA,都會有不一樣層面的收穫。sql
汽車之家社區於 2005 年上線,做爲汽車之家最老的業務之一,十四年來沉澱了億級帖子、十億級回覆數據,目前天天有千萬級 DAU、億級的訪問量,接口日均調用量 10 億+ 次 。期間經歷過架構升級重構、技術棧升級等,但其數據始終存放在 SQL Server 中。隨着數據的不斷遞增,咱們在使用 SQL Server 數據庫方面遇到了不少瓶頸,以致於咱們不得不尋找一個新的數據庫替換方案。數據庫
隨着業務的不斷擴大,汽車之家社區的訪問量和發表量不斷上漲,遇到的數據庫問題也愈來愈多,下面列舉兩個必須很快解決掉的問題:安全
在 2018 年末的時候,公司專門成立了虛擬架構組來調研新的數據庫來解決汽車之家社區遇到的問題。通過各類分析和測試,今年年初肯定方向爲分佈式數據庫,一共調研了三款當前比較火的分佈式數據庫:TiDB(PingCAP),Ignite(ASF-TLP) 和 CockroachDB。通過無數次測試咱們最終選擇了 TiDB,主要有如下幾個緣由:服務器
<center>TiDB 的研發同窗到之家進行技術交流</center>架構
<center>咱們去 TiDB 進行系統的課程培訓</center>併發
下面引用 TiDB 官方的一段描述:運維
TiDB 是一款定位於在線事務處理、在線分析處理(HTAP: Hybrid Transactional/Analytical Processing)的融合型數據庫產品,實現了一鍵水平伸縮,強一致性的多副本數據安全,分佈式事務,實時 OLAP 等重要特性。同時兼容 MySQL 協議和生態,遷移便捷,運維成本極低。
從中咱們不難發現,TiDB 切實解決了咱們在應用 SQL Server 時候的痛點:分佈式
基於以上理論的支持,咱們進行了大量的功能測試、性能測試、異常測試、業務接入測試等。
OLAP 測試:50G TPC-H 測試,TiDB 相較 MySQL 有很大的速度優點:
TPC Benchmark™H(TPC-H) 是決策支持基準。 它由一套面向業務的臨時查詢和併發數據修改組成。 選擇查詢和填充數據庫的數據具備普遍的行業範圍相關性。 該基準測試說明了決策支持系統,該系統可檢查大量數據,高度複雜地執行查詢併爲關鍵業務問題提供答案。
在真正的數據遷移以前,咱們還有一些實際問題須要解決:
下圖是咱們整個遷移過程的架構圖,包含 SQL Server 到 TiDB 的全量同步、增量同步,以及 TiDB 到 SQL Server 的反向同步過程。
如今,須要肯定的是整個項目的遷移流程,有了大的方向,在實施中目標會更明確一些。
以汽車之家社區的業務形態以及數據量級來看,動輒十多個小時的離線遷移是徹底不可能接受的,咱們只能在凌晨 1:00-3:00 這個時間窗口來完成遷移,且時間越短越好。
因此咱們選擇在線遷移的方案,在線遷移稍微複雜一些,流程上有準備全量數據,而後實時同步增量數據,在數據同步跟上(延遲秒級別)以後,採用滾動升級的方式將應用的讀流量切換到 TiDB 上。
觀察應用正常運行,進行短暫停機和關停 SQL Server 寫權限,確保沒有數據再寫入 SQL Server, 就能夠將寫流量指向 TiDB,至此遷移完畢。
整個遷移流程中,應用的讀數據場景不受影響,寫入場景受影響週期爲停機(關寫權限)到寫流量指向 TiDB。
下圖是咱們梳理出來的流程圖,咱們在整個遷移的過程當中必須嚴格按這些流程執行。
下面咱們來詳細介紹全量和增量同步的實施方案。
首先咱們要感謝如下兩個開源項目,站在巨人的肩膀上使咱們節約了不少時間。
愚公是阿里巴巴推出的一款 Oracle 數據遷移同步工具,而做者 alswl 在此基礎上實現了 SQL Server 數據源的支持。在此愚公的使用方法咱們再也不贅述,感興趣的同窗請自行查看。
在認真拜讀了大神的項目,並進行了相關測試後,發現它並不能 100% 知足咱們的需求。
Yugong 數據流是標準 ETL 流程,分別有 Extractor、 Translator、Applier 這三個大類來實現 ETL 過程。
首先講 Extractor,愚公原有的配置方式是將須要導出的庫表寫在配置文件當中,這對於 1000+ 張表來講,太不現實了。這裏咱們增了一個新特性,在不配置須要導出的表名的狀況下,將數據庫中全部的用戶表讀出來,並經過一個新增的配置項進行正則匹配,以此決定哪些表須要進行數據同步。
#查詢表 SELECT name FROM sys.databases WITH (nolock) WHERE state_desc = 'ONLINE' #查詢開啓CDC的表 SELECT name FROM %s.sys.tables t WITH (nolock) JOIN %s.[cdc].[change_tables] ct WITH (nolock) ON t.object_id = ct.source_object_id
其次,合庫合表後,原有 SQL Server 中各個表的自增主鍵 ID 衝突,因此新增實現 RowDataMergeTranslator,其功能是,讀取內存中的 RowData 而後進行轉換,將從 SQL Server 中讀取的行數據,丟棄其原有的主鍵列,轉而使用 TiDB 生成。並根據配置文件決定哪些表須要實現這一特性。
record.removeColumnByName(config.getDiscardKey());
最後的 Applier 並未作改動,處理好的數據直接寫入 TiDB。
自此合庫合表的事情咱們解決了。
在實現這部分需求的時候,咱們應用了 SQL Server 的 CDC,並在增量同步的基礎上增長了延遲驗證數據正確性的功能。更多關於 CDC 的內容,這裏再也不贅訴,你只須要知道它能獲取到增量數據,參考 CDC官方文檔。
須要注意的是,CDC 開啓的時機須要在全量同步以前,保證 CDC 記錄能夠覆蓋全量同步過程當中產生的增量數據。
根據以上的流程圖能夠看到,Producer 從 SQL Server 中讀取 CDC 日誌,並將其轉化成一條包含表信息、列信息和行數據的消息,投遞到 Kafka 中。下游的消費者在拉取到消息以後,把數據轉化成兼容 MySQL 的 SQL 語句在 TiDB 中執行(這裏也實現了合庫合表),從而實現整個數據增量同步的過程。
這裏還有另外一個消費者實現數據校驗功能,它會延遲五秒消費同一隊列,並經過提取主鍵(或索引)的方式從 TiDB 中查出該條已經寫入的數據,將兩側的整行數據作比較(本實踐中去除主鍵後比較),若是有問題會進行嘗試從新寫入,如出現異常則向相關人員發送報警。
在實現了這些並進入到測試階段後,咱們發現了一個問題,1000+ 回覆表,對應 1000+ CDC 日誌表,一個 Producer 就須要開啓 1000+ 線程。以設計的 5s 間隔去輪詢這些表時,服務器 CPU 直接就跑滿了,產生了大量線程等待,輪詢 CDC 日誌的及時性沒法保證。經過分析業務和 DBA 查詢得知,其實汽車之家社區天天產生的回覆有 95% 都集中在最新的 5% 的帖子當中。換言之,咱們只有幾十張表須要如此高頻的去檢索 CDC 日誌,其餘的表咱們經過增長輪詢間隔、分批部署等方式,將這個問題解決了。
細心的同窗讀到這裏會發現,校驗功能其實邏輯上並不嚴謹,若是說在五秒鐘內上游數據產生了變動,就有可能會產生拿着新數據去校驗老數據的問題。這裏有兩個解決方案:
以前咱們提到了,當項目切換到 TiDB 之後,須要預防其出現不可預估的問題,可以隨時切回 SQL Server 才能保障萬無一失。
TiDB Binlog 使得這件事情垂手可得。咱們使用官方提供的 Pump 和 Drainer 將 Binlog 抽取到 Kafka 之中,解析數據變動的內容,根據業務 ID 計算出數據在 SQL Server 中本來屬於哪一個庫哪一個表,而後進行數據同步。
<center>解析 Binlog (Protobuf 協議)</center>
<center>經過業務 ID 決定數據寫到哪一個庫表</center>
就業務的改造這一環節,因歷史積澱,需修改的地方不少,分佈於各個項目之中,咱們採起經過接口查找實現、搜索代碼、DBA 幫助抓取 SQL 的方式,保證涵蓋了 100% 的相關業務,只有這樣才能保障上線後無端障。
與此同時,咱們針對每一條改造後的 SQL 都進行了優化,使能夠精確的命中最優的索引,從而實現了在十億級數據量下,TP 業務 99% 的響應時間在 12ms,99.9% 的響應時間在 62ms。
除以上遷移流程所涉及到的功能點之外,咱們還制定了一些開發規範和一些實用工具的研發,用以保障 TiDB 在汽車之家更好的應用。
TiSlowSQL 也是汽車之家運維組參加 Hackathon 項目,具體內容敬請期待後續文章!
汽車之家社區已於 9 月底正式上線分佈式數據庫 TiDB,目前運行穩定。在其餘業務遷移完成以後,汽車之家社區的 SQL Server 服務會逐步下線。對於本次遷移的過程咱們作了如下幾點總結:
由 SQL Server 遷移至 TiDB,從傳統關係型到分佈式 HTAP,從商業受權到開源社區,是汽車之家社區歷史上一次重大的技術方向轉型。
汽車之家有不少海量數據的應用場景,這一次從 SQL Server 到分佈式數據庫 TiDB 的遷移,爲咱們之後其餘業務遷移至 TiDB 打下了良好的基礎,也與 TiDB 官方創建了良好的按期溝通機制。但願 TiDB 官方一如既往的快速迭代,咱們也會和 TiDB 官方合做開發一些比較實用的功能。
關於 TiDB 使用上的疑惑或經驗,能夠登錄 http://www.asktug.com 和你們一塊兒交流~