分布式數(shù)據(jù)庫TiDB解讀
點(diǎn)擊上方“IT那活兒”公眾號,關(guān)注后了解更多內(nèi)容,不管IT什么活兒,干就完了?。。?/strong>
TiDB 是 PingCAP 公司設(shè)計(jì)的開源分布式數(shù)據(jù)庫,結(jié)合了傳統(tǒng)的 RDBMS 和 NoSQL 的特性。
TiDB 高度兼容 MySQL,支持無限的水平擴(kuò)展,具備強(qiáng)一致性和高可用性。
TIDB具備一整套完整的生態(tài)環(huán)境,從數(shù)據(jù)遷移,備份恢復(fù),數(shù)據(jù)同步,監(jiān)控告警,HTAP,大數(shù)據(jù),運(yùn)維工具等。大多數(shù)情況下,無需修改代碼即可從 MySQL 輕松遷移至 TiDB,分庫分表后的 MySQL 集群亦可通過 TiDB 工具進(jìn)行實(shí)時(shí)遷移。
通過簡單地增加新節(jié)點(diǎn)即可實(shí)現(xiàn) TiDB 的水平擴(kuò)展,按需擴(kuò)展吞吐或存儲,輕松應(yīng)對高并發(fā)、海量數(shù)據(jù)場景。
TiDB 100% 支持標(biāo)準(zhǔn)的 ACID 事務(wù)。
相比于傳統(tǒng)主從 (M-S) 復(fù)制方案,基于 Raft 的多數(shù)派選舉協(xié)議可以提供金融級的 100% 數(shù)據(jù)強(qiáng)一致性保證,且在不丟失大多數(shù)副本的前提下,可以實(shí)現(xiàn)故障的自動(dòng)恢復(fù) (auto-failover),無需人工介入。
TiDB 作為典型的 OLTP 行存數(shù)據(jù)庫,同時(shí)兼具強(qiáng)大的 OLAP 性能,配合 TiSpark,可提供一站式 HTAP 解決方案,一份存儲同時(shí)處理 OLTP & OLAP,無需傳統(tǒng)繁瑣的 ETL 過程。
- TiDB 是為云而設(shè)計(jì)的數(shù)據(jù)庫,同 Kubernetes 深度耦合,支持公有云、私有云和混合云,使部署、配置和維護(hù)變得十分簡單。
Placement Driver (簡稱 PD) 是整個(gè)集群的管理模塊,其主要工作有三個(gè):
- a: 存儲集群的元信息(某個(gè) Key 存儲在哪個(gè) TiKV 節(jié)點(diǎn));
- b: 對 TiKV 集群進(jìn)行調(diào)度和負(fù)載均衡(如數(shù)據(jù)的遷移、Raft group leader 的遷移等);
PD 不斷的通過 Store 或者 Leader 的心跳包收集信息,獲得整個(gè)集群的詳細(xì)數(shù)據(jù),并且根據(jù)這些信息以及調(diào)度策略生成調(diào)度操作序列,每次收到 Region Leader 發(fā)來的心跳包時(shí),PD 都會(huì)檢查是否有對這個(gè) Region 待進(jìn)行的操作,通過心跳包的回復(fù)消息,將需要進(jìn)行的操作返回給 Region Leader,并在后面的心跳包中監(jiān)測執(zhí)行結(jié)果。這里的操作只是給 Region Leader 的建議,并不保證一定能得到執(zhí)行,具體是否會(huì)執(zhí)行以及什么時(shí)候執(zhí)行,由 Region Leader 自己根據(jù)當(dāng)前自身狀態(tài)來定。調(diào)度依賴于整個(gè)集群信息的收集,需要知道每個(gè)TiKV節(jié)點(diǎn)的狀態(tài)以及每個(gè)Region的狀態(tài)。TiKV集群會(huì)向PD匯報(bào)兩類信息:1)每個(gè)TiKV節(jié)點(diǎn)會(huì)定期向PD匯報(bào)節(jié)點(diǎn)的整體信息。TiKV節(jié)點(diǎn)(Store)與PD之間存在心跳包,一方面PD通過心跳包檢測每個(gè)Store是否存活,以及是否有新加入的Store;另一方面,心跳包中也會(huì)攜帶這個(gè)Store的狀態(tài)信息,主要包括: e) 發(fā)送/接受的Snapshot數(shù)量(Replica之間可能會(huì)通過Snapshot同步數(shù)據(jù)) g) 標(biāo)簽信息(標(biāo)簽是否具備層級關(guān)系的一系列Tag)2)每個(gè) Raft Group 的 Leader 會(huì)定期向 PD 匯報(bào)Region信息每個(gè)Raft Group 的 Leader 和 PD 之間存在心跳包,用于匯報(bào)這個(gè)Region的狀態(tài),主要包括下面幾點(diǎn)信息:
c) 掉線Replica的個(gè)數(shù);PD 不斷的通過這兩類心跳消息收集整個(gè)集群的信息,再以這些信息作為決策的依據(jù)。
除此之外,PD 還可以通過管理接口接受額外的信息,用來做更準(zhǔn)確的決策。比如當(dāng)某個(gè) Store 的心跳包中斷的時(shí)候,PD 并不能判斷這個(gè)節(jié)點(diǎn)是臨時(shí)失效還是永久失效,只能經(jīng)過一段時(shí)間的等待(默認(rèn)是 30 分鐘),如果一直沒有心跳包,就認(rèn)為是 Store 已經(jīng)下線,再?zèng)Q定需要將這個(gè) Store 上面的 Region 都調(diào)度走。但是有的時(shí)候,是運(yùn)維人員主動(dòng)將某臺機(jī)器下線,這個(gè)時(shí)候,可以通過 PD 的管理接口通知 PD 該 Store 不可用,PD 就可以馬上判斷需要將這個(gè) Store 上面的 Region 都調(diào)度走。2.2 計(jì)算節(jié)點(diǎn) tidb serverTiDB Server 負(fù)責(zé)接收 SQL 請求,處理 SQL 相關(guān)的邏輯,并通過 PD 找到存儲計(jì)算所需數(shù)據(jù)的 TiKV 地址, 與 TiKV 交互獲取數(shù)據(jù),最終返回結(jié)果。TiDB Server 是無狀態(tài)的,其本身并不存儲數(shù)據(jù),只負(fù)責(zé)計(jì)算,可以無限水平擴(kuò)展, 可以通過負(fù)載均衡組件(如LVS、HAProxy 或 F5)對外提供統(tǒng)一的接入地址。SQL引擎2.3 存儲節(jié)點(diǎn) tikv server
TiKV Server 負(fù)責(zé)存儲數(shù)據(jù),從外部看 TiKV 是一個(gè)分布式的提供事務(wù)的 Key-Value 存儲引擎。存儲數(shù)據(jù)的基本單位是 Region, 每個(gè) Region 負(fù)責(zé)存儲一個(gè) Key Range (從 StartKey 到 EndKey 的左閉右開區(qū)間)的數(shù)據(jù), 每個(gè) TiKV 節(jié)點(diǎn)會(huì)負(fù)責(zé)多個(gè) Region 。TiKV 使用 Raft 協(xié)議做復(fù)制,保持?jǐn)?shù)據(jù)的一致性和容災(zāi)。副本以 Region 為單位進(jìn)行管理,不同節(jié)點(diǎn)上的多個(gè) Region 構(gòu)成一個(gè) Raft Group,互為副本。數(shù)據(jù)在多個(gè) TiKV 之間的負(fù)載均衡由 PD 調(diào)度,這里也是以 Region 為單位進(jìn)行調(diào)度。TiKV單節(jié)點(diǎn)選擇了基于LSM-tree的RocksDB引擎,底層使用kv存儲結(jié)構(gòu),沒有使用btree,而是采用lsm-tree的索引結(jié)構(gòu)(log structured merge trees)- LMS-tree:是一個(gè)用空間置換寫入演出,用順序?qū)懭胩鎿Q隨機(jī)寫入的數(shù)據(jù)結(jié)構(gòu)。
LSM-Tree里面如何寫數(shù)據(jù)的?- 當(dāng)收到一個(gè)寫請求時(shí),會(huì)先把該條數(shù)據(jù)記錄在WAL Log里面,用作故障恢復(fù)。
- 當(dāng)寫完WAL Log后,會(huì)把該條數(shù)據(jù)寫入內(nèi)存的SSTable里面(刪除是墓碑標(biāo)記,更新是新記錄一條的數(shù)據(jù)),也稱Memtable。注意為了維持有序性在內(nèi)存里面可以采用紅黑樹或者跳躍表相關(guān)的數(shù)據(jù)結(jié)構(gòu)。
- 當(dāng)Memtable超過一定的大小后,會(huì)在內(nèi)存里面凍結(jié),變成不可變的Memtable,同時(shí)為了不阻塞寫操作需要新生成一個(gè)Memtable繼續(xù)提供服務(wù)。
- 把內(nèi)存里面不可變的Memtable給dump到到硬盤上的SSTable層中,此步驟也稱為Minor Compaction,這里需要注意在L0層的SSTable是沒有進(jìn)行合并的,所以這里的key range在多個(gè)SSTable中可能會(huì)出現(xiàn)重疊,在層數(shù)大于0層之后的SSTable,不存在重疊key。
- 當(dāng)每層的磁盤上的SSTable的體積超過一定的大小或者個(gè)數(shù),也會(huì)周期的進(jìn)行合并。此步驟也稱為Major Compaction,這個(gè)階段會(huì)真正 的清除掉被標(biāo)記刪除掉的數(shù)據(jù)以及多版本數(shù)據(jù)的合并,避免浪費(fèi)空間,注意由于SSTable都是有序的,我們可以直接采用merge sort進(jìn)行高效合并。
選擇了基于LSM-tree的RocksDB引擎,底層使用kv存儲結(jié)構(gòu),沒有使用B-tree,而是采用LMS-tree的索引結(jié)構(gòu)(log structured merge trees)RocksDB存儲引擎,RockDB 性能很好但是是單機(jī)的,為了保證高可用所以寫多份,上層使用 Raft 協(xié)議來保證單機(jī)失效后數(shù)據(jù)不丟失不出錯(cuò)。保證有了比較安全的 KV 存儲的基礎(chǔ)上再去構(gòu)建多版本,再去構(gòu)建分布式事務(wù),這樣就構(gòu)成了存儲層 TiKV。RocksDB特點(diǎn):
a) RocksDB是一款非常成熟的lms-tree引擎;采用Raft復(fù)制協(xié)議,TiKV采用range分片算法。- raft是一種用于替代paxos的共識算法相比于paxos,raft的目標(biāo)是提供更清晰的邏輯分工使得算法本身能被更好的理解,同時(shí)它的安全性更高,并能提供一些額外的特性。
TiFlash是4.0版本引入的新特性,TiFlash以Raft Learner方式接入Multi-Raft組,使用異步方式傳輸數(shù)據(jù),對TiKV產(chǎn)生非常小的負(fù)擔(dān);當(dāng)數(shù)據(jù)同步到TiFlash時(shí),會(huì)被從行格式解析為列格式。 TiDB提供基于Prometheus+Grafana和Dashboard兩種監(jiān)控方式,Prometheus方式可以提供告警,Dashboard方式不能提供報(bào)警。
3.1 下載tidb-docker-compose查看集群配置文件cat docker-compose.yml (3個(gè)PD,3個(gè)tikv,1個(gè)tidb以及其他組prometheus,grafana,tidb-vision,spark)TiDB啟動(dòng)順序:PD -> TiKV -> TiDB -> TiFlash,關(guān)閉順序正好相反。docker-compose down
docker-compose up -d
發(fā)現(xiàn)tikv 在循環(huán)重啟,查看日志。原因:TiKV 啟動(dòng)時(shí)預(yù)占額外空間的臨時(shí)文件大。臨時(shí)文件名為 space_placeholder_file,位于 storage.data-dir 目錄下。TiKV 磁盤空間耗盡無法正常啟動(dòng)需要緊急干預(yù)時(shí),可以刪除該文件,并且將 reserve-space 設(shè)置為 0MB。默認(rèn)5GB。mysql -h XXX.0.0.1 -P 4000 -u root
本文作者:韋寶軍(上海新炬王翦團(tuán)隊(duì))
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/129366.html