分佈式數據存儲系統之三要素

什麼是分佈式數據存儲系統?

分佈式存儲系統的核心邏輯,就是將用戶需要存儲的數據根據某種規則存儲到不同的機器上,當用戶想要獲取指定數據時,再按照規則到存儲數據的機器裏獲取

如下圖所示,當用戶(即應用程序)想要訪問數據 D,分佈式操作引擎通過一些映射方式,比如 Hash、一致性 Hash、數據範圍分類等,將用戶引導至數據 D 所屬的存儲節點獲取數據。
在這裏插入圖片描述
上面的這個獲取數據的整個過程與到商店購物的過程是不是有些類似呢?

顧客到商店購物時,導購會根據顧客想要購買的商品引導顧客到相應的貨架,然後顧客從這個貨架上獲取要購買的商品,完成購物。這裏的顧客就是圖中的應用程序,導購就相當於分佈式操作引擎,它會按照一定的規則找到相應的貨架,貨架就是存儲數據的不同機器節點。

其實,這個過程就是分佈式存儲系統中獲取數據的通用流程,顧客、導購和貨架組成了分佈式存儲系統的三要素,分別對應着分佈式領域中的數據生產者 / 消費者數據索引數據存儲

接下來,我們就詳細看看這三個要素吧。

分佈式數據存儲系統三要素

顧客就是數據的生產者和消費者,也就是說顧客代表兩類角色,生產者會生產數據(比如,商店購物例子中的供貨商就屬於生產類顧客),將數據存儲到分佈式數據存儲系統中,消費者是從分佈式數據存儲系統中獲取數據進行消費(比如,商店購物例子中購買商品的用戶就屬於消費類顧客);導購就是數據索引,將訪問數據的請求轉發到數據所在的存儲節點;貨架就是存儲設備,用於存儲數據。

顧客:生產和消費數據

顧客相當於分佈式存儲系統中的應用程序,而數據是應用程序的原動力根據數據的產生和使用,顧客分爲生產者和消費者兩種類型。生產者負責給存儲系統添加數據,而消費者則可以使用系統中存儲的數據。就像是火車票存儲系統,如圖所示,鐵路局就相當於生產者類型的顧客,而乘客就相當於消費者類型的顧客。鐵路局將各個線路的火車票信息發佈到訂票網站的後臺數據庫中,乘客通過訂票網站訪問數據庫,來進行查詢餘票、訂票、退票等操作。
在這裏插入圖片描述
生產和消費的數據通常是多種多樣的,不同應用場景中數據的類型、格式等都不一樣。根據數據的特徵,這些不同的數據通常被劃分爲三類:結構化數據、半結構化數據和非結構化數據。

  • 結構化數據通常是指關係模型數據其特徵是數據關聯較大、格式固定。火車票信息比如起點站、終點站、車次、票價等,就是一種結構化數據。結構化數據具有格式固定的特徵,因此一般採用分佈式關係數據庫進行存儲和查詢。
  • 半結構化數據通常是指非關係模型的有基本固定結構模式的數據,其特徵是數據之間關係比較簡單。比如HTML 文檔,使用標籤書寫內容。半結構化數據大多可以採用鍵值對形式來表示,比如 HTML 文檔可以將標籤設置爲key,標籤對應的內容可以設置爲value,因此一般採用分佈式鍵值系統進行存儲和使用。
  • 非結構化數據是指沒有固定模式的數據,其特徵是數據之間關聯不大。比如文本數據就是一種非結構化數據。這種數據可以存儲到文檔中,通過ElasticSearch(一個分佈式全文搜索引擎)等進行檢索。

導購:確定數據位置

導購是分佈式存儲系統必不可少的要素,如果沒有導購, 顧客就需要逐個貨架去尋找自己想要的商品。想象一下,如果你去訂票網站訂火車票,按照自己的需求點擊查詢車票後,系統會逐個掃描分佈式存儲系統中每臺機器的數據,尋找你想要購買的火車票。如果系統中存儲的數據不多,響應時間也不會太長,畢竟計算機的速度還是很快的;但如果數據分佈在幾千臺甚至上萬臺機器中,系統逐個機器掃描後再給你響應,我相信你會對這個訂票網站很失望。這種定位數據存儲位置的方式會浪費你很多時間,嚴重影響購票體驗。

因此,在分佈式存儲系統中,必須有相應的數據導購,否則系統響應會很慢,效率很低。爲解決這個問題,數據分片技術就走入了分佈式存儲系統的大家庭數據分片技術,是指分佈式存儲系統按照一定的規則將數據存儲到相對應的存儲節點中,或者到相對應的存儲節點中獲取想要的數據,這是一種很常用的導購技術:

  • 一方面可以降低單個存儲節點的存儲和訪問壓力;
  • 另一方面,可以通過規定好的規則快速找到數據所在的存儲節點,從而大大降低搜索延遲,提高用戶體驗。

