【數據庫】Redis和RocksDB、levelDB的區別


 

區別

Redis 是一個服務,獨立的進程,用戶的程序需要與它建立連接才能向它發請求,讀寫數據。

RocksDB 和LevelDB 是一個庫,嵌入在用戶的程序中,用戶程序直接調用接口讀寫數據。

 

Redis 是一個遠程內存數據存儲(類似於 memcached)。它是一個服務器。單個 Redis 實例非常高效,但完全不可擴展(就 CPU 而言)。 Redis 集群是可擴展的(就 CPU 而言)。
RocksDB 是一個嵌入式鍵/值存儲(類似於 BerkeleyDB 或更確切地說是 LevelDB)。它是一個庫,支持多線程和基於日志結構合並樹的持久性。

 

總的來說,Redis 比 RocksDB 具有更多的功能。它可以原生地理解復雜數據結構的語義,例如列表和數組。

相比之下,RocksDB 將存儲的值視為一團數據。如果您想進行任何進一步的處理,您需要將數據帶到您的程序中並在那里進行處理(換句話說,您不能將處理委托給數據庫引擎(又名 RocksDB))。
RocksDB 僅在單個服務器上運行。 Redis 有一個集群版本(雖然它不是免費的)
Redis 是為內存計算而構建的,雖然它也支持將數據備份到持久存儲,但主要用例是內存用例。相比之下,RocksDB 通常用於持久化數據,並且在大多數情況下將數據存儲在持久性介質上。
RocksDB 有更好的多線程支持(特別是對於讀——寫仍然受到並發訪問的影響)。

 

https://stackoverflow.com/questions/31831706/redis-vs-rocksdb

 

相關聯

Google 開源NOSQL存儲引擎庫LevelDB ,在它的基礎之上,Facebook 開發出了另一個 NOSQL 存儲引擎庫 RocksDB。沿用了 LevelDB 的先進技術架構的同時還解決了 LevelDB 的一些短板。

 

Redis 緩存有什么問題?


當我們將 Redis 拿來做緩存用時,背后肯定還有一個持久層數據庫記錄了全量的冷熱數據。Redis 和持久層數據庫之間的數據一致性是由應用程序自己來控制的。應用程序會優先去緩存中獲取數據,當緩存中沒有數據時,應用程序需要從持久層加載數據,然后再放進緩存中。當數據更新發生時,需要將緩存置為失效。

function getUser(String userId) User {
User user = redis.get(userId);
if user == null {
user = db.get(userId);
if user != null {
redis.set(userId, user);
}
}
return user;
}

function updateUser(String userId, User user) {
db.update(userId, user);
redis.expire(userId);
}

 

 


嚴格來說我們還需要仔細考慮緩存一致性問題,比如在 updateUser 方法中,數據庫正確執行了更新,但是緩存 redis 因為網絡抖動等原因置為失效沒有成功,那么緩存中的數據就成了過期數據。如果你將設置緩存和更新持久存的先后順序反過來,也還是會有其它問題,這個讀者可以自行思考一下。

 

 

 


在多進程高並發場合也會導致緩存不一致,比如一個進程對某個 userId 調用 getUser() 方法,因為緩存里沒有,它需要從數據庫里加載。結果剛剛加載出來,正准備要設置緩存,這時候發生了內存 fullgc 代碼暫停了一會,而正在此時另一個進程調用了 updateUser 方法更新了數據庫,將緩存置為失效(其實緩存里本來就沒有數據)。然后前面那個進程終於 fullgc 結束要開始設置緩存了,這時候進緩存的就是過期的數據。

LevelDB 是如何解決的?


LevelDB 將 Redis 緩存和持久層合二為一,一次性幫你搞定緩存和持久層。有了 LevelDB,你的代碼可以簡化成下面這樣

function getUser(String userId) User {
return leveldb.get(userId);
}

function updateUser(String userId, User user) {
leveldb.set(userId, user);
}


LevelDB 具體是什么?


前面我們說道它是一個 NOSQL 存儲引擎,它和 Redis 不是一個概念。Redis 是一個完備的數據庫,而 LevelDB 它只是一個引擎。如果將數據庫必須成一輛高級跑車,那么存儲引擎就是它的發動機,是核心是心臟。有了這個發動機,我們再給它包裝上一系列的配件和裝飾,就可以成為數據庫。不過也不要小瞧了配件和裝飾,做到極致那也是非常困難,將 LevelDB 包裝成一個簡單易用的數據庫需要加上太多太多精致的配件。LevelDB 和 RocksDB 出來這么多年,能夠在它的基礎上做出非常一個完備的生產級數據庫寥寥無幾。

在使用 LevelDB 時,我們還可以將它看成一個 Key/Value 內存數據庫。它提供了基礎的 Get/Set API,我們在代碼里可以通過這個 API 來讀寫數據。你還可以將它看成一個無限大小的高級 HashMap,我們可以往里面塞入無限條 Key/Value 數據,只要磁盤可以裝下。

正是因為它只能算作一個內存數據庫,它里面裝的數據無法跨進程跨機器共享。在分布式領域,LevelDB 要如何大顯身手呢?

 

 

 


這就需要靠包裝技術了,在 LevelDB 內存數據庫的基礎上包裝一層網絡 API。當不同機器上不同的進程要來訪問它時,都統一走網絡 API 接口。這樣就形成了一個簡易的數據庫。如果在網絡層我們使用 Redis 協議來包裝,那么使用 Redis 的客戶端就可以讀寫這個數據庫了。

 

 

 

如果要考慮數據庫的高可用性,我們在上面這個單機數據庫的基礎上再加上主從復制功能就可以變身成為一個主從結構的分布式 NOSQL 數據庫。在主從數據庫前面加一層轉發代理(負載均衡器如 LVS、F5 等),就可以實現主從的實時切換。

如果你需要的數據容量特別大以至於單個機器的硬盤都容不下,這時候就需要數據分片機制將整個數據庫的數據分散到多台機器上,每台機器只負責一部分數據的讀寫工作。數據分片的方案非常多,可以像 Codis 那樣通過轉發代理來分片,也可以像 Redis-Cluster 那樣使用客戶端轉發機制來分片,還可以使用 TiDB 的 Raft 分布式一致性算法來分組管理分片。最簡單最易於理解的還是要數 Codis 的轉發代理分片。

 

 

 


當數據量繼續增長需要新增節點時,就必須將老節點上的數據部分遷移到新節點上,管理數據的均衡和遷移的又是一個新的高級配件 —— 數據均衡器。

看到這里讀者應該可以從整體上理解了分布式數據庫中 LevelDB 所處的地位。下一節我們開始全面了解一下 LevelDB 的內存數據庫特性。

 

 


原文鏈接:https://blog.csdn.net/shellquery/article/details/100892922

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM