隨著業(yè)務(wù)高速增長屁柏、數(shù)據(jù)量逐步增多躺孝,單實(shí)例、單庫就乓、單表出現(xiàn)性能瓶頸和存儲瓶頸泉懦。從選型和架構(gòu)設(shè)計(jì)角度來看這很符合發(fā)展規(guī)律,一開始沒必要引入過于復(fù)雜的架構(gòu)導(dǎo)致資源成本和開發(fā)成本過高疹瘦,而是逐步隨著業(yè)務(wù)發(fā)展速度去迭代架構(gòu)崩哩。為了應(yīng)對這些問題,我們采取了諸多措施如單庫按業(yè)務(wù)邏輯拆分成多個(gè)庫的垂直拆分言沐,分庫分表的水平拆分邓嘹、一主多從讀寫分離等。這些技改同時(shí)也使得整個(gè)業(yè)務(wù)層架構(gòu)更加復(fù)雜险胰,且無法做到透明的彈性汹押,因此我們逐步把目光轉(zhuǎn)向了已經(jīng)趨于成熟的分布式關(guān)系型數(shù)據(jù)庫 TiDB。
自 2020 年初開始使用 TiDB起便,隨著運(yùn)維體系的逐步完善棚贾,產(chǎn)品自身能力的逐步提升,接入業(yè)務(wù)已經(jīng)涉及得物的多個(gè) 業(yè)務(wù)線榆综,其中個(gè)別為關(guān)鍵業(yè)務(wù)場景妙痹。業(yè)界關(guān)于 TiDB 的功能剖析、場景落地鼻疮、平臺化建設(shè)都有很多優(yōu)秀的文章怯伊。本文基于得物內(nèi)部的實(shí)踐情況,會從選型策略判沟、運(yùn)維手段耿芹、運(yùn)營方式、核心場景實(shí)踐等幾個(gè)方向講述TiDB 在得物實(shí)踐落地過程挪哄。
2. TiDB 架構(gòu)
上圖是我們目前的接入方式和整體架構(gòu)吧秕。TiDB 的部署架構(gòu)這里就不做贅述了,需要了解的同學(xué)可以參考官方文檔中燥。我們之所以采用 SLB 來做 TiDB 的負(fù)載均衡接入寇甸,就是為了簡化接入成本與運(yùn)維成本,訪問流量的負(fù)載均衡以及節(jié)點(diǎn)擴(kuò)縮容可以通過調(diào)整 SLB 解決疗涉。當(dāng)然如果能夠?qū)崿F(xiàn) SDK 負(fù)載均衡與故障剔除拿霉,結(jié)合配置中心的流量調(diào)度也是非常好的解決方案。得物 TiDB 部署均采用單機(jī)單實(shí)例部署咱扣,TiDB Server绽淘、PD 采用無本地 SSD 機(jī)型,TiKV 采用本地 SSD 機(jī)型闹伪。既兼顧了性能沪铭,又能降低成本壮池。詳細(xì)的機(jī)型選擇會在后面的內(nèi)容提到。
3. MySQL 與 TiDB 的對比
圈內(nèi)一直流傳著一句話杀怠,沒有一種數(shù)據(jù)庫是"銀彈"椰憋。絕大部分用戶選擇 TiDB 就是為了彌補(bǔ) MySQL 的不足,所以選型階段對兩者做些比較也是在所難免的赔退。本文基于我們內(nèi)部的現(xiàn)狀和場景對兩個(gè)產(chǎn)品我們關(guān)注的點(diǎn)進(jìn)行了簡要對比橙依。對比的目的不是為了去印證那個(gè)數(shù)據(jù)庫產(chǎn)品能力更強(qiáng)。而是想通過對比來幫助團(tuán)隊(duì)在合適的場景選擇合適的產(chǎn)品硕旗。
擴(kuò)展性
MySQL
MySQL 就自身擴(kuò)展能力而言主要是來自于垂直擴(kuò)容窗骑,但是這個(gè)會受限于機(jī)器的規(guī)格上限。水平擴(kuò)容涉及業(yè)務(wù)改造和使用成本提升漆枚。改造為分庫分表创译,對研發(fā)來說是一個(gè)費(fèi)力度很高的方案。需要引入 Sharding 邏輯墙基,改造完成后需要業(yè)務(wù) SQL 必須帶 Sharding Key 才能執(zhí)行或者高效執(zhí)行软族。所以并不是說做不到可擴(kuò)展。
TiDB
由于 TiDB 是計(jì)算存儲分離的架構(gòu)碘橘,且有狀態(tài)的存儲層 TiKV 是分布式存儲互订。所以單從上面定義的擴(kuò)展性來說,確實(shí)對比 MySQL 有很大優(yōu)勢痘拆。集群處理能力和存儲能力仰禽,可以通過擴(kuò)容 TiDB Server、TiKV 簡單實(shí)現(xiàn)纺蛆。這里需要注意的是吐葵,TiKV 屬于有狀態(tài)服務(wù),擴(kuò)容會涉及到數(shù)據(jù)的 Reblance桥氏,過程中 TiKV(region 遷移) 和 PD(調(diào)度) 產(chǎn)生大量交互温峭,為避免影響業(yè)務(wù),擴(kuò)縮容過程中需要關(guān)注集群情況字支,根據(jù)需求適當(dāng)調(diào)整遷移力度凤藏。
性能
MySQL
關(guān)于 RT。MySQL 由于是單機(jī)數(shù)據(jù)庫堕伪,所以對于點(diǎn)查或簡單查詢的 RT揖庄、熱點(diǎn)更新的 RT 與 TPS ,相比分布式數(shù)據(jù)庫有天然優(yōu)勢欠雌。數(shù)據(jù)獲取鏈路短(單機(jī)數(shù)據(jù)庫本地調(diào)用蹄梢,分布式數(shù)據(jù)庫涉及存算分離),且不用考慮分布式事務(wù)的沖突檢測富俄。所以總體的訪問 RT 要低于 TiDB禁炒,具體數(shù)據(jù)這邊就不羅列了而咆,社區(qū)有不少性能壓測的帖子。
關(guān)于聚合查詢幕袱”┍福互聯(lián)網(wǎng)公司在 C 端基本不存在此類問題,也是不允許的们豌。所以主要是場景在 B 端馍驯。解決方法一般是分為幾種:1.提供專門的只讀實(shí)例給 B 端提供查詢能力;2.異構(gòu)數(shù)據(jù)來解決(MySQL+ES玛痊、ADB 等等)。
關(guān)于優(yōu)化器狂打。MySQL 多年的積累擂煞,在優(yōu)化器的穩(wěn)定性雖然不如商用數(shù)據(jù)庫那么可靠,偶爾也有走錯索引的情況趴乡。一般只能通過修改 SQL对省、修改索引來解決,切記別用 force index 這種有坑的解決方案晾捏。但是總體來說我們遇到的 MySQL 走錯索引的情況要遠(yuǎn)低于 TiDB蒿涎。
TiDB
關(guān)于 RT。分布式數(shù)據(jù)庫解決的更多是吞吐量和容量上的需求惦辛,比如點(diǎn)查或簡單查詢的 RT 無法像單機(jī)數(shù)據(jù)庫那么短劳秋,但是可以通過節(jié)點(diǎn)擴(kuò)容的方式提升 QPS 吞吐量。熱點(diǎn)數(shù)據(jù)這里就不展開講了胖齐,它本身也不是分布式數(shù)據(jù)庫能解決的范疇玻淑。如果你的業(yè)務(wù)場景是一個(gè)對 RT 要求很高的場景,那么優(yōu)先使用 MySQL呀伙。如果是高吞吐量需求優(yōu)先补履,可以嘗試使用 TiDB。
關(guān)于聚合查詢剿另。由于 TiDB 的存儲節(jié)點(diǎn) TiKV 不只是具備存儲能力箫锤,TiKV 實(shí)現(xiàn)了coprocessor 框架來支持分布式計(jì)算的能力。所以理論上通過加機(jī)器就能擴(kuò)展計(jì)算能力雨女,從我們實(shí)際使用的場景來看也是如此谚攒,這部分的能力就要優(yōu)于 MySQL。具體的效果在本文最后的章節(jié)會有體現(xiàn)戚篙。
關(guān)于優(yōu)化器五鲫。這個(gè)是大家對 TiDB 一直以來吐槽的點(diǎn)之一,有時(shí)候統(tǒng)計(jì)信息健康度 90 以上的情況下岔擂,還是會走錯索引位喂,當(dāng)然這里有一部分原因可能是條件過多和索引過多導(dǎo)致的浪耘。為了解決問題,核心服務(wù)上線的 SQL 就必須一一 Review塑崖。如果無法正確使用索引的就使用 SPM 綁定七冲,雖然能解決,但是使用成本還是略高规婆。希望官方繼續(xù)加油澜躺。
資源成本
MySQL
如果是一個(gè)數(shù)據(jù)量小且查詢模型比較簡單的需求(比如:1-2TB,簡單查詢?yōu)橹?抒蚜,那么肯定是 MySQL 成本較低掘鄙。以我們 TiDB 基礎(chǔ)配置為例,相比 MySQL 成本高出 27%(該成本是用高可用的 MySQL 對標(biāo)3 TiDB嗡髓、3 TiKV操漠、3 PD 的 TiDB)。所以得物內(nèi)部選型饿这,單從資源成本角度考慮浊伙,還是首選 MySQL。
TiDB如果是一個(gè)數(shù)據(jù)量較大且持續(xù)增長或查詢模型比較復(fù)雜的需求(比如:3-5 TB 以上长捧,多條件查詢嚣鄙、聚合查詢等)。一般該類型的業(yè)務(wù)都采用分庫分表的解決方案串结。以得物一個(gè)分庫分表的集群(10個(gè)寫實(shí)例哑子、10個(gè)讀實(shí)例)為例,替換為 TiDB(6 TiDB肌割、12 TiKV赵抢、3 PD),成本相比 MySQL 成本節(jié)省 58%声功。此例子只作為得物一個(gè)業(yè)務(wù)場景的替換結(jié)果烦却,不代表所有場景。為了驗(yàn)證這個(gè)結(jié)論先巴,本文后面的內(nèi)容會講到這個(gè)核心場景的實(shí)踐其爵。
運(yùn)維成本
MySQL
MySQL 作為被使用最多的開源關(guān)系型數(shù)據(jù)庫,從社區(qū)活躍度伸蚯、產(chǎn)品成熟度摩渺、周邊生態(tài)工具、解決方案積累等方面來看都是非常優(yōu)先的產(chǎn)品剂邮。主從架構(gòu)的 MySQL 維護(hù)成本極低摇幻,當(dāng)主庫異常或無法修復(fù)時(shí),我們只需要切換即可绰姻。
另外得益于優(yōu)秀的社區(qū)生態(tài)枉侧,運(yùn)維工具、數(shù)據(jù)庫接入組件狂芋、數(shù)據(jù)同步組件都有非常多的成熟工具榨馁,稍加改造就可以實(shí)現(xiàn)本地化適配。
TiDB
分布式的架構(gòu)的設(shè)計(jì)沒有像 MySQL 這樣的主從帜矾,每個(gè)存儲節(jié)點(diǎn)都是提供讀寫翼虫。當(dāng)一個(gè)節(jié)點(diǎn)出問題的時(shí)候,會影響整個(gè)集群的訪問屡萤。無法實(shí)現(xiàn) MySQL 這樣通過主從切換實(shí)現(xiàn)快速的故障隔離珍剑。?
?https://www.xiaohongshu.com/discovery/item/63189ac1000000001103426a
?https://www.xiaohongshu.com/discovery/item/63161bdf0000000011013a26
?https://www.xiaohongshu.com/discovery/item/6314c2ad0000000008021a71
?https://www.xiaohongshu.com/discovery/item/6314c07a00000000120098b5
TiDB 由 3 個(gè)角色組成,當(dāng)出現(xiàn)問題的時(shí)候無法快速定位問題(當(dāng)然也是我們個(gè)人能力需要提升的點(diǎn))死陆,比如當(dāng)某個(gè)時(shí)間點(diǎn)的查詢超過預(yù)期的時(shí)候次慢,需要排查執(zhí)行計(jì)劃、各個(gè)節(jié)點(diǎn)的負(fù)載情況翔曲、各節(jié)點(diǎn)的網(wǎng)絡(luò)情況。雖然提供了完善的監(jiān)控劈愚,但是指標(biāo)與節(jié)點(diǎn)過多需要一一排查才能有結(jié)論瞳遍。不像 MySQL 出現(xiàn)查詢超預(yù)期的問題,基本上通過幾個(gè)核心指標(biāo)就能判斷出根因菌羽。