也就是說,當鐵路局發佈各個線路的火車票信息時,會按照一定規則存儲到相應的機器中,比如北京到上海的火車票存儲到機器 A 中,西安到重慶的火車票存儲到機器 B 中。當乘客查詢火車票時,系統就可以根據查詢條件迅速定位到相對應的存儲機器,然後將數據返回給用戶,響應時間就大大縮短了。如圖所示,當查詢北京 - 上海的火車票相關信息時,可以與機器 A 進行數據交互。
在這裏插入圖片描述
這個例子中按照數據起點、終點的方式劃分數據,將數據分爲幾部分存儲到不同的機器節點中,就是數據分片技術的一種。當查詢數據時,系統可以根據查詢條件迅速找到對應的存儲節點,從而實現快速響應。

上述的例子中,按照數據特徵進行了數據分片,當然,還有其他很多數據分片的方案。比如,按照數據範圍,採用哈希映射、一致性哈希環等對數據劃分。

數據範圍數據分片方案介紹

**針對數據範圍的數據分片方案是指,按照某種規則劃分數據範圍,然後將在這個範圍內的數據歸屬到一個集合中。**這就好比數學中通常講的整數區間,比如 1~1000 的整數,[1,100]的整數屬於一個子集、[101,1000]的整數屬於另一個子集。

對於前面講的火車票的案例,按照數據範圍分片的話,可以將屬於某條線的所有火車票數據劃分到一個子集或分區進行存儲,比如機器 A 存儲京廣線的火車票數據,機器 B 存儲京滬線的火車票數據。也就是說,數據範圍的方案是按照範圍或區間進行存儲或查詢。

如圖所示,當用戶查詢北京 - 上海的火車票相關信息時,首先判斷查詢條件屬於哪個範圍,由於北京 - 上海的火車線路屬於京滬線,因此係統按照規則將查詢請求轉到存取京滬線火車票數據的機器 B,然後由機器 B 進行處理並給用戶返回響應結果。
在這裏插入圖片描述
爲了提高分佈式系統的可用性與可靠性,除了通過數據分片減少單個節點的壓力外,數據複製也是一個非常重要的方法。**數據複製就是將數據進行備份,以使得多個節點存儲該數據。**想象一下,當某個存儲節點出現故障時,如果只採用數據分片技術,那這個節點的數據就會丟失,從而給用戶造成損失。因此,數據複製在分佈式存儲系統中是不可或缺的。
在這裏插入圖片描述
數據 A 被拆分爲兩部分存儲在兩個節點 Node1 和 Node2 上,屬於數據分片;而對數據 B 來說,同一份完整的數據在兩個節點中均有存儲,就屬於數據複製。

在實際的分佈式存儲系統中,數據分片和數據複製通常是共存的:

  • 數據通過分片方式存儲到不同的節點上,以減少單節點的性能瓶頸問題;
  • 而數據的存儲通常用主備方式保證可靠性,也就是對每個節點上存儲的分片數據,採用主備方式存儲,以保證數據的可靠性。其中,主備節點上數據的一致,是通過數據複製技術實現的。

回憶下Kafka 集羣的總體架構,下圖是Kafka 集羣消息存儲架構圖,這就是數據分片和數據複製共存的一個典型應用場景。如下所示:

  • 消息數據以 Partition(分區)進行存儲,一個 Topic(主題)可以由多個 Partition 進行存儲,Partition可以分佈到多個 Broker 中;
  • 同時,Kafka 還提供了 Partition 副本機制(對分區存儲的信息進行備份,比如 Broker1 中的 Topic-1 Partion-0 是對 Broker 0 上的 Topic-1 Partition-0進行的備份),從而保證了消息存儲的可靠性。

在這裏插入圖片描述

貨架:存儲數據

貨架是用來存儲數據的,因爲數據是由顧客產生和消費的,因此貨架存儲的數據類型與顧客產生和消費的數據類型是一致的,即包括結構化數據、半結構化數據和非結構化數據。針對這三種不同的數據類型,存儲“貨架”可以大致劃分爲以下三種:

  • 分佈式數據庫,通過表格來存儲結構化數據,方便查找。常用的分佈式數據庫有 MySQL Sharding、Microsoft SQL Azure、Google Spanner、Alibaba OceanBase 等。
  • 分佈式鍵值系統,通過鍵值對來存儲半結構化數據。常用的分佈式鍵值系統有 Redis、Memcache 等,可用作緩存系統。
  • **分佈式存儲系統,通過文件、塊、對象等來存儲非結構化數據。**常見的分佈式存儲系統有 Ceph、GFS、HDFS、Swift 等。

而對貨架材料也就是存儲介質的選擇,本質就是選擇將數據存儲在磁盤還是內存(緩存)上:

  • 磁盤存儲量大,但 IO 開銷大,訪問速度較低,常用於存儲不經常使用的數據。比如,電商系統中,排名比較靠後或購買量比較少、甚至無人購買的商品信息,通常就存儲在磁盤上。
  • 內存容量小,訪問速度快,因此常用於存儲需要經常訪問的數據。比如,電商系統中,購買量比較多或排名比較靠前的商品信息,通常就存儲在內存中。

主流分佈式數據存儲系統

首先,我們看一下主流的分佈式數據庫,主要包括 MySQL Sharding、SQL Azure、Spanner、OceanBase 等,具體對比分析如下表所示。
在這裏插入圖片描述
然後,我們看一下主流的分佈式存儲系統,主要包括 Ceph、GFS、HDFS 和 Swift 等,具體對比分析如下所示。
在這裏插入圖片描述

總結

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章