Riak 是一個 erlang 開發的開源的分佈式 key-value 數據庫,
在 High Availability
, Fault Tolerance
, Scalability
方面表現優異。
其實現受 Amazon Dynamodb 啓發,是一個頗有表明性的分佈式數據庫。node
Riak 集羣是一個去中心化的集羣。每一個服務器節點都是平等的,能夠自由地添加和刪除。
這使得 Riak 的故障轉移(Failure Over)和擴展很是容易。
在 CAP 理論方面,Riak 能夠自由地在 CP 和 AP 之間作平衡。數據庫
下面仍是讓咱們從簡單的例子開始,來理解下 Riak 的分佈式數據庫模型,包括數據的存儲,節點服務器的,CAP理論的關係等。服務器
首先讓咱們先定義一個概念:N
,表示數據的"份數"。在分佈式數據庫中,一份數據每每會存儲多份拷貝(所謂冗餘,或者 replications)分佈式
如今,假設咱們有一個服務器節點(node1),存有三個數據(key分別是 P0, P1, P2),N = 1。那麼能夠想象,這三個數據都是存放在 node1 中。以下圖所示:函數
當 N = 2 時,假設 P0, P1, P2 的冗餘數據分別是 R0, R1, R2, 那麼能夠想象,這6個數據也應該都存儲在 node1 中,如 下圖所示:spa
這時候,讓咱們把服務器節點增長到2個(node1, node2),那麼能夠想象,6個數據有不少中組合方式,例以下面這兩種:code
也許你發現了,他們有個共同點:同一個數據的冗餘數據放在不一樣的服務器節點中。這樣就算一個節點刪除(當機)了,集羣的數據仍然能保證完整性。
這爲故障轉移(Failure over)提供了基礎。ip
那麼如今的問題來了,是否有什麼科學(公式化)的方式來找到分配這些數據的組合(之一)呢?開發
Riak 經過被稱做 Riak Ring
的東西來解決這個問題。get
首先,Riak 將全部的 key 經過 hash 函數映射到一個 160 bit 的整數空間中。
即一個 key 對應着一個 0 ~ 2^160 - 1 的整數。
而後,Riak 引入了 vnode(虛擬節點) 的概念,vnode 個數是能夠配置的,默認是 64。
160 bit 的整數會均勻的分佈到全部的 vnode。
最後,這些 vnode 會"均勻地"分配到 物理節點上。具體的分配的方法很巧妙,經過 Riak Ring
這樣的東西。
下面咱們用一幅圖來具體解釋下 Riak Ring
。圖中,假設 vnode 32 個,服務器節點 4個。
讓咱們把 160 bit 想像成一個環,環上的一小段表明一個 vnode。四種顏色分別表明 4 個服務器節點。
2^160 個整數按照從小到大的順序均勻地分佈到 32 個 vnode 中,例如 2^159 是第 17 個 vnode 上的第一個整數。
32 個 vnode 按照從小到大的順序依次被分配到 4 個服務器節點上。即:
如今還剩下一個問題:
冗餘數據的存儲
咱們先假設 N = 3(即有2份冗餘存儲)
假設要存儲的數據,key 爲 test-key
,根據 Riak Ring 算出來,應該存儲在 vnode6(即:node2)上。
那麼 拷貝1 存儲在 vnode7(即:node3)上,拷貝2 存儲在 vnode8(即:node4)上。
因此 Riak 對於冗餘數據的存儲策略是:將冗餘數據依次存到下一個vnode中。