TiDB 在小紅書從 0 到 200+ 節點的探索和應用

做者介紹:張俊駿,小紅書數據庫與中間件團隊負責人數據庫

小紅書使用 TiDB 歷史能夠追溯到 2017 年甚至更早,那時在物流、倉庫等對新技術比較感興趣的場景下應用,在 2018 年 5 月以後,咱們就開始逐步鋪開,延展到其餘適合 TiDB 的場景中去。截止目前,小紅書使用的 TiDB 節點數在 200+ 個,將來也有更大擴展空間。安全

本文根據近兩年 TiDB 在小紅書的落地過程,和你們一塊兒探討一下,小紅書在新數據庫選型的考慮因素、以及 TiDB 從場景分類的角度是如何考量及逐步推廣使用的。具體包括如下內容:性能優化

  1. 目前小紅書數據服務總體架構,以及從數據流角度如何對不一樣數據庫服務進行定義和劃分。多線程

  2. 從基本功能、數據同步、部署管理、運維、二次開發及優化、安全等多個維度解讀小紅書在數據庫選型的考慮因素及思考。架構

  3. TiDB 的適用場景,以及在小紅書如何進行場景選擇、如何逐步進行上線規劃。併發

1、小紅書數據服務總體架構

圖 1

如圖 1 所示,小紅書數據服務總體架構最上層是在線應用層(online app),應用層往下確定會依賴一些離線(offline)或者在線(online)的 database(其實它更多的意義應該算存儲,好比 Redis 也被咱們理解爲 database,因此稱之爲「數據服務」可能會更好),這些在線數據服務(online database)會有兩條線:app

  • 經過實時數據流(dataflow)將數據導入到離線數據庫(offline database)支撐離線分析以及實時展現的場景,也就是圖 1 最下層的展現類服務(presentation)和數倉(data warehouse)。運維

  • 這些數據還可能會回灌到線上其餘 database 上,有些是離線,有些是實時。工具

圖 1 藍框中的部分基本上都由咱們團隊負責。咱們首先須要保證在線數據庫(online database) 的穩定性、安全性以及性能優化等,其次咱們的多種數據庫數據同步服務(database to database replication) 有點像阿里提出的 data replication center 這個概念,這部分也基本上由咱們團隊全權負責。oop

2、小紅書數據服務組件選型 RoadMap

對於一個新的數據庫或數據服務組件選型(如 TiDB),咱們該從哪些方面去入手搞清楚它的特性?下面分享一下咱們的經驗。

1. 產品的基本功能

第一步,咱們須要考察該數據服務/組件的基本功能,首先,咱們要了解它的讀寫場景,包括點查、批量獲取(batch get)、範圍掃描(range scan)、過濾查詢(filter query)、聚合查詢(aggregation)等等。而後咱們看看它是否符合響應時間(latency) 以及帶寬(bandwidth,即能承接多少併發)的要求。最後咱們會關注可擴展性,好比 TiDB 可能最大的特色就是擴展性很是好。這幾點是你們都會想到的最基本的要求,這裏我就一筆略過。

2. 數據同步與處理相關解決方案

第二部分是數據同步與處理相關解決方案。這裏咱們有如下 4 點考慮:

  • 首先考慮這個數據服務組件的數據同步是同構或異構的場景,同構的同步好比 Redis to Redis、MongoDB to MongoDB,異構的同步好比 TiDB 到 Kafka 等等。這個狀況基本上你們也會遇到,由於一個數據服務很難同時支持兩種或更多的場景,不一樣的數據服務之間的數據要保持一致,就會產生數據同步的問題。

  • 接下來考察離線導出,好比若是咱們依賴 Hive、 Spark 作離線分析,那麼可能要放在 HDFS、S3 等對象存儲上,就須要離線導出,通常是天天導出一次。

  • 第三點是實時導出,即在實時場景下可能須要導出到消息中間件,好比 Kafka、RocketMQ 等。

  • 第四點是離線導入,導入的場景通常是在離線的引擎計算的結果,做爲評估的指標再寫入線上的 database 提供數據服務。

