應用的角度聊過了,我們再看看這三種存儲的一些技術細節,首先看看在系統層級的分布。

我們從底層往上看,最底層就是硬盤,多個硬盤可以做成RAID組,無論是單個硬盤還是RAID組,都可以做成PV,多個PV物理卷捏在一起構成VG卷組,這就做成一塊大蛋糕了。接下來,可以從蛋糕上切下很多塊LV邏輯卷,這就到了存儲用戶最熟悉的卷這層。到這一層為止,數據一直都是以Block塊的形式存在的,這時候提供出來的服務就是塊存儲服務。你可以通過FC協議或者iSCSI協議對卷訪問,映射到主機端本地,成為一個裸設備。在主機端可以直接在上面安裝數據庫,也可以格式化成文件系統后交給應用程序使用,這時候就是一個標准的SAN存儲設備的訪問模式,網絡間傳送的是塊。
如果不急着訪問,也可以在本地做文件系統,之后以NFS/CIFS協議掛載,映射到本地目錄,直接以文件形式訪問,這就成了NAS訪問的模式,在網絡間傳送的是文件。
如果不走NAS,在本地文件系統上面部署OSD服務端,把整個設備做成一個OSD,這樣的節點多來幾個,再加上必要的MDS節點,互聯網另一端的應用程序再通過HTTP協議直接進行訪問,這就變成了對象存儲的訪問模式。當然對象存儲通常不需要專業的存儲設備,前面那些LV/VG/PV層也可以統統不要,直接在硬盤上做本地文件系統,之后再做成OSD,這種才是對象存儲的標准模式,對象存儲的硬件設備通常就用大盤位的服務器。
從系統層級上來說,這三種存儲是按照塊->文件->對象逐級向上的。文件一定是基於塊上面去做,不管是遠端還是本地。而對象存儲的底層或者說后端存儲通常是基於一個本地文件系統(XFS/Ext4..)。這樣做是比較合理順暢的架構。但是大家想法很多,還有各種特異的產品出現,我們逐個來看看:
對象存儲除了基於文件,可以直接基於塊,但是做這個實現的很少,畢竟你還是得把文件系統的活給干了,自己實現一套元數據管理,也挺麻煩的,目前我只看到Nutanix宣稱支持。另外對象存儲還能基於對象存儲,這就有點尷尬了,就是轉一下,何必呢?但是這都不算最奇怪的,最奇怪的是把對象存儲放在最底層,那就是這兩年大紅的Ceph。

Ceph是個開源的分布式存儲,相信類似的架構圖大家都見過,我把底層細節也畫出來,方便分析。
底層是RADOS,這是個標准的對象存儲。以RADOS為基礎,Ceph 能夠提供文件,塊和對象三種存儲服務。其中通過RBD提供出來的塊存儲是比較有價值的地方,畢竟因為市面上開源的分布式塊存儲少見嘛(以前倒是有個sheepdog,但是現在不當紅了)。當然它也通過CephFS模塊和相應的私有Client提供了文件服務,這也是很多人認為Ceph是個文件系統的原因。另外它自己原生的對象存儲可以通過RadosGW存儲網關模塊向外提供對象存儲服務,並且和對象存儲的事實標准Amazon S3以及Swift兼容。所以能看出來這其實是個大一統解決方案,啥都齊全。
上面講的大家或多或少都有所了解,但底層的RADOS的細節可能會忽略,RADOS也是個標准對象存儲,里面也有MDS的元數據管理和OSD的數據存儲,而OSD本身是可以基於一個本地文件系統的,比如XFS/EXT4/Brtfs。在早期版本,你在部署Ceph的時候,是不是要給OSD創建數據目錄啊?這一步其實就已經在本地文件系統上做操作了(現在的版本Ceph可以直接使用硬盤)。
現在我們來看數據訪問路徑,如果看Ceph的文件接口,自底層向上,經過了硬盤(塊)->文件->對象->文件的路徑;如果看RBD的塊存儲服務,則經過了硬盤(塊)->文件->對象->塊,也可能是硬盤(塊)->對象->塊的路徑;再看看對象接口(雖然用的不多),則是經過了硬盤(塊)->文件->對象或者硬盤(塊)->對象的路徑。
是不是各種組合差不多齊全了?如果你覺得只有Ceph一個這么玩,再給你介紹另一個狠角色,老牌的開源分布式文件系統GlusterFS最近也宣布要支持對象存儲。它打算使用swift的上層PUT、GET等接口,支持對象存儲。這是文件存儲去兼容對象存儲。對象存儲Swift也沒閑着,有人在研究Swift和hadoop的兼容性,要知道MapReduce標准是用原生的HDFS做存儲的,這相當是對象存儲去兼容文件存儲,看來混搭真是潮流啊。
雖說現在大家都這么隨便結合,但是這三種存儲本質上還是有不同的,我們回到計算機的基礎課程,從數據結構來看,這三種存儲有着根本不同。塊存儲的數據結構是數組,而文件存儲是二叉樹(B,B-,B+,B*各種樹),對象存儲基本上都是哈希表。

數組和二叉樹都是老生常談,沒有太多值得說的,而對象存儲使用的哈希表也就是常聽說的鍵值(KeyVaule型)存儲的核心數據結構,每個對象找一個UID(所謂的“鍵”KEY),算哈希值(所謂的“值Vaule”)以后和目標對應。找了一個哈希表例子如下:
關鍵字
|
內部編碼
|
內部編碼的平方值
|
H(k)關鍵字的哈希地址
|
KEYA
|
11050201
|
122157778355001
|
778
|
KYAB
|
11250102
|
126564795010404
|
795
|
AKEY
|
01110525
|
001233265775625
|
265
|
BKEY
|
02110525
|
004454315775625
|
315
|
鍵值對應關系簡單粗暴,畢竟算個hash值是很快的,這種扁平化組織形式可以做得非常大,避免了二叉樹的深度,對於真.海量的數據存儲和大規模訪問都能給力支持。所以不僅是對象存儲,很多NoSQL的分布式數據庫都會使用它,比如Redis,MongoDB,Cassandra 還有Dynamo等等。順便說一句,這類NoSQL的出現有點打破了數據庫和文件存儲的天然屏障,原本關系數據庫里面是不會存放太大的數據的,但是現在像MongoDB這種NoSQL都支持直接往里扔大個的“文檔”數據,所以從應用角度上,有時候會把對象存儲,分布式文件系統,分布式數據庫放到一個台面上來比較,這才是混搭。
當然實際上幾個開源對象存儲比如swift和ceph都是用的一致性哈希,進階版,最后變成了一個環,首首尾相接,避免了節點故障時大量數據遷移的尷尬,這個幾年前寫Swift的時候就提過。這里不再深入細節。