聊聊數(shù)據(jù)存儲系統(tǒng)Couchbase與Redis
背景
Redis 和Couchbase都是基于內存的數(shù)據(jù)存儲系統(tǒng)。在它們各自的官方描述中,Couchbase是高性能,高伸縮性和高可用的分布式緩存系統(tǒng);Redis是一個開源的內存數(shù)據(jù)結構存儲系統(tǒng)。
Couchbase
介紹
2012年2月,CouchOne與Membase合并,Couchbase基于Membase與CouchDB開發(fā)了一款新產品。 CouchBase是一款開源的、分布式的、面向文檔的NoSQL數(shù)據(jù)庫,主要用于分布式緩存和數(shù)據(jù)存儲領域,Membase 是 NoSQL 家族的一個新的重量級的成員,它是個鍵/值、持久化、可伸縮的解決方案,使用了memcached wire協(xié)議。CouchOne支持CouchDB。CouchDB是個文檔數(shù)據(jù)庫,提供了端到端的復制方法,這對于移動與分布在不同位置的數(shù)據(jù)中心來說是很有用的。CouchBase能夠通過manage cache提供快速的亞毫米級別的k-v存儲操作,并且提供快速的查詢和其功能強大的能夠指定SQL-like查詢的查詢引擎。Couchbase是一個較新的、發(fā)展迅速的nosql數(shù)據(jù)庫技術。
特點
couchbase是一個非關系型數(shù)據(jù)庫,它實際上是由couchdb+membase組成,所以它既能像couchdb那樣存儲json文檔,也能像membase那樣高速存儲鍵值對。主要有以下幾個特點:
- 速度快:由于是內存優(yōu)先的高性能設計,所有的讀寫操作都是直接操作內存,因此速度非??臁?/li>
- 高可用:主要從兩個方面,一個是它自帶集群方案,支持多副本模式,另一個是它自帶持久化方案,可以設置定時把數(shù)據(jù)異步寫到文件系統(tǒng)上。
- 配置使用方便:安裝后自帶web管理臺,可以在管理臺上對集群、桶、索引、搜索等進行管理和操作,大量減輕運維的工作,使用簡單。
- 快速構建:Couchbase 使開發(fā)人員能夠構建響應迅速且靈活的云、移動和邊緣計算應用程序,這些應用程序可以輕松擴展。
數(shù)據(jù)模型
Couchbase 數(shù)據(jù)模型基于 JSON,它支持基本的數(shù)據(jù)類型,例如數(shù)字和字符串;和復雜類型,例如嵌入式文檔和數(shù)組,單個Document通常代表應用程序代碼中對象的單個實例。一個Document可能被認為等同于關系型數(shù)據(jù)庫中的一行;每個Document的屬性都相當于一列。然而,Couchbase 提供了比關系數(shù)據(jù)庫更大的靈活性,因為它可以存儲具有不同模式的 JSON 文檔。Document可以包含嵌套結構,這允許開發(fā)人員表達多對多關系,而不需要引用或join表。
buckets
buckets是couchbase中組織數(shù)據(jù)的一種方式,類似于關系型數(shù)據(jù)庫中的databse,一個集群最多可以創(chuàng)建30個buckets。每個存儲buckets必須指定為以下三種類型之一。
- Couchbase buckets:這些類型數(shù)據(jù)持久存儲在內存和硬盤中。它們允許使用DCP(Database Change Protocol) 自動復制數(shù)據(jù)以實現(xiàn)高可用性;并通過XDCR (Cross Data Center Replication)跨多個集群動態(tài)擴展。
- Ephemeral buckets:這是 Couchbase buckets的替代方案,可在不需要持久性時使用。數(shù)據(jù)僅在內存中。
- Memcached buckets:只存儲在內存中,遵循Memcached協(xié)議,現(xiàn)在已經棄用。
同步協(xié)議
DCP (Database Change Protocol),DCP 協(xié)議是一個高效的二進制協(xié)議,它主要用于集群內的數(shù)據(jù)復制、索引復制、備份數(shù)據(jù)等等。主要概念有以下幾點:
- 有序復制,基于每個vbucket存在一個順序序列號,同步時根據(jù)序列號進行更新。
- 重啟恢復,當同步連接中斷后,重新連接后,會對沖突數(shù)據(jù)進行恢復。
- 一致性,使用快照數(shù)據(jù)同步數(shù)據(jù)統(tǒng)一性。
- 內存間復制。
XDCR (Cross Data Center Replication),XDCR提供了多個有效vbucket的數(shù)據(jù)的復制,主要用于跨數(shù)據(jù)中心的多集群間的復制,可以跨版本復制。主要概念有以下幾點:
- 基于bucket復制,兩個集群的同一個bucket可以實現(xiàn)單向或者雙向復制。
- 通過DCP協(xié)議保持持續(xù)性復制,一個XDCR連接中包括多個DCP數(shù)據(jù)流。這些流可以根據(jù)不同的分區(qū)對目的集群進行同步復制。
- 支持多種集群拓撲復制。集群間可以通過單向,雙向復制。多個集群可以實現(xiàn)1對1,1對多,多對1等的集群復制拓撲圖。
- 安全復制。數(shù)據(jù)中心見傳輸數(shù)據(jù)可以使用SSL進行加密。
- 最終一致性和解決數(shù)據(jù)沖突的能力。當出現(xiàn)沖突數(shù)據(jù),會使用元數(shù)據(jù)的序列值,CAS值,文檔標簽和過期時間限制對數(shù)據(jù)進行沖突解決。
服務
Couchbase 服務器提供以下服務:
- Data service(數(shù)據(jù)服務):數(shù)據(jù)服務提供完全集成的內存緩存層,提供高速數(shù)據(jù)訪問,支持鍵指定的數(shù)據(jù)項的存儲、設置和檢索。
- Query service(查詢服務):類sql查詢語言獲取結果,還可以針對數(shù)據(jù)定義(定義索引)和數(shù)據(jù)操作(添加或刪除數(shù)據(jù))發(fā)出查詢。
- Index service(索引服務):創(chuàng)建索引,為Analytics和Query使用,索引服務支持為存儲在 Couchbase 集群中的項目,創(chuàng)建主索引和二級索引。
- Analytics service(分析服務):分析服務提供并行數(shù)據(jù)管理功能,允許運行復雜的分析查詢,適用于大數(shù)量,運行時間長,資源消耗比較大。
- Search Service (搜索服務):搜索服務為集群數(shù)據(jù) 提供全文索引和搜索引擎功能。
- Event Service(事件服務):支持對數(shù)據(jù)更改的近乎實時的處理:代碼既可以響應文檔突變而執(zhí)行,也可以按照計時器的調度執(zhí)行。
- Backup Service(備份服務):支持計劃完整和增量數(shù)據(jù)備份,既可以針對特定的單個存儲桶,也可以針對集群上的所有存儲桶。
Redis
介紹
Remote DIctionary Server(Redis) 是一個由Salvatore Sanfilippo寫的key-value存儲系統(tǒng),它 是一個開源(BSD許可)的內存型數(shù)據(jù)存儲系統(tǒng),支持網絡、可基于內存亦可持久化的日志型、Key-Value數(shù)據(jù)庫,并提供多種語言的AP以及豐富的數(shù)據(jù)結構,它可以用作數(shù)據(jù)庫、緩存和消息中間件。并支持事務、發(fā)布訂閱、lua腳本、lru驅動事件、過期機制、自動故障轉移等多種功能,由于Redis 是用ANSI C編寫的,可在大多數(shù) POSIX 系統(tǒng)(如 Linux、*BSD 和 OS X)中運行,無需外部依賴。
特點
- 內存數(shù)據(jù)庫,速度快,也支持數(shù)據(jù)的持久化,可以將內存中的數(shù)據(jù)保存在磁盤中,重啟的時候可以再次加載進行使用。
- Redis不僅僅支持簡單的key-value類型的數(shù)據(jù),同時還提供list,set,zset,hash等數(shù)據(jù)結構的存儲。
- Redis支持數(shù)據(jù)的備份,即master-slave模式的數(shù)據(jù)備份。
- Redis的所有數(shù)據(jù)存儲在內存中,對數(shù)據(jù)的更新將異步地保存到磁盤上。
- 功能豐富。除了支持五種數(shù)據(jù)結構之外,還支持事務、流水線、發(fā)布/訂閱、消息隊列等功能。
- (服務架構)支持高可用和分布式。
持久化
redis 提供了兩種持久化的方式,分別是RDB(Redis DataBase)和AOF(Append Only File)。
- RDB,簡而言之,就是在不同的時間點,將 redis 存儲的數(shù)據(jù)生成快照并存儲到磁盤等介質上。
- AOF,則是換了一個角度來實現(xiàn)持久化,那就是將 redis 執(zhí)行過的所有寫指令記錄下來,在下次 redis 重新啟動時,只要把這些寫指令從前到后再重復執(zhí)行一遍,就可以實現(xiàn)數(shù)據(jù)恢復了。
其實 RDB 和 AOF 兩種方式也可以同時使用,在這種情況下,如果 redis 重啟的話,則會優(yōu)先采用 AOF 方式來進行數(shù)據(jù)恢復,這是因為 AOF 方式的數(shù)據(jù)恢復完整度更高。如果你沒有數(shù)據(jù)持久化的需求,也完全可以關閉 RDB 和 AOF 方式,這樣的話,redis 將變成一個純內存數(shù)據(jù)庫,就像 memcache 一樣。
集群管理
Redis在3.0版本以后開始支持集群,經過中間幾個版本的不斷更新優(yōu)化,最新的版本集群功能已經非常完善,Redis 集群是一個提供在多個Redis間節(jié)點間共享數(shù)據(jù)的程序集,集群節(jié)點共同構建了一個去中心化的網絡,集群中的每個節(jié)點擁有平等的身份,節(jié)點各自保存各自的數(shù)據(jù)和集群狀態(tài)。節(jié)點之間采用Gossip協(xié)議進行通信,保證了節(jié)點狀態(tài)的信息同步。Redis 集群數(shù)據(jù)通過分區(qū)來進行管理,每個節(jié)點保存集群數(shù)據(jù)的一個子集。數(shù)據(jù)的分配采用一種叫做哈希槽(hash slot)的方式來分配,和傳統(tǒng)的一致性哈希不太相同。Redis 集群有16384個哈希槽,每個key通過CRC16校驗后對16384取模來決定放置哪個槽。為了使在部分節(jié)點失敗或者大部分節(jié)點無法通信的情況下集群仍然可用,集群使用了主從復制模型。讀取數(shù)據(jù)時,根據(jù)一致性哈希算法到對應的 master 節(jié)點獲取數(shù)據(jù),如果master 掛掉之后,會啟動一個對應的 salve 節(jié)點來充當 master 。在redis3.0以前的版本要實現(xiàn)集群一般是借助哨兵sentinel工具來監(jiān)控master節(jié)點的狀態(tài),如果master節(jié)點異常,則會做主從切換,將某一臺slave作為master,哨兵的配置略微復雜,并且性能和高可用性等各方面表現(xiàn)一般,特別是在主從切換的瞬間存在訪問瞬斷的情況,而且哨兵模式只有一個主節(jié)點對外提供服務,沒法支持很高的并發(fā),且單個主節(jié)點內存也不宜設置得過大,否則會導致持久化文件過大,影響數(shù)據(jù)恢復或主從同步的效率。
總結
其實不論是在大塊數(shù)據(jù)還是大數(shù)據(jù)量的處理上,Couchbase都要優(yōu)于Redis,很多平臺都是采用Couchbase來管理數(shù)千萬熱數(shù)據(jù)。所以,如果緩存大多數(shù)情況下僅僅需要提供數(shù)據(jù)新增和查詢操作,那Couchbase基于文檔類型的存儲結構能夠始終如一地為提供亞毫秒的查詢體驗,對于預定義的數(shù)據(jù)類型你還可以通過創(chuàng)建索引進一步優(yōu)化性能,這種情況下,Couchbase無疑是你更好的選擇。
- Redis支持服務器端的數(shù)據(jù)操作:Redis相比Couchbase來說,擁有更多的數(shù)據(jù)結構和并支持更豐富的數(shù)據(jù)操作,通常在Couchbase里,你需要將數(shù)據(jù)拿到客戶端來進行類似的修改再set回去(你需要先先通過get方法從服務器讀取數(shù)據(jù)文檔,并將文檔反序列化為json對象,之后修改json對象對應屬性,再通過set方法將數(shù)據(jù)寫入服務器,序列化后進行存儲)。這大大增加了網絡IO的次數(shù)和傳輸中的數(shù)據(jù)體積。在Redis中,這些復雜的操作通常和一般的GET/SET一樣高效。
- 內存使用效率對比:使用簡單的key-value存儲的話,Couchbase的內存利用率更高,而Redis采用hash結構來做key-value存儲,由于其組合式的壓縮,其內存利用率會高于Couchbase。所以,如果需要緩存能夠支持更復雜的數(shù)據(jù)結構和更頻繁數(shù)據(jù)的部分更新操作,那么Redis會是不錯的選擇。(下文會在關于數(shù)據(jù)存儲模型來證明這一點)。
- 性能對比:由于Redis只使用單核,而Couchbase可以使用多核,所以平均每一個核上Redis在存儲小數(shù)據(jù)時比Couchbase性能更高。而在100k以上的數(shù)據(jù)中,Couchbase性能要高于Redis,雖然Redis最近也在存儲大數(shù)據(jù)的性能上進行優(yōu)化,但是比起Couchbase,還是稍有遜色。