說重點(diǎn)
公司用了TiDBv4.0有一段時(shí)間了,業(yè)務(wù)上也多了另一種優(yōu)化選擇,今天找個(gè)時(shí)間,對照官網(wǎng)和一些架構(gòu)設(shè)計(jì)及文稿綜合一下,總結(jié)下自己對TiFlash的整體看法
TiDB-v4.0引入了TiFlash,架構(gòu)圖官網(wǎng)給出如下,簡而言之有以下特點(diǎn):
- 列存擴(kuò)展:通過raft learner的復(fù)制協(xié)議,配合MVCC獲取快照隔離級(jí)別,解決隔離性和列存同步問題
-?借助 ClickHouse 高效實(shí)現(xiàn)的協(xié)處理器層
- 與TiKV一樣,有region的單位,合并和分割
在我看來,以此實(shí)現(xiàn)的比較重要的三點(diǎn):
1.實(shí)時(shí)更新的列存
2.Multi-Raft的復(fù)制體系
3.根據(jù)代價(jià)的智能選擇

1.TP和AP的存儲(chǔ)格式
TP和AP對應(yīng)的是行存和列存,然而這點(diǎn)在內(nèi)存中體現(xiàn)差異并不大.由此引出SAP Hana的作者Plattner使用 In Memory + 列存技術(shù) 同時(shí)處理OLTP和OLAP,2014年Gartner提出的HTAP概念,也是針對內(nèi)存進(jìn)行計(jì)算設(shè)計(jì).
關(guān)鍵點(diǎn)問題:列存不適合TP類場景,這是個(gè)common sense,但是不是所有人都知道Why?
數(shù)據(jù)快速訪問需要仰賴 Locality,簡單說就是根據(jù)訪問模式,要讀寫的數(shù)據(jù)盡量放在一起。并不在一起的數(shù)據(jù)需要額外的 Seek 并且 Cache 效率更低。
行存和列存,去除 encoding 和壓縮這些因素,本質(zhì)上是針對不同的訪問模式提供了不同的數(shù)據(jù) Locality。行存一次訪問一整行數(shù)據(jù)就會(huì)得到很好的速度;列存將同一列的數(shù)據(jù)放在一起,那么每次只獲取一部分列的讀取就會(huì)得到加速;另一方面,列存在傳統(tǒng)印象里更新很慢也部分是因?yàn)槿绻褂?Naive 的方式去將一行拆開成多列寫入到應(yīng)有的位置,將帶來災(zāi)難性的寫入速度。這些效應(yīng)在磁盤上很明顯,但是在內(nèi)存中就會(huì)得以削弱,因此這些年以來我們提起 HTAP,首先想到的是內(nèi)存數(shù)據(jù)庫。
但是內(nèi)存畢竟成本較高,暫時(shí)只能在特殊領(lǐng)域得到硬要,所以,HTAP的設(shè)計(jì)突破口還在磁盤而非內(nèi)存.但是譬如PAX格式,是在同一個(gè)存儲(chǔ)引擎中通過算法去柔TP和AP,但始終突破不了Locality,在優(yōu)秀的架構(gòu)設(shè)計(jì)也很難逼近兩側(cè)最優(yōu)解,實(shí)際場景實(shí)現(xiàn)更會(huì)復(fù)雜數(shù)據(jù).
TiDB以HTAP為宣傳理念,知道PAX的坑,那么怎么繞過去? --用模塊化解決問題
模塊化的思想貫穿TiDB設(shè)計(jì)理念始終,TiDB,PD和TiKV的分層模塊切割都表現(xiàn)了這種架構(gòu)設(shè)計(jì)思路.TiDB拿出的答案是,通過Raft 剝離/柔和 行存和列存 ,把難以實(shí)現(xiàn)的突破口通過解耦合的方式避免在一個(gè)存儲(chǔ)引擎中解耦合,這也跟Raft根據(jù)Paxos實(shí)現(xiàn)的簡化思想大道同路.這樣一是減少了產(chǎn)品開發(fā)周期,二是引進(jìn)了列存(ClickHouse),把行存和列存放在兩個(gè)盒子里,分而治之.
2.如何實(shí)現(xiàn)列存的數(shù)據(jù)更新和實(shí)時(shí)同步速度
TiDB有了松耦合設(shè)計(jì)和ClickHose+TiKV,怎么實(shí)現(xiàn)TP和AP根據(jù)主鍵的實(shí)時(shí)同步?--Delta Main
傳統(tǒng)的Hadoop等通過大量覆蓋和去重達(dá)到列存更新的目的,但是時(shí)間消耗為T+1,拋棄實(shí)時(shí)更新獲取批量告訴加載.HTAP的目標(biāo),必須要保證列存的更新速度和行存一樣快,才能實(shí)時(shí)更新.
TiDB采取了業(yè)界通過的做法 Delta Main,通過寫優(yōu)化方式存儲(chǔ)變更數(shù)據(jù),逐步將更新部分歸并到讀優(yōu)化的主列存去,保證歸并速率,這樣數(shù)據(jù)大部分就能使在讀優(yōu)化區(qū)使用進(jìn)而保持性能.簡而言之就是 寫按照寫入順序而非主鍵順序排序,大大提高寫的速度,讀按照 Row-Group 按列切割,并排序后壓縮.C-Store作為列存的鼻祖,就是這種設(shè)計(jì)的一種實(shí)現(xiàn).以下是設(shè)計(jì)架構(gòu)圖

