不吹不黑,赞一下应用运维管理的cassacdra
不吹不黑的為菊廠的應(yīng)用運維管理AOM點個贊。Why?
某菊廠應(yīng)用運維管理工具AOM每天處理著億級條數(shù)據(jù),這么多數(shù)據(jù)是怎么存儲的呢?
說到數(shù)據(jù)存儲就會想到關(guān)系型數(shù)據(jù)庫,比如mysql,oracle,sybase。關(guān)系型數(shù)據(jù)庫有自己的優(yōu)勢,數(shù)據(jù)強一致性,支持事務(wù),通用,技術(shù)成熟。但是對于大批量數(shù)據(jù)的存儲和查詢就稍顯吃力,畢竟AOM每秒的寫入數(shù)據(jù)至少都是上萬條,甚至是十幾萬條,隨著系統(tǒng)規(guī)模增長,數(shù)據(jù)庫的擴容也成為新的瓶頸。
AOM的數(shù)據(jù)存儲系統(tǒng)使用的是非關(guān)系型數(shù)據(jù)庫-----cassandra,相比關(guān)系型數(shù)據(jù)庫,cassandra擁有高并發(fā),大數(shù)據(jù)下讀寫能力強,支持分布式,易擴展等優(yōu)點,當(dāng)前也有最致命的缺點,不支持事務(wù),不過對于事務(wù)我們可以通過zk/etcd等其他組件協(xié)助完成。
對于關(guān)系型數(shù)據(jù)庫相比非關(guān)系型數(shù)據(jù)庫為什么會有這么大的差異,這個就得從兩者的架構(gòu)上來講了,下面編者以mysql和cassandra進行對比分析。
不管是mysql還是cassandra,最終數(shù)據(jù)的存儲都要落盤,我們先來看下磁盤的寫入原理:
?
磁盤的基本組件可分為以下幾部分:磁頭,盤片,盤面,磁道,柱面,扇區(qū)等。
盤片被劃分成一系列同心環(huán),圓心是盤片中心,每個同心環(huán)叫做一個磁道,所有半徑相同的磁道組成一個柱面。磁道被沿半徑線劃分成一個個小的段,每個段叫做一個扇區(qū),每個扇區(qū)是磁盤的最小存儲單元。當(dāng)需要從磁盤讀取數(shù)據(jù)時,系統(tǒng)會將數(shù)據(jù)邏輯地址傳給磁盤,磁盤的控制電路按照尋址邏輯將邏輯地址翻譯成物理地址,即確定要讀的數(shù)據(jù)在哪個磁道,哪個扇區(qū)。為了讀取這個扇區(qū)的數(shù)據(jù),需要將磁頭放到這個扇區(qū)上方,為了實現(xiàn)這一點,磁頭需要移動對準(zhǔn)相應(yīng)磁道,這個過程叫做尋道,所耗費時間叫做尋道時間,然后磁盤 旋轉(zhuǎn)將目標(biāo)扇區(qū)旋轉(zhuǎn)到磁頭下,這個過程耗費的時間叫做旋轉(zhuǎn)時間。
即一次訪盤請求(讀/寫)完成過程由三個動作組成:
1)尋道(時間):磁頭移動定位到指定磁道?
2)旋轉(zhuǎn)延遲(時間):等待指定扇區(qū)從磁頭下旋轉(zhuǎn)經(jīng)過?
3)數(shù)據(jù)傳輸(時間):數(shù)據(jù)在磁盤與內(nèi)存之間的實際傳輸
大家應(yīng)該有過類似的經(jīng)歷,進行數(shù)據(jù)拷貝時,文件個數(shù)越少,單個文件越大,拷貝的速率越快,反之文件個數(shù)多,單個文件小,拷貝的速率越慢,這其中的原因就是因為在拷貝小文件時,系統(tǒng)的耗時基本都耗費在尋址上了。Cassandra相比mysql有更高的寫入能力,就是因為cassandra采用了更高效的寫入機制,該機制大大縮短了磁盤的尋址時間(準(zhǔn)確來講應(yīng)該是尋址次數(shù))。
我們先來看下Mysql(InnoDB)的索引原理, InnoDB的索引采用B+樹,其數(shù)據(jù)結(jié)構(gòu)如下所示:
?
所有的數(shù)據(jù)都存儲在葉子節(jié)點,葉子節(jié)點之間都有指針,這是為了做范圍遍歷。B+樹的優(yōu)勢在于快速索引,B+樹的層高基本都在2~3層,也就意味著一次數(shù)據(jù)查找只需要2~3次IO操作。而且每次的單條數(shù)據(jù)都非常穩(wěn)定,耗時和查找次數(shù)都差不多。B+樹最大的性能問題是會產(chǎn)生大量的隨機IO,隨著數(shù)據(jù)的插入,葉子節(jié)點會慢慢分裂,邏輯上連續(xù)的節(jié)點物理上確不連續(xù),甚至相隔甚遠,順序遍歷的時候,會產(chǎn)生大量的隨機IO操作。這正如大家熟知的ArrayList和LinkedList,ArrayList在內(nèi)存中是一塊連續(xù)的內(nèi)存,訪問的時候順序訪問,LinkedList是多個內(nèi)存塊通過指針串聯(lián)起來的,訪問的時候必須先通過指針獲取下一個內(nèi)存塊的地址,然后再通過地址訪問,因此ArrayList的訪問遠遠高于LinkedList。B+樹的葉子節(jié)點就類似一個LinkedList,隨著葉子節(jié)點的分裂,在做順序檢索時,跨葉子節(jié)點的訪問往往需要先找到下一個葉子節(jié)點的地址(磁盤尋址),然后才能訪問到具體的葉子節(jié)點。
B+樹的順序檢索會產(chǎn)生大量的隨機IO,B+樹的寫入同樣會產(chǎn)生類似的問題,比如上圖B+樹中的9和86,它們所屬的葉子節(jié)點在磁盤上相隔甚遠,數(shù)據(jù)插入時就會產(chǎn)生兩次隨機寫入。當(dāng)大批量數(shù)據(jù)寫入時,隨機IO操作的次數(shù)也就更多。
如下是一張隨機讀寫和順序讀寫的性能比對圖:
?
從上圖可以直觀的感受到隨機讀寫與順序讀寫的差異,這兩者完全不在一個量級。用過kafka和HDFS的開發(fā)者就會發(fā)現(xiàn)kafka和HDFS的磁盤IO使用率非常高,有時甚至接近磁盤的最大寫入速率,這個就是因為kafka和HDFS是基于文件的順序?qū)懭?#xff08;當(dāng)然還有其他技術(shù))。從以上分析來看,磁盤的隨機讀取/寫入是影響mysql順序檢索和批量寫入的最大因素,那我們有沒有辦法減少這種隨機寫入呢,此時LSM-Tree(Log-Structured Merge-Tree)呼之欲出。
2006年,google發(fā)表了BigTable的論文。BigTable的數(shù)據(jù)結(jié)構(gòu)就采用了LSM(http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.44.2782&rep=rep1&type=pdf)。目前LSM被很多數(shù)據(jù)庫作為存儲結(jié)構(gòu),比如HBase,Cassandra,LevelDB。LSM拋棄了大多數(shù)數(shù)據(jù)庫使用的傳統(tǒng)文件組織方法,通過減少更新/寫入操作帶來的隨機操作次數(shù)來提高數(shù)據(jù)的寫入能力。
LSM Tree的核心思路其實非常簡單,就是假定內(nèi)存足夠大,因此不需要每次有數(shù)據(jù)更新就必須將數(shù)據(jù)寫入到磁盤中,而可以先將最新的數(shù)據(jù)駐留在磁盤中,等到積累到一定數(shù)目之后,再使用歸并排序的方式將內(nèi)存內(nèi)的數(shù)據(jù)合并追加到磁盤隊尾(因為所有待排序的樹都是有序的,可以通過合并排序的方式快速合并到一起)。
LSM的核心思路可以分為兩部分:
①、數(shù)據(jù)先寫入內(nèi)存
②、將內(nèi)存中的數(shù)據(jù)排序后追加到磁盤隊尾。
?
LSM由兩個或兩個以上的存儲結(jié)構(gòu)組成。最簡單的LSM由兩部分組成,一部分常駐內(nèi)存,稱為C0;另一部分存儲在硬盤上,稱為C1。
數(shù)據(jù)寫入時,先記錄到本地的操作日志文件(HLog或CommitLog),為將來做數(shù)據(jù)恢復(fù)使用。然后將數(shù)據(jù)寫入到C0中,由于C0使用的是內(nèi)存,因此插入性能遠遠高于磁盤寫入。當(dāng)C0的節(jié)點數(shù)目超過一定閾值時,會將C0中的數(shù)據(jù)進行一次排序,然后追加到C1樹中。
多部件的LSM就是包含多個存儲結(jié)構(gòu):
?
隨著數(shù)據(jù)規(guī)模增加,C0中的數(shù)據(jù)超過閾值后就會往磁盤中寫入一個新的file,這樣磁盤中的樹(file)會越來越多。當(dāng)較小的Ci-1個數(shù)超過一定閾值的時候,會進行Ci-1和Ci的合并。合并是為了減少整個C樹的個數(shù),加快搜索速度。
數(shù)據(jù)查詢的時候,會按照樹的生成時間按照從新到舊的順序逐個遍歷每個C樹,即C0,C1,C2….Ck。為什么要按照時間順序從最近往之前遍歷呢,這就是LSM的另一個巧妙點(更新/刪除)。
LSM的更新和刪除操作都是往C0上新增一條記錄,通過新記錄+標(biāo)記的方式完成,因此在遍歷的時候必須按照時間順序進行遍歷,這樣就可以保證數(shù)據(jù)更新和刪除的正確性,同時保證了數(shù)據(jù)的順序?qū)懭搿.?dāng)前LSM在進行C樹合并時,會對刪除和更新記錄進行合并。
我們來看下HBase的整個架構(gòu)圖:
?
HBase是基于HDFS之上采用LSM結(jié)構(gòu)做的數(shù)據(jù)存儲。HBase的主要部件可以分為如下幾類:
storeFile:小文件,不可編輯。即寫入到磁盤中的C樹。
Hlog:LSM中用于記錄寫入記錄的操作日志,為了將來做數(shù)據(jù)恢復(fù)使用,畢竟C0中的數(shù)據(jù)是在內(nèi)存中存儲,當(dāng)HBase宕機后,內(nèi)存中的數(shù)據(jù)就會丟失,此時需要從Hlog中恢復(fù)。
Memstore:即C0樹。至此,LSM和B+樹的對比也就講完了。
轉(zhuǎn)載于:https://www.cnblogs.com/hwpaas/p/9485615.html
總結(jié)
以上是生活随笔為你收集整理的不吹不黑,赞一下应用运维管理的cassacdra的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python函数Day1
- 下一篇: 判断变量类型