為什麼分布式資料庫這麼喜歡用kv store?

時間 2021-05-08 08:44:37

1樓:NebulaGraph

採用鍵值對儲存主要還是出於資料模型和效能角度考慮的。目前比較流行的方案有 Google 開源的 LevelDB 和 FaceBook 開源的 RocksDB。鍵值型儲存模型比較簡單,LSM 模型將隨機寫轉換為順序寫,在隨機讀方面也可以優化,效能比較有保障。

分布式系統往往根據 key 做分割槽,各個節點之間往往是 Shared Nothing 架構,當然也有其他架構,比如 HBase 就是 Shared Disk。針對 Shared Nothing,鍵值型儲存引擎比較合適,各個例項可以根據 key 進行處理,對於分布式處理比較方便。

2樓:

從另乙個角度看,儲存的目的是為了查詢/計算,而目前的分布式查詢/計算系統基本上都是基於map reduce的,而map reduce是面向kv資料的,所以分布式資料庫採用kv store,因為它要方便上層進行分布式查詢/計算。

3樓:藍色麻雀

使用KV更有利於讀多寫少的讀查詢加速和併發,也有利於海量的資料儲存

資料查詢可以不用Key,但失去基於Key的查詢,將是全域性掃瞄,效能極差,失去了做資料庫的意義

4樓:hellocode

『工程上的解耦』這個共性大家都提到了,我補充另乙個角度。

雖然不論是單機資料庫(MySQL、PostgreSQL等等),還是題主說到的分布式資料庫(CockroachDB、TiDB),都存在KV這個抽象,但對於KV這個介面的設計,還是存在差別的。

資料庫通常會有這麼幾個模組,KV儲存、事務、索引,這三者之間的關係看起來涇渭分明,但實際上交織耦合,其中存在很多設計點。

第一種設計是目前share-nothing分布式資料庫用的比較多的:基於單機KV儲存實現分布式KV,再基於分布式KV實現事務,在distributed transactional key-value store的基礎上再實現global index,以及查詢引擎。在這種設計下,單機的KV儲存甚至不需要支援事務,因為完全可以基於這個KV實現分布式事務。

典型代表是TiDB。

這種設計的好處不再贅述,看一下侷限性:分層太過清晰,想打通多個層次的時候反而比較複雜。例如分布式事務,是不是可以和Consensus Protocol融合,實現安全的MVCC Follower Read?

是不是可以借助單機引擎的事務,來優化單個region內的事務避免分布式事務的開銷?

所以第二種設計,保留單機事務的概念,把單機事務當做common case,而分布式事務只是錦上添花。奠定了這麼乙個基本概念之後,通常索引也會優先做成單機的,全域性索引的優先順序降低甚至不做。在這種設計下,單機的KV儲存,事實上就需要支援事務,甚至,為了在此基礎上做分布式事務,還需要提供一些額外的介面,例如point-in-time snapshot read。

典型代表是MongoDB。

由於具有了原生的單機事務,因此在common case下會很高效,可以當單機資料庫來用。但其痛點也隨之產生:如何基於單機事務做分布式事務,兩階段提交怎麼做,事務隔離怎麼做,多版本讀怎麼做?

並且,這些功能往往會耦合於單機的事務引擎,可想而知其複雜度。

如果單獨考慮第二種設計中的索引實現,又會產生多種的KV介面設計。索引是基於KV做,還是下沉到KV中?

前面一種相對清晰,但效能方面有所折衷,由於索引的建立是基於純粹的KV介面,bulk load不好做,並且索引本身也是多版本的

後面一種設計,由於儲存引擎具有了schema資訊,索引可以有更多的優化空間。例如索引可以做成單版本的(PostgreSQL),指向多版本的heap file,以省去多版本的開銷;例如像X-Engine那樣,利用LSM 的特性實現更加高效的Fast DDL

簡單總結一下,雖然大部分資料庫都有KV儲存這個抽象,但仍然存在很大的設計空間,例如單機的KV是否需要支援事務,是否需要感知schema,是否需要暴露多版本的介面。因此,不能籠統地說分布式資料庫都喜歡用KV store。

5樓:溫正湖

任何資料庫都得有儲存引擎啊。儲存引擎肯定是具備kv功能的,這是必要條件。所以在通用的分布式kv引擎(至少本地kv儲存)上實現分布式資料庫,事半功倍。

6樓:FOCUS

說說我個人的想法。

資料庫的本質就是將資料排序。

使用 kv store 保證資料寫入後,能高效保持有序。

而 kv store 都需要乙個 unique key。

7樓:艾瑞克.Eric

引用我看到的問題

像cockroach,tidb,yugabyte這些,明明是關係庫,為啥非要弄個key,即使業務邏輯不需要表有unique key,也要給每條記錄硬加乙個key,這是什麼目的?

然後試答一下:

