CouchBase數據庫-一個較新的、發展迅速的nosql數據庫技術
couchbase是一個較新的、發展迅速的nosql數據庫技術。2014年,viber宣布使用couchbase替換mongodb,以適應10億級的用戶量,目前,couchbase已大量運用於生產環境,國內使用的公司主要有新浪,騰訊等。由於中文資料較少,閱讀了官方文檔中的部分介紹後,將資料翻譯和匯總如下。
概述
couchbase是CouchDB和MemBase的合並。而memBase是基於Memcached的。因此couchbase聯合了couchbase的簡單可靠和memcached的高性能,以及membase的可擴展性。
靈活的數據模型:couchbase中使用json格式存儲對象和對象之間的關系。
Nosql數據庫的一個特性是不需要定義數據結構,在couchbase中,數據可以存儲為key-value對或者json文檔,不需要預先定義嚴格的格式,由於這種特性,couchbase支持以 scale out(水平擴展)方式擴展數據量,提升io性能,只需要在集群中添加更多的服務器就行了。相反,關系數據庫管理系統scale up(縱向擴展),通過加更多的CPU,內存和硬盤以擴展容量。
Couchbase可用於單機環境,也可以和其他服務器一起提供分布式的數據存儲。
數據存儲:
Couchbase通過使用buckets提供數據管理服務,buckets相當於關系數據庫中的庫,couchbase中沒有表的概念,保存數據時,先建bucket,然後就直接插入數據了。buckets可以供集群中的多個客戶端程序訪問。couchbase通過Buckets組織,管理和分析數據資源。
couchbase中有兩種類型的數據bucket,當啟動couchbase服務的時候,可以選擇需要的類型。
1)memcached buckets。只將數據存儲在內存中。提供了一個分布式的(橫向擴展),純內存的,key-value緩存。Memcached buckets 設計用於關系數據庫的緩存,可以緩存經常訪問的數據,由此減少web程序中數據庫的查詢次數。
2)couchbase buckets。存數據在內存和硬盤。提供高可用性和可動態重新配置的分布式數據存儲,提供數據持久化和復制服務。couchbase buckets 100% 兼容開源的分布式緩存memcached。
內存配額
Server Quota:
Couchbase服務初始化時會給服務器分配內存限額,表示這個服務器中可用的最大內存,是node級的。初始配置在集群中的第一臺服務器(node)上,所有服務器的內存配額都是一樣的。例如集群中有10臺服務器,服務器內存配額是16G,整個集群中共160G可用內存。如果需要加2個新的服務器,每個新的服務器需要16G的可用內存,集群中可用的內存數將是192G。
Bucket Quota:
Bucket 內存配額是分配給一個bucket的可用內存。配置在每個節點上,是從server quota中分配出去的。例如,如果你創建了一個新的bucket,限額是1GB,在10個節點的集群中,匯總後會有10G。如果添加兩個節點,集群中匯總後會有12G的bucket 限額。
從圖上可以看出,增加新的節點就可以擴展總的可用內存,從而增加存儲的數據量。通過bucket限額系統可以判斷數據是否應該調出內存。
vBucket
vBucket相當於一個key的子集,保存的是客戶端存儲對象的key值,vBuckets 用於在集群的節點間分配數據和備份數據。是couchbase 實現 auto sharding,在線動態增減節點的重要基礎。不是用戶可訪問的組件,但是至關重要。
通過vbucket,客戶端直接訪問保存信息的服務器,不需要通過中間代理或者其他架構,因此可以從數據中抽象出物理拓撲結構。這種方式使couchbase易擴展。
這種架構不同於memcached使用的架構,memcached的做法是用 key 算出一個 hash,得到服務器列表中的對應服務器。這個列表需要動態維護,還需要一個hash算法用於處理集群拓撲結構的變化。
如以下代碼所示:
servers = [‘server1:111‘, ‘server2:112‘, ‘server3:113‘]
server_for_key(key) = servers[hash(key) % servers.length]
這種算法很簡單,也很容易理解,但也有幾個問題:
1、如果一臺服務器失效,會造成該分片的所有 key 失效。
2、如果服務器容量不同,管理非常麻煩。
3、運維、配置非常不方便。
為了把 key 跟服務器解耦,couchbase 引入了 vBucket。每個key都屬於一個vbucket,查找對應的value時先用hash函數計算這個key屬於哪個vbucket,再從vBucket 與服務器對應表中查找這個vbucket屬於哪個服務器,映射表保存vbucket和服務器的對應關系,一個bucket一行,一個服務器可以對應多個vbucket。
1、key hash 對應一個 vBucket,不再直接對應服務器。
2、集群維護一個全局的 vBucket 與服務器對應表。
例如,集群中有3個服務器,客戶端要查找 一個key對應的value值,首先計算key屬於哪個Vbucket,在這個例子中,hash結果是vB8 ,通過查映射表,客戶端確定vB8對應到服務器C,然後get操作直接發送到服務器C。
一段時間後,需要加一個新的服務器D到集群,vbuckets映射表更新為:
這時,客戶端再想取key對應的value值,hash算法結果仍為vB8,但是新的映射表會將vB8映射到服務器D。
由於 vBucket 把 key 跟服務器的靜態對應關系解耦合,基於 vBucket 可以實現一些非常強大有趣的功能,例如:
Replica,以 vBucket 為單位的主從備份。如果某個節點失效,只需要更新 vBucket 映射表,馬上啟用備份數據。
動態擴容。新增加一個節點後,可以把部分 vBucket 轉移到新節點上,並更新 vBucket 映射表。
緩存層
Couchbase自動管理緩存層,確保有足夠的內存空間以維持性能。couchbase後臺有個進程,專門把一定時間沒有被訪問的數據移出內存,這個進程的掃描時間和數據的最大無活動時間都是可以設置的。couchbase在對數據進行增刪時會先體現在內存中,而不會立刻體現在硬盤上,從內存的修改到硬盤的修改這一步驟是由couchbase自動完成,等待執行的硬盤操作會以write queue的形式排隊等待執行,也正是通過這個方法,硬盤的I/O效率在write queue滿之前是不會影響couchbase的吞吐效率的,而write queue的長度是可以設置的。通過write queue執行大量寫數據庫操作時用戶可能會感受到很短時間的內存飆升,但是異步特性和queue的使用使讀寫速度都非常快。
對於所有文檔couchbase都會建立一個額外的56byte的metadata,這個metadata功能之一就是表明數據狀態是否活動在內存中。同時文檔的id也作為標識符和metadata一起長期活動在內存中。這表示對文檔id不存在的情況服務器可以直接返回‘文檔id不存在。couchbase官方建議bucket申請的內存中,metadata和key所占用的內存不應超過一半,否則couchbase的性能會顯著下降。為了保證這個條件,當有效數據占用超過一定內存時就需要把超額數據移除了。
這裏有低水位和高水位的概念,也就是說當移除數據過多以至於內存中有效數據占用內存低於低水位的時候,couchbase會隨機挑一些文件到內存中以達到低水位。當有效數據內存占用超過高水位時,couchbase就會移除數據。高低水位都是可以設置的。
隨著內存數據越來越多,會逐漸到達低水位,這時候,系統不會做任何處理。當數據量持續增加,到達高水位時,系統會啟動一個job任務移除數據,當到達低水位時任務停止。如何進入數據的速度大於移除數據的速度,系統會返回空間不足的錯誤提示,直到有足夠的內存為止。
如果只使用memcached buckets,服務器只提供數據緩存,不會持久化到硬盤。如果服務器內存空間不足,系統會使用LRU算法從內存中Eviction 數據,Eviction表示服務器會移除一個數據項的key,metadata和所有其他信息。Eviction後,數據將無法恢復。
硬盤存儲
考慮到性能,couchbase服務主要使用緩存為客戶端保存和返回信息,同時會逐漸將數據保存到硬盤以維持高可靠性。如果有節點fail了可以直接從硬盤恢復數據,數據是逐漸持久化到硬盤的,同時保存到緩存層和硬盤write queue,不會阻塞客戶線程。當客戶端訪問一個不在內存的數據時,持有load queue的進程會將數據讀到內存,在數據返回之前客戶端需要等待。
多線程讀寫:之前的couchbase版本,讀寫硬盤的線程只有一個。為了提高讀寫硬盤的速度和提高緩存命中率,現在couchbase提供了多線程讀寫。
多線程讀寫需要考慮線程之間的同步問題以避免沖突。為了維持性能和避免沖突,couchbase對每個線程訪問的資源進行了靜態分配,同時使用了資源鎖。當創建多個讀寫線程時,服務器為每個線程單獨分配了不同的vbuckets。通過這種靜態協調方式,可以保證同一個vbuckets只有一個讀線程和一個寫線程可以訪問。上圖表示6個線程和兩個數據vbucket。每個線程有預先分配的可讀寫範圍。
Rebalancing
Couchbase 服務器上數據的分配方式是通過vbucket結構實現的,如果想增加或減少集群中的機器,vbuckets中存儲的數據都需要重新分配,vBucket map(映射表)也需要更新以適應新的集群結構。
Rebalancing 是集群結構發生變化時的數據調整,需要手動操作,這個過程改變vbuckets到服務器的分配,需要在服務器節點之間遷移數據以適應新的結構。
Rebalancing過程可以發生在集群運行和提供服務時,客戶端使用現有架構讀寫數據,同時後端在節點之間遷移數據。一旦這個過程完成, 更新vBucket map表,並通知smart clients和代理服務(MOxi).
Rebalancing後數據在集群中重新分配,因此數據被均勻分配到整個數據庫,這個過程需要考慮數據和數據的副本。
總結
數據存儲:nosql,易水平擴展。
緩存層:低水位和高水位設置,文檔metadata。
vBucket:使系統易於動態管理,自動分片,reblancing。
多線程持久化:預分配每個線程的訪問範圍,保證性能和可靠性。
CouchBase數據庫-一個較新的、發展迅速的nosql數據庫技術