圖 2

3. 產品的部署及管理

部署其實很是重要,它涵蓋如下 5 個方面。

  • 第一點是組件管理界面。當集羣多到必定程度時,若是你沒有一個很好的管理界面,會連本身用的是什麼集羣都記不清楚。因此管理界面很是必要,並且最初多是 1 個集羣 1 個管理界面,而後是 100 個集羣 1 個管理界面。

  • 第二點是選版本和機型。在版本選擇方面,不一樣版本提供的功能不同,同時也要考慮版本升級的成本。在機型的選擇方面,不管是自建機房、用雲主機,仍是使用最近推出來的新概念「Bare-Metal」(裸金屬),機型選擇都是很是痛苦的事情,但同時機型選擇對存儲來講相當重要。咱們目前絕大多數都是部署在騰訊雲和 AWS 上,而且開始慢慢嘗試在 Bare-Metal 上的應用。

  • 第三點是監控、報警、日誌收集。我將這個問題分爲三個級別:機器級、應用級和業務級。機器級指機器主機上的問題,包括如何作監控、報警、日誌收集,雖然這點與該數據服務組件沒有太大關係,可是咱們仍然須要關注;應用級指該數據服務組件的報警、監控、日誌收集具體是怎麼作的;業務級指特定的業務有特定的報警需求,例如一個訂單表忽然有幾十萬的 QPS 寫入,在平時屬於異常的狀況,這種異常是須要自定義的,甚至須要咱們在某些特定位置埋點並輸出結論,由於若是不關注這些異常狀況,就極可能致使這三件事用三種不一樣架構,最後部署的集羣極其複雜繁瑣,三個級別用了三個不一樣的監控工具,看到三個不一樣的監控界面,致使運維成本增長。

  • 第四點是跨區/跨雲部署。這一點多是互聯網公司的比較大的需求。在遇到跨區/跨雲的部署的時候,須要考察該數據服務組件是否天生支持跨區/跨雲。若是不支持,須要再考慮是否須要再啓動數據同步。

  • 第五點是考察附屬組件,也就是與該數據服務組件強綁定的其餘組件,好比 zk、lb、jmx_exporter 等等,這些組件的部署成本也須要考慮。咱們須要減小 OPS 成本,或者說,一個好的總體架構設計可以防止業務瘋狂上線時不少意外的出現。

4. 運維的易用性

運維包括擴容、縮容、遷移,其中遷移可能要考慮跨區遷移、機型升級遷移等。在使用維護某個組件的時候會產出「XX 組件的運維手冊」,這樣下次遇到問題的時候,能夠先去看看運維手冊裏它是不是一個已知問題,有沒有現成的解決方案。在公司人員變更比較頻繁或者業務方直接介入到這個場景的時候,若是沒有運維手冊,有些項目很難落地。

圖 3

5. 產品可優化的空間

優化部分基本上分爲配置調優、客戶端代碼調優、二次開發、三次開發。其中二次開發就是在現有的開源產品上再開發,修復 bug 或者本身實現某些新增功能/工具,將來可能還會貢獻給社區;而三次開發則是本身寫一個和某些組件相似的東西,直接替換掉。在小紅書內部,二次開發是比較主流的,三次開發不多,畢竟從零開始自研一個組件到適應特定業務場景,實際上是跟不上咱們的業務上線節奏的,因此三次開發至少眼下不適合做爲咱們主要的攻堅方向。

6. 其餘考慮因素

將來在小紅書數據服務組件系統,咱們會作不少完善工做,好比安全、審計、服務化、容器化等方面的事情。譬如咱們目前在部署一個組件的時候,容器化尚未在討論範圍以內,也就是須要用容器部署就容器部署,須要在虛擬機上部署就在虛擬機上部署,並無一個明確的結論傾向。固然,我我的認爲將來容器化是一個主流趨勢。

以上就是小紅書的數據服務組件選型的 RoadMap,看起來跟接下來要講的「TiDB 在小紅書多場景下的應用」沒有太大的關係,但我認爲在作應用以前應該先把上面列舉的這些方向思考清楚,這樣會對將來落地工做的投入產出比產生很是大的影響,好比咱們最近按照上面的方向調研 Tidis 和 TiFlash 的時候速度就快不少。

3、TiDB 在小紅書多場景下的應用

場景 1:展現類業務

圖 4

TiDB 在小紅書的第一個應用場景是展現類業務,它的 pipeline 如圖 4 中紅色部分所示,線上通常是 MongoDB 或者 MySQL,經過一條實時數據流(realtime dataflow) 鏈接 Redis 或者 TiDB,最後實現 presentation 功能。接下來介紹這類場景下的兩個具體項目。

項目 1:大促實時看板

圖 5

第一個項目是大促實時看板,在去年雙十一期間上線,當時咱們的節奏也比較快,七、8 月開始調研,11 月就上大促業務。

當時該項目下一共有 8 個實時報表,QPS 寫入均值 5K,大促活動開始時 QPS 峯值接近 200K/秒,每過 2s 會有較大的聚合查詢 query,聚合結果還須要寫入 Redis 再 pop 到 TiDB,集羣規模方面只用了 10 個 TiKV 和 3 個 PD。還有一點值得提一下,當時每一個節點掛了 3.5T * 4 塊的 NVME SSD,可是後來事實證實這個選型是有問題的,由於大促的時候咱們人人都在盯着,磁盤壞了會馬上獲得解決,因此即便把四塊盤作了 raid0,而後上線了,根本沒法肯定 NVME 盤出問題的機率是多少,後來差很少每月會出現一兩次相似的故障,故障率很高,雖然我相信將來 NVME 會作得更好,但這樣高的故障率從設計角度來看,這個選型就未必是最合適的。

在實現上,咱們遇到的第一個問題是保證最終一致性的寫入。咱們作了多線程寫入,每一個線程寫入特定的記錄,保證線程之間不會衝突。除此以外,咱們還作了一些調優工做,咱們發現每個事務的 batch insert size 設置爲 100 時能達到吞吐、延遲綜合最優的要求。最初業務側設置的 batch size 很是大,後來發現事務之間衝突的機率、響應的時間等等都會出現一些問題,但 batch size 設置爲 1,那麼併發又會成爲一個問題。因此通過了一段時間的調優,最後獲得了前面的結論。這個參數你們能夠根據需求本身調整,用二分法/摺紙法試驗就能夠獲得。

這個項目最終全程寫入和查詢在大促期間保持穩定,寫入時延小於 20ms,查詢時延小於 1s,由於咱們須要 2s 作一次查詢,這個響應時間是能知足要求的。

項目 2:實時業務數據展現

圖 6

這個項目背景有兩點:

  • 第一,咱們業務方有實時分析的需求,須要實時觀測線上庫寫入內容,多是針對某個用戶作一些查詢,還多是一個很是大的 query,好比須要快速看到新上線功能的效果,尤爲是在實驗以及風控等項目上響應時間要求很是高。

  • 其次須要做爲離線 ETL 任務的數據源,同時須要預備改成線上服務。盤算一下業務量,總共支持須要超過一百個 MongoDB 或 MySQL 數據庫的實時展現,峯值總讀寫 QPS 超過 500K,如今的業務需求大概這個量級,將來可能會更高。

咱們當前考慮是按業務線去拆分集羣,部分核心表一式多份。好比用戶表可能有多個業務依賴,好比社區業務、訂單物流業務等等,但若是按照業務線拆分集羣以後,就沒法作 Join 了,這也是咱們不能接受的,因此對核心表會以一式多份的形式存在。實際使用場景下,大部分都是點查,好比查特定用戶、特定訂單的線上狀態,同時有少許的單表聚合查詢和跨表 Join 查詢。換句話說,能夠認爲是一個實時的數據倉庫,但又不作複雜 ETL,更多依賴線上真實數據。