關係型資料庫的key一般指索引,基於B+樹或Hash,提公升查詢的速度,不帶unique時沒有唯一性約束。建表的時候不一定要求一定加索引,完全沒有任何索引的表也是可以新增的,直到你遇到查詢瓶頸了 (… 即,並沒有非要弄個key

+分布式以後,儲存、索引這些具體的實現,可以通過已經造好的輪子,也就是題中提到的kv儲存(這裡的key就不是索引了,而是鍵),比如tidb的底層tikv的底層rocksdb,來進行具體的儲存和實現,同時使用一定的分布式一致性協議比如raft保證所需的一致性級別、事務的隔離等級等等。既然是底層,那麼具體kv實現的細節上層的關係型資料庫引擎使用的時候是不會具體感知到kv存在的,除非出故障了(事故之類,kv副本丟多了)或者踩中kv導致的限制了(比如改字段長度什麼的)

具體為什麼用kv可以參考tidb/tikv的文件,簡單來說是kv+raft相對於堆mysql例項的方案更易橫向擴充套件,但並不是唯一解,比如k->column families也是一種方案,但key的設計非常tricky,甚至要用到類似儲存過程的機制保證寫對…

8樓:Ivony

因為沒有主鍵的關係型資料不滿足第二正規化……

分布式儲存總要個分割槽鍵吧,否則怎麼做分布式儲存……難不成每次都對整個資料做雜湊?所以這個主鍵在實現上是必然存在的。

9樓:

個人理解,應該是為了解耦合。

現在的資料庫通常都會分為儲存引擎和查詢引擎。儲存引擎負責保證資料的持久化,簡單的事務控制。

查詢引擎負責查詢優化,併發控制(上層通過mvcc或者鎖,鎖的狀態也會被下沉到儲存層)

通過查詢層和儲存層解耦合,可以降低系統的複雜度,解耦合之後,我們發現,儲存層和查詢層之間互動,所需的最小方法集就是kv的put和get。

這樣做其實是降低了儲存層的複雜性,把這部分複雜性移植到了查詢層。大概是因為,儲存層比較複雜,工業化產品較少,所以要保證通用性。而查詢層五花八門,各大公司都會基於某個儲存引擎封裝一層查詢層。

10樓:花和尚劉老六

話說,誰說tidb是關係型資料庫的?讓你用SQL不代表就是關係型資料庫呀,底層儲存引擎是個KV引擎呀。至於為啥用KV,因為快啊,O(1)的複雜度啊,跟關係型資料庫的索引是乙個道理啊

11樓:

我認為可能有以下幾個原因

kv邏輯概念有利於遮蔽各檔案系統的差異性;尤其在分布式環境下,更需要乙個邏輯實體來表示儲存關係

另外,在google第乙個如此實現後,後來者就照樣依葫蘆畫瓢了

12樓:

分布式資料庫也有用 page store 的呀, 比如 Aurora, PolarDB.

之所以大家都愛用(有序) KV 是因為 KV 足夠簡單. 當然很多模型 KV 描述起來有些浪費, 比如你說的不要求有序, 那麼直接按約定 hash 分片, 然後線掃行不行?

當然可以, 這個學名叫做 sharding, 線掃然後聚合的也有 map reduce 嘛.

但需求是快速變化的, 今天按 hash 分了, 明天我希望擴容呢? 後天我希望建立精確到 row 的索引呢? 大後天希望快速的有序查詢呢?

所以, 乙個比較通用的方案就是目前的有序 KV Store + 乙個無狀態解析層.

通用帶來的代價就是損失效能, 但反過來開發人員能投入更大的精力去優化, 最後的效果哪個好也難說.

分布式資料庫的分布式事務?

NebulaGraph 業務系統往往是通過子系統組合的模式來完成,這些子系統很可能是不同的資料庫,甚至可能是 友商 的,互相直接無法保證事務,還是得業務自身保證。 codingfor 你說的單機事物,我的理解其實是指single threaded excution,而不是指在單台機器上做事物 暗含了...

在分布式資料庫儲存中,資料分割槽和資料放置有什麼區別?

楊東東 資料分割槽和資料放置是邏輯和物理的關係,邏輯是頂層設計,物理是具體實現,邏輯設計決定物理實現,物理約束反過來影響邏輯設計。舉個例子,給你10個桌球,要求放入3個盒子裡。如何決定哪個球放入哪個盒子?比如 按照編號大小 0 2放入盒子A,3 5放入盒子B,6 9放入盒子C 按照編號特徵 對3取餘...

什麼情況下,需要使用分布式資料庫?

NebulaGraph 首先,分布式資料庫的優勢大致上概括為三種 1,資料分布儲存在不同的節點上,解決了單機下資料量的限制問題 2,分布式計算,均衡了計算負載 3,從資料安全性考慮,分布式資料庫一般都有多副本機制,以此保證了某乙個節點資料壞掉後能正常提供服務。基於以上三點,我認為海量資料的高併發業務...