月活超 1.1 億,用戶超 4 億,你也在用的「知乎」是如何在超大規模 TiDB 集羣上玩轉多雲多活的?來聽聽知乎代曉磊的答案!

導讀

代曉磊,知乎數據庫負責人,同時也是 TiDB 社區北京地區組織者,一位有着 13 年數據庫從業經驗的數據庫老兵,對數據庫運維及 TiDB 有着豐富的實踐經驗。在“2024 新年圍爐茶會”中,他分享了《TiDB 在知乎實踐的那些事》話題,回顧了最近兩年知乎 TiDB 實踐的最新進展 ,以及對數據庫未來發 展方向的個人觀點,本文根據代曉磊老師的演講實錄進行整理。

視頻鏈接: https://www.bilibili.com/video/BV1FT4y1n7fn/

知乎應用 TiDB 歷史非常久,至今總共部署了 400 多個 TiDB Server 節點, 600 多個 TiKV 節點,數據規模達到 PB 級別。知乎有一個最大的 TiDB 集羣有 500 多 TB 的規模,單副本一天能存 30TB 數據,三副本能存將近 100TB 左右。在這種規模下,知乎核心場景中約 30% 的場景都運行在 TiDB 上。

從數據庫版本來看,目前知乎的 TiDB 集羣大概有 80% 處於 TiDB 4.x 版本,有百分之十幾在 TiDB 5.4.3 版本,還有少量的 6.5 版本。應用 6.x 版本主要是因爲一些新的 feature 吸引我們,比如說熱點表、CDC 能力的提升、多雲多活的能力等。

TiDB 在知乎實踐的那些事

1 多雲多活方案實踐

第一個分享的實踐是“多雲多活”。

目前來看,知乎是 TiDB 社區中唯一一家在互聯網場景裏落地多雲多活的。在 2023 年年初的時候,我們就多雲多活架構和 PingCAP 內部的產研團隊做過一些交流。

TiDB 的官方文檔其實提供了很多種多雲多活方案:

第一種是 基於 TiCDC 的主備集羣方案 。通過 TiCDC 的 能力能夠解決一部分多雲多活的需求,相當於使用 MySQL 的 Master and Slave 那種方式來用 TiDB 集羣。它能解決一部分需求的原因取決於你對從庫的定位,是將它定位爲一個災備庫,還是一個只讀庫,還是承擔業務一部分線上流量的庫。

這種架構的關鍵點是什麼呢?就在於 CDC 的同步能力。在 TiDB 4.x 時,CDC 的同步能力確實有點弱。之前我在上家公司的時候,個人與 PingCAP 做了 TiCDC 這個項目的合作,TiCDC 的一些場景、應用、需求,由我來提,由我去驗證。比如早期的 TiCDC 經常容易 OOM,當拉取一個寫入量很大的集羣時,它對 TiKV 的負載影響在 20%左右,通過跟 CDC 團隊一起迭代 + 優化,使得 CDC 對 TiKV 的影響降到 5% 之內。當 TiCDC 向下遊 sync 的時候,它還有一些性能瓶頸,比如說 CDC 拉取得快, 但是 sync 到下游比較慢,那 TiCDC 整個內存消耗就比較大,最後就導致 OOM。後來 CDC 做了一些排序後的數據落地到文件中的改造,避免了一些 OOM 的問題 。通過這些優化,TiCDC 逐漸變得穩定可用。

還有另 外一種解決方案是 自適應集羣方案 。它是 同一個數據中心裏邊的一個主備機房,可以通過自適應的方式去做 raft 級別的同步,可以有同城三中心、異地五中心等方式,將 TiDB 的同集羣分佈在不同 IDC 或者分佈到不同雲的方案。

我們最後選擇的方案其實基於 Placement rule 的方案。我們有三個 IDC ,都是採用的某些雲廠商的服務。其中有兩個在線集羣,在線集羣集羣是可以承擔在線讀寫流量的,每一個集羣裏都有 TiDB Server 節點、 PD 節點和 TiKV 節點,還有一個災備集羣,基於副本 2-2-1 組成了五副本,通過 placement rule 的方式把副本投放到不同的 IDC,然後再結合 follow read 或者 steal read 的方式去承接在線的這部分流量。實現了任何一個在線機房宕機的時候,整個集羣是可用的。最近這一段時間,包括一些大的雲廠商,和一些很知名的 APP,都出現過不可用的故障情況。後面在講到數據庫發展的時候,也會講到多雲多活是未來必須要去解決和發展的方向。

2 數據庫的穩定性建設

然後再講一下我們做的數據庫穩定性建設,具體而言也就是 TiDB 的穩定性建設。TiDB 穩定建設其實分了幾個方面:

2.1 可觀測能力

可觀測能力的提升是解決發現問題和定位問題非常好的方式。可觀測性都包括什麼呢?一般來說是包括如 metric、trace、log 三點。

首先,我來講一講 metric 。剛來到知乎的時候,我發現監控項非常多,集羣版本也很多。你們去看過文檔就知道了,一個 TiDB 集羣相關的監控項,有差不多 90 多個。每個集羣有這麼多監控項,每個集羣的負載不同,它觸發的報警閾 值可能也不同,公司採用同一套模版來渲染監控項目,這樣的話,不同負載的集羣在同一套報警觸發閾值的情況下,就會發現我的手機晚上不斷地收到預警信息,晚上根本就睡不着。metric 這個問題如果不解決其實真的很痛苦。

那麼,我們是怎麼解決這個問題的呢?

首先,我們對各種集羣要設定不同的報警閾值,千人千面。不同集羣的版本不一樣,它的 metric 的表達式也不一樣,它的閾值在不同版本也就不一樣。你需要動態地去適配,搞成一個配置表,把這些監控項的配置實例化。針對某個集羣的這套九十個指標的監控進行實例化;然後是報警配置,你可以做一些報警的聚合。之前的話,報警一發一堆,都是同一個報警。比如說有一個 schema error,這個報警可能同個集羣裏邊有多個人、多個團隊都在使用,那這個報警聚合之後就會發一條給到我們。怎麼做報警聚合,怎麼做報警預置,怎麼做報警的定製化,發送不同人,這都是屬於在 metric 做的一項。我們通過優化這些閾值報警,從最高時候的 1, 500 個 critical 的報警降到了幾十個。這個東西一週幾十個的話,再除上 7 天,每天就只有幾個。再分分時間段,到晚上的報警也就稍微少一點, DBA 也能睡着覺 了。

第二是 trace+log 一起。 trace+log 是在 Ti DB 定位問題的時候很好的一個手段。知乎是 all in K8s 的,基於 TiDB operator 去做了一套整體的管控。這套東西對於這一套架構來講,你要存日誌的話,其實你得需要制定一定的 PVC 去綁定相應的 PV。存儲需要綁 PV,你的日誌也要綁 PV。但是我們日誌沒有綁 PV,因爲數據盤都是給 tikv 用,日誌建議用動態雲盤,因爲價格問題就沒有配置。所以,之前日誌只會打到 Pod 的 100M 標準輸出裏邊去做輪詢。有時候有的集羣日誌特別大的時候,如果這個日誌如果沒有持久化到硬盤,它只能保留幾分鐘,可能是 10 分鐘。那 10 分之前發生的一個問題,之後再去排查的時候,就會發現沒日誌來看了。

在跟業務線去開故障覆盤會的時候,這個業務就會 argue,“你爲什麼沒有那個日誌?”排查不出來問題的時候,因爲沒有日誌這一項可能會附帶上故障責任。那這個這時候需要怎麼做?我們做了一套 ELK 的體系,就是基於 filebeat 去收集各個日誌,包括 TiDB 的 error log、 slow 日誌, PD + TiKV 的各種日誌。把這些日誌收集到 Kafka,其實在 ELK 裏,有 logstash 這個軟件,通過 lua 來解析日誌。但是對於 TiDB 的 slow log 來講,你需要讓某一類的 SQL 通過打水印的方式形成一條 SQL,來進行 slow log 的聚合,基於 lua 實現就比較麻煩了,我們自己寫了一套聚合的邏輯來存儲這些慢日誌。