咱們的設計方案是把 TiDB 做爲一個 MySQL/MongoDB 的從庫,但對於 MongoDB 來講可能還要作一點同步任務的數據改造工做。如今規模是 10 節點 TiKV + 3 節點 PD 的集羣總共有 3 個,後面可能會按需求擴增。

在實踐細節上,首先咱們會基於 Canal 去作 oplog/binlog 的實時同步。其次,目前咱們對加列以外的 DDL 支持得不夠好,這部分還須要 DBA 手工介入,但在將來會有一些改進。最後是多租戶問題,好比判斷某個部門的同事是否有權限訪問另外一個部門的數據庫,這件事在線上會很是頭疼,如今在接入層解決這個問題,咱們內部有一個叫 venus 的展現平臺,將上層全鏈控制、認證等事情去掉,因此咱們就不用關注這件事了,至少眼下不用關注。這個項目已經開始逐步上線,基本上架構已經肯定。

場景 2:分析類業務

圖 7

分析類業務的 pipeline 如圖 7 所示,最後的 data warehouse 構建在 AWS 上。

項目 3:分庫分表 MySQL ETL

圖 8

這個場景下的第一個項目是作分庫分表的 MySQL ETL。以最大的表爲例,上游 10 節點的MySQL,共計 10000 個分表,存量數據 1000 億條左右,每日增量 10 億+,QPS 寫入均值 3000 條/s,峯值接近 10000 條/s,平臺促銷活動對這部分影響也不大,甚至反而會下降,由於活動主要是電商部門在作,社區的查詢需求反而變少。咱們在 TiDB 離線庫保留了大約 30 天增量監控數據,全量數據存在 S3 上,每日夜間(白天偶爾)會有基於 sqoop 的抽數任務觸發。集羣規模方面,目前使用 10 節點 TiKV + 3 節點 PD。

在實踐細節方面,首先咱們對 MySQL 自增 ID 進行了處理,而後對 sqoop 進行了一些基於 TiDB 的細節上適配,最後調整 TiDB 的 max transaction size 以優化抽取率。除此以外,還有一個值得一提的事情,由於實體數據(用戶/筆記/訂單數據等)不宜硬刪除,可是在 MySQL 關係表作軟刪除是很是可怕的事情,最後可能會由於數據量太過於龐大形成雪崩。但 TiDB 不同,咱們把線上的硬刪除變成了 TiDB 的軟刪除,這對於數倉來講是很是有價值的事情。對於天天全量抽數的表來講,不管軟硬刪除,次日數倉裏的數據老是對的。可是對於大數量的場景,全量抽數代價太高,就會採起增量抽取的方式,即設置一個條件,通常是 update_time 爲今天。這時候硬刪除就存在問題了:上面的 query 條件沒法判斷一條記錄到底是被刪除了,仍是在當天沒有被更新。而前面又提到,關係表上是不適合作軟刪除的。因此咱們在作 ETL 的時候,線上作 delete 的操做,咱們在 TiDB 上會新增一個 is_deleted 字段,並將其設置爲 true。這個時候有一個小細節,刪除這個操做的時間戳怎麼設置。刪除這個操做時的時間戳是跟普通寫入的時間戳不同的。普通的寫入,時間戳就是線上庫的 update time,可是刪除的時候是不會帶上線上的 update_time 的,因此由於這條記錄被硬刪除了,時間戳都找不到了,這時咱們只能用收到這條消息的 update_time 去作它的時間戳,這時就會有些小問題,固然這個問題咱們尚未徹底解決掉,假設你們有相似的需求的話,咱們能夠私下交流討論。目前這個項目已經上線,運行穩定。

項目 4:MySQL 歸檔

圖 9

