分布式儲存系統設計(3) 儲存結構

2022-04-07 14:39:08 字數 2846 閱讀 3773

在nosql儲存系統中,一般都採用key-value的資料型別,key-value結構簡單,易於儲存,非常適合分布式nosql儲存系統。但簡單的資料型別對業務儲存的資料就有一定的侷限性,比如需要儲存列表型別的資料。針對這個問題,系統對key-value型別的資料做了一些擴充套件,支援在乙個key下儲存多個欄位和列表,擴大了資料儲存的業務場景。本文主要介紹這個分布式儲存系統所支援的資料型別,以及資料在記憶體中的儲存實現。

key-value

key-value是最簡單的資料型別,key和value都不支援結構化資料,業務進行讀寫的時候需要進行序列化和反序列化,系統並不理解資料結構,都當作二進位制序列處理,具有通用性,這樣key和value就支援任意型別的資料,只要序列化後的資料長度不超過限制。

key-fields支援多個字段,使用整型的tag進行字段標識,每個tag對應的field長度可以不一樣,field也是序列化的資料,比較通用。對於需要在乙個key的資料中儲存多個欄位的場景,key-fields相比key-value友好了很多。

key-rows支援多個行,每一行就是乙個key-fields,支援多個字段,各行的field數量、長度都可以不一樣,非常靈活。key-rows可以用來儲存列表,支援更複雜的業務場景,如存放乙個使用者的購物訂單資訊。

由於資料是全記憶體儲存,為了保證程序重啟時不丟失資料,使用共享記憶體的方式,同時也方便了多個程序訪問資料。對於key-value型別的資料,最高效資料結構自然是雜湊表。這裡介紹一種多階雜湊表的實現,具有簡單、高效、魯棒等特點,非常適合工程應用。

多階雜湊表採用類似再雜湊的思想來解決衝突。如下圖所示,把乙個線性陣列劃分為n階,每一階的桶大小(元素個數)為ni(1≤i≤n),插入資料時,通過hash(key)%ni計算在每一階的位置,從第1階開始,如果出現衝突,則繼續在下一階查詢,只到找到空位為止,如果在n階都發生了衝突,則插入失敗,查詢的過程需要類似。需要注意的是,在插入乙個新的資料時,需要先在所有階都查詢一遍,對效能會有一定的影響,例如資料1第一次插入在第3階,隨後在其查詢路徑上第2階的資料2被刪除,在資料1再次插入時,會在第2階找到空位,如果插入此位置,第3階的資料2會殘留而無法清理,造成空間的浪費。而對於nosql資料儲存系統來說,新增資料佔比比較少,大部分操作是資料更新和讀取,所以多階雜湊表在這種場景下可以保持比較好的效能。

衡量多階雜湊表的好壞主要有2個指標,空間利用率和平均查詢次數。通過實驗可知,階數越多,處理衝突的能力越強,空間的利用率也高,但平均查詢次數越多,可見空間利用率和平均查詢次數相互制約,需要根據實際情況進行權衡。

對於每一階的桶大小,需要選擇不同的質數,可以在數學上證明各階的桶大小互質時,資料在各階的分布會更加均勻,從而降低了衝突的概率。最簡單的方法是各階選擇連續的質數,那有沒有更好的選擇,可以在相同階數下,得到更高的空間利用率和更少的平均查詢次數。在每階桶大小相近的情況下,低階會分布更多的資料,所以從低階到高階桶大小遞減的情況下,會提公升空間利用率;在階數不變的條件下,為了降低平均查詢次數,應該讓低階桶大小越大越好,同時為了保持高階對衝突的處理能力,桶大小不能太小。綜上所述,桶大小從低階到高階依次遞減,在低階遞減比較劇烈,在高階遞減比較平緩,而等比數列比較符合這個特徵。桶大小採用係數為1.5的等比數列與桶大小平均分布的對比測試結果如下,使用隨機數進行插入,第一次出現插入失敗時的空間利用率作為最終的結果,可以看出在相同階數下,桶大小為等比數列時會有更高的空間利用率和更少的平均查詢次數,階數為20階是比較好的選擇,此時多階雜湊表的空間利用率達到93%,平均查詢次數約為3次。

在前面所列舉的幾種資料型別,key和資料都是變長的,而雜湊表的節點是定長的,如果把資料直接存在雜湊表節點,是非常浪費空間的。為了提高記憶體的利用率,這裡採用一種雜湊表和煉表相結合的資料介面,如下圖所示,雜湊表節點存的是資料索引,key和資料都存放在乙個定長塊鍊錶中,這樣就可以根據資料大小來分配定長塊的數量,即高效又不浪費空間。定長塊的大小也需要仔細權衡,太大了會導致無效空洞比較大,太小了又會使得每個資料占用的定長塊數量比較多,對效能有一定的影響。

對於一塊儲存空間,單程序進行讀寫是最簡單的設計,沒有讀寫衝突的問題,但單程序在處理能力上就會成為瓶頸。為了提公升處理能力,有必要使用多程序或多執行緒併發的方式,這樣就引入了讀寫衝突的問題。

解決了寫程序互斥的問題,讀寫程序之間還是會存在衝突,如果某個資料在進行寫操作的過程中,正好讀程序在讀取這個資料,就有可能讀到的是不完整的資料。這個問題可以通過校驗來解決,在資料中記錄乙個校驗值,每次寫入就更新校驗值,讀取資料的時候,對資料進行校驗,如果校驗失敗說明出現了讀寫衝突,則需要進行重試。為了降低讀寫衝突的概率,在更新資料的時候,按照下圖所示的流程,並不在原來的定長塊鏈上進行覆寫進行處理,而是分配新的定長塊鏈寫入資料。

大多數使用分布式儲存的業務,都是寫少讀多的場景,在上面的讀寫衝突處理機制下,乙個儲存單元是可以同時支援乙個寫程序和多個讀程序,使得讀操作有更高的併發能力,非常適合寫少讀多的情況。

python分布式儲存系統 分布式系統

danger 什麼是分布式系統 分布式系統是由一組通過網路進行通訊 為了完成共同的任務而協調工作的計算機節點組成的系統。分布式系統的出現是為了用廉價的 普通的機器完成單個計算機無法完成的計算 儲存任務。其目的是利用更多的機器,處理更多的資料。首先需要明確的是,只有當單個節點的處理能力無法滿足日益增長...

分布式儲存系統概述

雲計算 大資料,這些熱點詞彙,後台的基礎設施離開不了分布式儲存系統,它的兩個特點,一是規模大,二是成本低。其實分布式系統的設計是根據需求來變化的,那麼我們接下來就看,我們需要儲存哪些資料,以及,分布式儲存系統有哪些分類。1.分布式儲存的資料 大致可以分為三類 結構化資料 這個最容易理解,關聯式資料庫...

分布式儲存系統 Ceph

你了解ceph嗎?ceph是一種分布式儲存系統,它可以將多台伺服器組成乙個超大集群,把這些機器中的磁碟資源整合到一塊兒,形成乙個大的資源池 pb級別 然後按需分配給應用使用。那麼你知道ceph的架構嗎?ceph的底層實現是rados,rados是由c 寫的,但是它向外界暴露了呼叫介面,即librad...