2.2 資源隔離

穩定性建設還有一方面是關 於 資源隔離 。之 前我們做資源隔離的方式比較粗獷。爲什麼粗獷呢?因爲之前採用的方式就是一個大的 TiDB 集羣,各個業務線都在集羣裏創建 database 使用。如果資源隔離做不好的話,就會出現 db1 的請求影響到 db2,進而產生很多的問題。

之前的使用方式是大家都混用同一批 TiDB Server。導致的問題是一旦有一些業務使用了大的 SQL,佔資源比較大的一些 SQL,就會導致這個集羣的穩定性抖動。其實計算資源是可以做隔離的,分別創建不同業務的 tidb server 集羣來給不同業務使用,實現了 TiDB Server 這個計算側的隔離。

另外 TiDB 有各種的 SQL 抑制策略。比如說像 Max execution time (最大可執行時間),就是 DML、Select SQL 一旦超過時間片殺不留,這是一個紅線,是非常殘暴的一個方式。第二個就是設定 SQL 的一些 quota。你可以通過各種 SQL 的 quota 的設定,讓業務 SQL 使用的資源足夠小。另外,你還可以搞一些自動化的殺 SQL 的程序,在觸發最大可執行時間之前,殺掉你想殺的那些 SQL。類似於 pt-kill 的一些功能,就是殺什麼用戶的,殺什麼類型的 SQL。這些就是穩定性建設裏,非常細節的一些方面。

那在這種混用集羣的情況下,存儲測(TiKV)如何做資源隔離?第一種方式就是拆集羣,之前混用的集羣誰抖動影響別人的就把誰先拆出來,讓它自己一個集羣,儘量避免核心集羣受到影響。之前用得比較粗獷,所有的 S、A、B、 C 級別的業務級別混用,那就需要從部署規劃想辦法。每個 S 級都單獨給它搞一個集羣,一個大業務線的 A 級的集羣給它搞上三套。所有的 B、C 級以下的全都扔到一個老集羣裏邊隨便玩。這套方案涉及到大量 database 遷移,避免一個大集羣裏面有各種業務級別的數據庫存在。做完業務拆分後就可以做 SLA 的承諾了。

其實各個業務線都有自己的 SLO 的指標,我們 DBA 是要求 SLA 指標,比如我們承諾 99.95% 的可用性。這個 99.95% 的可用性只賦予 S 級別業務。其他非 S 級的,我只保證 99.9% 的可用性。這樣做了集羣拆分後,我就敢跟業務去做承諾了,就能夠保證自己的 SLA。這也是作爲 DBA 這個行業裏最核心的一個指標:穩定性是第一位的,哪怕其他事做得再漂亮,今年掛了 3 個 P0 的 DB,你的績效肯定不好。

3 天穹平臺

講完多雲多活和穩定性建設,再來說說知乎這兩年在做的一個平臺——天穹平臺。天穹平臺是用來幹什麼的?其實就是類似於 TiEM 加 TiDB dashboard,我們將它們整合了一下。這東西的好處是什麼呢?我們想通過這套平臺來管控整個 TiDB 的生命週期,把整個 TiDB 從創建到遷移,到日常運維,到下線的整個生命週期都放在一個平臺上,通過點點鼠標的方式來進行運維管控。