項目 4 MySQL 歸檔是基於項目 3 的演進。業務背景方面,以最大的表爲例,主要爲物流倉儲部門的訂單及衍生信息,存量很是很是大,每個月進行歸檔到 TiDB 的數據有數十億,但對 QPS 要求不是很高,與業務方討論以後暫定,過去一年半的記錄存放在 TiDB 供業務方查詢,更久遠的記錄歸檔到 S3/Cos 上。

項目 4 與項目 3 代碼相比處理的場景更復雜一些,由於它以前 MySQL 的分庫分表邏輯不像項目 3 那些清晰,集羣規模也會相對大一些,目前是 25 個 TiKV 節點 + 3 個 PD 節點,將來可有擴容的需求。實現細節上,項目 4 和項目 3 相似,這裏就不贅述了。

場景 3:線上服務

圖 10

TiDB 接入實時數據寫入服務的業務有如下四個考慮:

  • 第一點是代碼更改爲本,這一項成本已經比較低了,由於基本上都是 jdbc 鏈接,但多多少少會有一些變動。

  • 第二點是數據遷移成本,對於已經上線的業務來講,遷移數據都是一件很是費勁的事情,尤爲是咱們還要求不停服務進行熱遷移的話。

  • 第三點是運維成本,從本來的 MySQL 切換到咱們本身維護 TiDB ,其實無形中增長了運維成本,尤爲是在掛盤率比較高的場景下。

  • 第四點是技術棧成本,由於有些人對 TiDB 不熟悉,會比較懼怕接觸和使用,絕大部分人更願意用本身熟悉的東西,因此須要有一個知識學習的過程,這也是一個成本。

如今咱們已經有一部分線上業務從 Hive 離線導入到 TiDB 作 T+1 級別數據服務,並且咱們新上線業務的關係型數據庫選型已經開始傾向於 TiDB,主要是由於它的擴展性爲咱們節省了很大的時間成本,尤爲是業務增加比較快的狀況下,選擇 MySQL 分庫分表實際上是一件代價極其大的事情。

我記得以前有同事問了一個問題,說這個場景用別的東西也能夠作,爲何必定要用 TiDB 呢?爲何要用牛刀來殺一隻雞呢?我回答他:有種狀況是你找不到一隻牛來殺,只能先「殺雞」成功了,將來纔有「殺牛」的機會,可是你們不要認爲「殺雞用牛刀」是一件很蠢事情,這能夠理解爲一個鑑定或者測試的過程。

4、將來 TiDB 在小紅書的接入計劃

圖 11

最後分享一下 TiDB 將來在小紅書的接入方向。

  • 首先在 ETL 方面,TiDB 的事務隔離性對某些場景來講有點高,咱們但願能自定義事務隔離需求,好比兩個事務有衝突,但咱們實際的寫入需求只要最終一致性。可是從目前 TiDB 的設計來講,這個需求可能比較困難,可是也不排除將這個事情 raise 起來的可能性。

  • 第二個很重要的事情是跨數據中心的部署,這是咱們將來會重點關注的方向,可能最終會獲得一個通用的解決方案,目前的規劃還不是特別明晰,由於將來業務可能在不一樣的雲會有不一樣的形態,咱們也但願能找到成本相對更低的解決方案。

  • 第三點是自動化運維,目前是往 TiDB + K8s 的方向推進,更好的解決集羣部署問題,由於在虛機上部署仍是比較痛苦的。

  • 最後,咱們已經有同事負責調研 TiFlash、Tidis,但目前尚未線上應用在依賴。同時咱們也在作 CK 和 TiFlash 的對比調研,目前 CK 已經在線上提供服務,將來若是 TiFlash 的調研結論是比較優秀的,確定也會有計劃替換。

本文根據張俊駿老師在 TiDB TechDay 2019 上海站上的演講整理。

更多案例閱讀www.pingcap.com/cases-cn/

相關文章
相關標籤/搜索