TiDB的列存引擎TiFlash-用DeltaTree實(shí)現(xiàn)思路:
?- 分成Delta space(優(yōu)化寫入) 和 Stable Space(優(yōu)化讀取)兩個(gè)空間,宏觀上降DeltaTree將數(shù)據(jù)切分,類似Region的概念,每個(gè)數(shù)據(jù)范圍行為一個(gè)片段,每個(gè)片段都有Delta space和Stable space.這樣在歸并是無序重寫所有數(shù)據(jù),減輕壓力
-? Delta space:按照寫入順序不斷追加數(shù)據(jù),等達(dá)到閾值則歸并到 Stable區(qū),輔以內(nèi)存中B+Tree索引,這樣雖然物理有序保證不了(以為會(huì)大大降低排序速度),但邏輯有序是可以保證的,免去歸并前排序代價(jià).
-?Stable Space:切分?jǐn)?shù)據(jù),排序后歸并壓縮存儲(chǔ).利用已經(jīng)邏輯有序的數(shù)據(jù)塊,對于正在讀取但仍未歸并到Stable Space的數(shù)據(jù),進(jìn)行在線歸并.
到此,解決了列存更新問題
3.從行存-->復(fù)制到列存的實(shí)現(xiàn)
松耦合的存儲(chǔ)引擎,行存列存不再一個(gè)模塊內(nèi),就要實(shí)現(xiàn)從行存中復(fù)制數(shù)據(jù)到列存.傳統(tǒng)的主從復(fù)制,如Mysql利用binlog這樣的 高層級(jí)復(fù)制,可以封裝細(xì)節(jié),回放binlog日志即可,但是重大問題會(huì)把TiDB這樣一個(gè)分布式系統(tǒng)變成因?yàn)閎inlog的匯聚和排序降維打擊成單點(diǎn)系統(tǒng).
于是利用 low level的日志復(fù)制,在raft從仍進(jìn)行數(shù)據(jù)復(fù)制,raft log細(xì)節(jié),TiFlash被設(shè)計(jì)成一種特殊的TiKV節(jié)點(diǎn),享受Multi-Raft體系的遍歷,跟TiKV一樣將很多擴(kuò)容,容錯(cuò)等細(xì)節(jié)都交給PD處理.當(dāng)然也是經(jīng)過開發(fā)人員的巨大努力實(shí)現(xiàn).
于是有了TiFlash,對比主從復(fù)制和統(tǒng)計(jì)器行列雙寫,AP和TP部分完全獨(dú)立運(yùn)行,擴(kuò)容.需要AP則增加TiFlash節(jié)點(diǎn),需要TP增加TiKV節(jié)點(diǎn).兩者互不干擾.
同時(shí)Region Leader的額副本單獨(dú)與列存?zhèn)鹊母北具M(jìn)行溝通,無序中間存儲(chǔ)介質(zhì),Region分裂則列存副本分裂,TiKV熱點(diǎn)打散遷移,列存遷移.得益于TiDB的Multi-Raft體系.

傳統(tǒng)意義,如果副本一直,則要同步復(fù)制,這樣分布式環(huán)境上,網(wǎng)絡(luò)延遲和列存節(jié)點(diǎn)高壓,都會(huì)對TP業(yè)務(wù)造成沖擊,為了保證數(shù)據(jù)一致性,列存必須更新完按在返回.而Raft解決了這個(gè)問題,TiFlash通過Learner角色介入Raft體系,不投票不候選,只異步同步Log的方式加入集群,這樣不會(huì)影響TP的業(yè)務(wù),TiKV無序等待TiFlash的數(shù)據(jù)同步,完成正常的行存副本容錯(cuò)復(fù)制就可以返回事務(wù).
那么問題來了,行存和列存間的數(shù)據(jù)一致性怎么保證?
TiDBv4.0在這點(diǎn)上選擇了一種一致的邏輯讀取結(jié)果,放棄時(shí)刻的數(shù)據(jù)上物理一致.即保證最終讀取得到最新的一致性數(shù)據(jù).當(dāng)讀取發(fā)生,列存向行存發(fā)起校對請求,得到收到請求順序的日志序號(hào),TiFlash等待數(shù)據(jù)復(fù)制進(jìn)度追上校對結(jié)果,這樣TiKV寫入最新數(shù)據(jù)保證能從TiFlash上讀取,配合時(shí)間戳和MVCC,提供和TiKV一樣的強(qiáng)一致保證,放心大膽的在一個(gè)查詢中混合兩種存儲(chǔ)引擎

4智能選擇
TiFlash默認(rèn)策略CBO,根據(jù)代價(jià)優(yōu)化自動(dòng)選擇行存或者列存.技術(shù)上來說并無太多新意.從實(shí)際體驗(yàn),TiDBv4.0通過這種巧勁完成了傳統(tǒng)的TP+報(bào)表擴(kuò)展到HTAP業(yè)務(wù).AP和TP邊界模糊了起來.一個(gè)業(yè)務(wù)里既能得到行存的集體信息,也能計(jì)算出想要的報(bào)表數(shù)據(jù),雖然需要大量的資源就是了.
最后,放上官網(wǎng)的部署網(wǎng)址,https://docs.pingcap.com/zh/tidb/stable/use-tiflash
```
ALTER TABLE table_name SET TIFLASH REPLICA count
```