秒換存儲引擎,又多了一種架構(gòu)方案?
精選作者 | 沈劍
在做業(yè)務(wù)架構(gòu)的過程中,你是否遇到過類似的痛點(diǎn)?
(1)數(shù)據(jù)量太大,容量復(fù)雜性上移到業(yè)務(wù)層;
(2)并發(fā)量太大,性能復(fù)雜性上移到業(yè)務(wù)層;
(3)前臺與后臺存儲異構(gòu),滿足不同查詢需求;
(4)線上與線下存儲異構(gòu),滿足大數(shù)據(jù)需求;
(5)存儲系統(tǒng)遷移成本高,不敢輕易做重構(gòu);
(6)...
職業(yè)生涯十五年,基本都在使用MySQL做線上業(yè)務(wù)的存儲。最近這幾年,遇到的問題慢慢多起來,嚴(yán)重影響了研發(fā)效率。TiDB近年甚火,于是最近做了一些調(diào)研,與大家分享。
如一貫風(fēng)格,更多的聊:TiDB究竟解決什么問題,以及為什么這么設(shè)計(jì),體現(xiàn)什么架構(gòu)思想。
問題的引出,MySQL體系結(jié)構(gòu)存在什么問題?
上面這幅MySQL體系結(jié)構(gòu)圖,相信很多人都見過:
- 上游:MySQL客戶端;
- 下游:MySQL服務(wù)端,又包含連接池,語法分析,語義分析,查詢優(yōu)化,緩沖池,存儲引擎,物理存儲,管理功能… 等諸多模塊;
畫外音:太復(fù)雜了,字都看不清了。
對MySQL體系結(jié)構(gòu)做了一個(gè)簡化:
如上圖所示:
- 上游:MySQL客戶端;
- 中間:通過MySQL協(xié)議通訊;
- 下游:MySQL服務(wù)端;
畫外音:對不起,忍一下我畫的丑圖。
核心的服務(wù)端,又主要分為兩層:
- 一層,計(jì)算層;
- 一層,存儲層;
MySQL如此這般,存在什么天然的問題?
【1】計(jì)算與存儲天然耦合。
計(jì)算層和存儲層,既然都在一個(gè)MySQL進(jìn)程里,所有的CPU資源,內(nèi)存資源都是共享的,勢必存在資源爭搶的耦合。
除了天生的不足,在數(shù)據(jù)量大,并發(fā)量大的典型互聯(lián)網(wǎng)業(yè)務(wù)場景里,對于MySQL的使用,還有哪些痛點(diǎn)呢?
我們都知道,當(dāng)讀寫量增加的時(shí)候,通常會對MySQL做主從分組集群:
如上圖所示:主從同步,讀寫分離,通過線性增加從庫來線性擴(kuò)展系統(tǒng)的讀性能。
畫外音:大部分業(yè)務(wù),讀容易成為主要矛盾。
我們也知道,當(dāng)存儲容量增加的時(shí)候,通常會對MySQL做水平切分集群:
如上圖所示:用一個(gè)鍵值進(jìn)行數(shù)據(jù)分片,以實(shí)現(xiàn)更大的存儲容量。
所以,實(shí)際上線上的MySQL集群是這樣的:
- 既有水平切分,多個(gè)分片;
- 又有主從分組,每個(gè)分片有一個(gè)主從集群;
而分片和分組,都是調(diào)用方微服務(wù)需要關(guān)注的,這就引出了下一個(gè)痛點(diǎn):
【2】調(diào)用方需要關(guān)注存儲細(xì)節(jié),底層存儲的復(fù)雜性轉(zhuǎn)移到了上層應(yīng)用。
另外,除了在線應(yīng)用,絕大部分互聯(lián)網(wǎng)公司都有各類大數(shù)據(jù)處理的需求:
- 離線分析:例如,經(jīng)營日報(bào);
- 在線分析:例如,分析師取數(shù);
- 實(shí)時(shí)處理:例如,實(shí)時(shí)報(bào)表;
為了滿足這類需求,又需要將MySQL中的數(shù)據(jù)同步到各類大數(shù)據(jù)體系的集群中:
用一系列大數(shù)據(jù)的技術(shù)體系,去解決各類大數(shù)據(jù)處理的需求。
這就引出了另一個(gè)痛點(diǎn):
【3】技術(shù)側(cè)需要關(guān)注數(shù)據(jù)同步,數(shù)據(jù)一致性,大數(shù)據(jù)集群的復(fù)雜性。
當(dāng)然,很多技術(shù)管理者也會調(diào)研各類替代產(chǎn)品,以解決上述1-3的問題,例如NoSQL的代表之一MongoDB,無奈【4】升級遷移需要大量的系統(tǒng)改造,綜合評估之后,往往不得不放棄遷移方案,繼續(xù)忍受MySQL帶來的各種問題。
歷史的痛點(diǎn),往往是創(chuàng)新的機(jī)會。
TiDB,它來了!
TiDB是如何設(shè)計(jì),以解決:
(1) 計(jì)算與存儲耦合;
(2) 存儲底層的復(fù)雜性轉(zhuǎn)移;
(3) 大數(shù)據(jù)體系復(fù)雜性轉(zhuǎn)移;
(4) 系統(tǒng)遷移成本高;
等問題的呢?
首先,TiDB在誕生之初,就確定了:
- 復(fù)用MySQL協(xié)議;
- 計(jì)算與存儲分離;
的設(shè)計(jì)大方向。
如上圖所示:
- 上游:不需要做任何改動,可以使用MySQL的各類driver,訪問TiDB;
- 中間:通過MySQL協(xié)議通訊;
- 下游:將計(jì)算層與存儲層拆分到兩個(gè)進(jìn)程里,解除資源爭搶的耦合,而這兩層的通訊則使用內(nèi)部協(xié)議,對調(diào)用方透明;
如此一來,難題 (1) 和 (4) 就得到了解決。
如何解決讀寫量擴(kuò)展,存儲量擴(kuò)展等“底層復(fù)雜性轉(zhuǎn)移”等問題呢?
對于計(jì)算層,實(shí)現(xiàn)連接池,語法分析,語義分析,查詢優(yōu)化等模塊,做到無狀態(tài),并通過集群的方式擴(kuò)展,這就是TiDB體系結(jié)構(gòu)中的“計(jì)算引擎tidb-server”集群。對于調(diào)用方,接入層TiDB集群就是入口,其背后的復(fù)雜性對上游不可見。上圖中,簡記為【接入層(計(jì)算層)】。
畫外音:微服務(wù)架構(gòu)中,站點(diǎn)應(yīng)用和微服務(wù)層也必須無狀態(tài)化,以實(shí)現(xiàn)輕易的集群擴(kuò)展,也是一個(gè)道理。
對于存儲層,實(shí)現(xiàn)一致性算法,分布式事務(wù),MVCC并發(fā)控制,算子下推等模塊,實(shí)現(xiàn)原子KV存儲,也能通過集群的方式自動擴(kuò)展,這就是TiDB體系結(jié)構(gòu)中的“存儲引擎TiKV-server” 集群。上圖中,簡記為【存儲層】。
畫外音:這與GFS中的chunk-server很像,有了它,不再需要手動水平切分?jǐn)U容了。
除此之外,需要一個(gè)擁有全局視野,實(shí)現(xiàn)元數(shù)據(jù)存儲,ID分配(key-id,事務(wù)ID),時(shí)間戳生成,心跳檢測,集群信息收集等模塊的master,這就是TiDB體系結(jié)構(gòu)中的“PD-server”集群。上圖中,簡記為【管理層】。
畫外音:這與GFS中的master-server很像。
如此一來,難題 (2) 存儲底層讀寫容量與存儲容量的復(fù)雜性轉(zhuǎn)移問題,也得到了解決。
大數(shù)據(jù)體系的復(fù)雜性,TiDB也將其屏蔽在了內(nèi)部:
- 擴(kuò)展接入層,讓大數(shù)據(jù)有獨(dú)立的接入,如上圖中的TiSpark;
- 擴(kuò)展存儲層,匹配以適合大數(shù)據(jù)的存儲,如上圖中的TiFlash;
畫外音:TiKV和TiFlash分別獨(dú)立存儲,且進(jìn)行異步數(shù)據(jù)同步,彼此解耦。
- 擴(kuò)展管理層,同時(shí)管理大數(shù)據(jù)的部分;
如此一來,難題 (3) 大數(shù)據(jù)數(shù)據(jù)同步,數(shù)據(jù)一致性,大數(shù)據(jù)集群的復(fù)雜性的問題,也得到了解決。
TiDB的架構(gòu),無處不體現(xiàn)著這樣的設(shè)計(jì)原則:使用者簡單易用,復(fù)雜麻煩的地方,都屏蔽到TiDB的內(nèi)部。
回到開篇,如果你也正經(jīng)歷著類似的痛點(diǎn)?
- 數(shù)據(jù)量太大,容量復(fù)雜性上移到業(yè)務(wù)層;
- 并發(fā)量太大,性能復(fù)雜性上移到業(yè)務(wù)層;
- 前臺與后臺存儲異構(gòu);
- 線上與線下存儲異構(gòu);
- 存儲系統(tǒng)遷移成本高;
- ...
不妨,試一試TiDB。
最后一個(gè)問題,業(yè)務(wù)架構(gòu)如何快速遷移至TiDB呢?
從MySQL到TiDB的遷移過程也非常平滑:
(1) 第一步,保持服務(wù)讀寫原有MySQL集群;
(2) 第二步,將原有MySQL集群中的數(shù)據(jù),同步到TiDB;
畫外音:TiDB的工具集很全,本文沒有擴(kuò)展介紹。
(3) 第三步,服務(wù)流量切換至TiDB;
畫外音:由于保持MySQL協(xié)議,業(yè)務(wù)代碼幾乎不用修改,這是TiDB能夠成功很重要的一個(gè)原因。
今天聊了聊TiDB體系結(jié)構(gòu)的宏觀設(shè)計(jì)原則,希望大家有收獲。如果對TiDB的內(nèi)核感興趣,未來可以和大家聊聊它的實(shí)現(xiàn)細(xì)節(jié)。
畫外音:大家感興趣嗎?
源碼:https://github.com/pingcap/tidb