我們搞了這套東西,把它的源數據一收集,然後去做遷移,去做管控,切 leader,包括查看日誌、慢 SQL 報表、殺 SQL、監控、報警,所有東西非常全地整合到一個平臺裏。DBA 和業務都可以使用這個平臺,業務使用平臺可以創建集羣,可以查看集羣的 QPS。比如業務抖動了,看看是不是 TiDB 導致的,那就可以登到這個集羣裏面看看集羣監控。比如我們結合 FinOps ,業務看看 TiDB 的成本怎麼樣。現在大家都在降本增效,那麼你使用的庫表有沒有已經下線的大庫表?有沒有使用的資源超出自己預估?因爲我們是按 GB 去把資源的費用分攤給業務的,在平臺裏邊可以去調整他的資源的 quota,以及促使業務調整寫入策略等等。

甚至他在這個平臺裏還可以做一些日常的 oncall 工單,比如說在 Jenkins 裏邊提一個 oncall,讓 DBA 幫忙擴擴容,去做一些什麼操作,所有事情都在天穹平臺自助化處理,通過工單的方式層層審批,然後去執行好整個 TiDB 生命週期的管理。

數據庫發展之我見

這部分我會分享作爲 13 年數據庫從業者的一些想法。數據庫的發展在我看來可以從三點來講:

1 數據庫的產品力

數據庫的產品力就在於這個數據庫實現了哪些功能? 比如說 ACID 一致性、支持分佈式事務、支持多租戶、資源隔離等等,這些都屬於屬於產品力。

比如說之前 TiDB 一直在講的高性能、很絲滑的 Scale,這就是它的產品力。 產品力還有一點很重要是它的穩定性,最近其實 TiDB 在 feature 的迭代上更關注穩定性,在同一個 workload 的情況下,能夠保證足夠穩定。

所以,產品力就是你的產品實現了什麼功能,產品的穩定性怎麼樣,產品的性能怎麼樣,實現了什麼功能,這些都是你的產品力。 這是一個產品最基礎的東西,有了這個基礎後,別人才能夠認可你、能夠去用你。 除此之外,產品還需要一個開放完整的生態。

2 數據庫的生態

生態其實就是數據怎麼從另外一個 DATABASE 遷到 TiDB ,包括 DM 組件,包括最早的基於 mydumper、 myloader 搞的組件,以及 Lightning 等等。 這些工具我都用過,我可以根據不同的業務場景把這些工具靈活運用。 比如離線場景的數據遷移,我可以直接 dump 出來, 然後 load 進 TiDB。 比如這個業務是一個新的集羣,我可以直接 Lighting,直接用很底層的方式直接生成 KV 對,非常快速的直接往 TiDB 集羣裏導入,因爲是新的集羣,沒有負載,怎麼快怎麼來。

上面說的是遷移,作爲一個開源分佈式數據庫,數據既要進得來,也要出得去,不能說遷移進來之後,就被鎖住了,這對於喜歡開源 DB 的互聯網廠商來說是不可接受的。

那數據怎麼出去呢? 有兩種方式: 第一種是比較 早的 TiDB binlog : Dumper +Drainer,Dumper 去 TiDB Server 裏把數據傳出來後進行聚合,再通過 Drainer 的方式往下游送。 後來我們 基於 TiCDC 替換了 TiDB b inlog,通過 TiCDC 及時地將增量的數據變更導出去。

另外一個生態工具就是做備份 的 BR 。數據庫備 份是非常核心的工作,假如說你被刪庫了,但在 S3 或者在某個地方還能夠把某一個時刻的數據給救回來。在 TiDB 上,即使遇到刪庫跑路,只要我們設定了足夠的時間,有各種 Flashback 的一些能力,就能把數據及時地找回來。

還有監控工具。TiDB 基於 CNCF 的 Prometheus 和 Grafana 搞了一套監控體系,包括 TiDB dashboard,可以查看集羣 region 的一些情況,如熱力圖、拓撲圖以及一些要診斷的東西。

另外還有一些部署相關的工具,我經歷過 TiDB ansible 時代,也經歷過 tiup 時代,目前正在用 TiDB operator。這些東西都是歷史的長流,滔滔不絕。

最後還有一些平臺側的工具,比如說前面提到的天穹平臺,或者你們以後自己開發的 TiDB 運維管控平臺,這些都是數據庫的生態。

當然,還有一種生態叫做開發者生態,比如基於 TiKV 搞一套 JuiceFS,或者基於 TiKV 開發一套自己的 KV。這些都是數據庫生態,能讓數據進得來、管得住、出得去,一個數據庫只有生態足夠健全才能把整個數據庫玩轉。

3 數據庫的場景

場景就是這個數據庫解決了用戶什麼痛點。 之前 TiDB 一直在講自己的場景解決的是 MySQL 的分庫分表,這其實是一個很好的場景,因爲大廠或者中小廠裏都有這個痛點,只要能把這個痛點解決了,然後足夠穩定,再加上你的產品力和生態都足夠好,就可以很好地去解決數據庫落地這個問題。

後來 TiDB 又多了 HTAP 場景。 在我看來,OLTP 和 OLAP 其實是不分家的,只是各佔多少百分比。 舉個例子,我晚飯訂飯下了一單,商家的交易系統不就是一個 OLTP 需求嘛? 這個 OLTP 需求裏邊其實也有一些 OLAP 的需求。 商家需要知道在下單的近半個小時之內,哪個菜賣得最好。 商家有 10 個廚師,可能要通過實時的 OLAP 情況,分析出哪些菜賣得最好。 比如我讓這 10 個廚師做 10 種菜,把其他菜的廚師勻到這些賣得最好的菜上,這就是 OLAP 的實時決策價值。 這個過程可能在一個數據庫裏發生,也可能通過一些準實時的 ETL 的方式發生,但是 HTAP 在這些場景裏是有一定應用場景的。

除此之外,數據庫還有一些多租戶的場景。多租戶其實是解決我們現在混用集羣的最好利器,但是這個功能要在 7.x 才提供,我們現在還是 4.x 版本。

其他還有資源隔離、數據分佈、更便宜的存儲引擎等等。比如說數據分佈策略,我可以把日常經常訪問的最近最熱的數據放到 Nvme SSD 上,把一些冷數據放到 HDD 或者 S3 上。或者 QPS 在不太高的情況下,直接把 S3 當成一個存儲引擎去解決一些使用問題。

數據庫未來方向

第一個方向是 AI x DB 。我目前看得比較多的 一個場景就是如何基於 NLP 的這種語言處理能力,把自然語言轉化成 SQL。這能夠幫助一些不會寫 SQL 的產品和運營,想查看數據的時候,給他們帶來一絲絲的爽意 。

第二個方向就是 AIOps 。比如說我數據庫做了一些故障預警,想借助這些幾 G、幾十 G 的報警日誌,去發現集羣存在的問題,這些日誌包括 access 日誌、error、slow 日誌。比如 slow 日誌,我會根據 slow 日誌所對應的 table,對應的索引使用的合不合理,去給一些 SQL 建議。還比如說當數據庫出現故障的時候,AIOps 自動幫你去修復,讓它有一個自愈能力,這都是 AI x DB 的一些方 向。

第三個方向是數據庫的多模態和多 workload 。什麼叫多模態?數據庫底層都可以轉成 KV 去存。我們有關係型數據庫,還有圖數據庫,還有文檔數據庫,還有各種 KV 類型的數據庫。未來,能不能搞一些類似於 TiRedis、TiMongo、TiHbase 等等的數據庫?這些都是未來可以想象的東西,只要你把底層的存儲搞好,再把上層的計算層搞好,就可以實現了。另外一個方向就是多 workload,這就是現在 TiDB 在講的 TiDB Serverless,就是 pay as you use,你使用多少就付多少錢。

這些就是我認爲未來數據庫發展的一些方向,希望能夠給大家帶來一些啓迪。

最後一起來回顧一下 【一年一度北京線下新年圍爐茶會】 

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