你需要一個經(jīng)典數(shù)據(jù)庫嗎?
一段時間以來,巨大數(shù)量的數(shù)據(jù)處理迫使所有的應用程序在數(shù)據(jù)庫層前添加緩存策略。即使經(jīng)典數(shù)據(jù)庫進行了大量的下劃線優(yōu)化,仍然不能提供足夠的速度和可用性。主要原因在于數(shù)據(jù)存儲越遠,獲取數(shù)據(jù)就越困難。另一個原因是因為數(shù)據(jù)庫中的數(shù)據(jù)通常保存在磁盤中,而不是在內(nèi)存。經(jīng)典數(shù)據(jù)庫卻是在內(nèi)存上嵌入了緩存來優(yōu)化,但是擁有一個專用的獨立緩存也是一種很常用的策略。
在解決訪問數(shù)據(jù)庫的性能問題,通常的解決方案是緩存。緩存并不新鮮,緩存實際上是把經(jīng)常訪問的少量數(shù)據(jù)保存在離你更近的地方。我們在處理器上有緩存,數(shù)據(jù)庫中也有緩存,你甚至可以在自己的應用中編寫緩存。
但隨著事情的發(fā)展,現(xiàn)在我們有來高可用的分布式內(nèi)存緩存,可以被不同的實例同時使用。
緩存——Redis
也許最流行的分布式內(nèi)存數(shù)據(jù)存儲是Redis,它不是緩存,但被當作緩存使用。 引用官方的描述如下:
Redis是一個開源的(BSD協(xié)議),內(nèi)存中的數(shù)據(jù)結(jié)構存儲,它可以用作數(shù)據(jù)庫,緩存,消息代理。它支持的數(shù)據(jù)結(jié)構包括字符串,哈希,列表,集合,有序集合,位圖,超級日志,具有半徑查詢和流的地理空間索引和流,Redis具有內(nèi)置復制,Lua腳本,LRU驅(qū)逐,事務和不同級別的磁盤持久化,并通過Redis哨兵和Redis集群自動分區(qū)。
Redis速度很快,它被認為是目前最快的數(shù)據(jù)存儲之一。它對CPU緩存進行了優(yōu)化,并且沒有上下文切換。從一開始它就被設計成了內(nèi)存數(shù)據(jù)庫,這不僅意味著將數(shù)據(jù)從磁盤移動到內(nèi)存,它從一開始就針對性的優(yōu)化了。
由于Redis速度非??欤梢源鎯Ω鞣N數(shù)據(jù)結(jié)構,因此它是分布式緩存的一個很好的備選。
因為作為緩存,Redis獲得了非常高的人氣。有一些緩存加載器庫在使用Redis作為應用程序和數(shù)據(jù)庫之間的緩存層。以Redisson地圖加載器為例:
因此,使用分布式緩存可以極大的提高性能。但是代碼和架構變得更復雜了。數(shù)據(jù)被復制到數(shù)據(jù)庫和緩存中,我們必須保持它們的數(shù)據(jù)同步。代碼應該管理整個緩存策略,控制緩存失效,重新填充緩存,都是為了保持數(shù)據(jù)的一致性。我們實現(xiàn)了更高的性能和可伸縮性,但引入了高風險的復雜性。
數(shù)據(jù)是重復的
你可能會問為什么要在兩個地方都保存數(shù)據(jù)?不能只保存Redis中的數(shù)據(jù)嗎?如果這樣做我們可以減少代碼的復雜性。但首先讓我們看看經(jīng)典數(shù)據(jù)庫的一下特點和優(yōu)勢,看看我們是否可以直接使用Redis實現(xiàn)這些。
關系型數(shù)據(jù)庫的優(yōu)點
傳統(tǒng)來說,緩存是不會長期保存數(shù)據(jù)的。我們將數(shù)據(jù)保存在緩存中只是為了快速的訪問,但是為了長時間的持久性,我們通常使用一個中央數(shù)據(jù)庫。
除了數(shù)據(jù)的持久性以外,關系型數(shù)據(jù)庫提供了數(shù)據(jù)一致性等其他特點。使用關系型數(shù)據(jù)庫,你可以定義數(shù)據(jù)間的關系,約束,復雜查詢,構建它是為了保證多個相關表間的一致性。
它有一些重要的優(yōu)勢,即使NoSQL數(shù)據(jù)庫很流行,關系型數(shù)據(jù)庫也不會很快消失。
但是使用Redis作為緩存和關系型數(shù)據(jù)庫搭配使用,增加了一層復雜性,因為你必須通過代碼保持兩者的數(shù)據(jù)同步。
考慮到你的緩存策略,你不得不構建一些復雜的代碼在Redis和數(shù)據(jù)庫間進行數(shù)據(jù)發(fā)送。不要誤解我的意思,有時候你必須這么做。就像之前提到的,關系型數(shù)據(jù)庫有它的優(yōu)點,我們不能把它扔掉。
但是我們必須每次都這么做嗎?如果不同數(shù)據(jù)間不需要非常復雜的關系,而只存儲一個鍵映射就足夠了呢?我們是不是可以不用關系型數(shù)據(jù)庫了?
Redis作為中央數(shù)據(jù)存儲
如前所述,關系型數(shù)據(jù)庫的優(yōu)點是一致性和持久性。如果我們不需要數(shù)據(jù)之間的關系映射,那么它將只保留持久性。有很多NoSQL數(shù)據(jù)庫提供鍵映射存儲,但我們可以直接使用Redis。
Redis持久化
Redis有兩種持久化模型:RDB和AOF。
RDB在指定的時間間隔保存數(shù)據(jù)快照。它們非常適合快速恢復備份。RDB最大化了Redis的性能,因為父進程所做的唯一工作就是fork創(chuàng)建快照的子進程。
但是由于RDB在一定時間間隔執(zhí)行計劃,如果你無法承受丟失一些數(shù)據(jù),那么這就不是一個好的選擇。fork是一個高成本的操作,不能在每次數(shù)據(jù)變化都進行fork,因此可能會出現(xiàn)最近的數(shù)據(jù)沒有被保存在快照中的情況。
AOF是一個不同的持久化模型。它是由一個只能追加的文件組成,只在其中添加所有數(shù)據(jù)。它更持久,因為fsync策略通常比整個RDB更有計劃性。由于該文件僅用于追加,因此數(shù)據(jù)是不可更改的。即使在最后一條數(shù)據(jù)沒有完全寫完而出現(xiàn)斷電,也可以很容易的重新斷電前的構建狀態(tài)。
但是它也有缺點。第一個是AOF文件通常比RDB更大。另外,如果fsync策略被調(diào)度的太頻繁,舉個例子,在每次寫命令之后,那么性能會大打折扣。在默認情況下,fsync每秒運行一次。
你應該使用哪個?
如果你想要一個類似Postgres提供的安全級別,你將不得不兩種情況都使用。使用RDB可以讓你在重啟后更快的恢復備份;使用AOF可以避免數(shù)據(jù)丟失。但是如果你能承受一些數(shù)據(jù)損失,那可以只使用RDB。記住,Redis會把它們合并成一個單一的持久化模型。
其他優(yōu)勢
未來是屬于字節(jié)尋址的
由于磁盤旋轉(zhuǎn)在很長一段時間都是持久化單元,所以當前的大多數(shù)數(shù)據(jù)庫仍然在適應磁盤的旋轉(zhuǎn)方面進行優(yōu)化。比如數(shù)據(jù)定位,以減少磁盤旋轉(zhuǎn)滯后,甚至選擇了專門的格式,將索引放在了盤片的特定部分。但是這些優(yōu)化對于當前的技術,比如SSD,是沒有意義的。Redis存儲數(shù)據(jù)是為字節(jié)尋址優(yōu)化的。未來是屬于字節(jié)尋址的,而Redis已經(jīng)在那里了。
可伸縮性和高可用性
Redis提供了不同的方式來實現(xiàn)伸縮性和高可用性。
你可以在不同的Redis節(jié)點上分割數(shù)據(jù)來實現(xiàn)水平的可擴展性。分片將減輕單個實例的負擔,你將受益于多核和計算能力。但是你應該知道分片的局限性,因為不能支持多鍵操作和事務。
通過復制獲得高可用性。主節(jié)點是同步復制的,可以免受節(jié)點故障,數(shù)據(jù)中心故障和Redis進程故障。如果主節(jié)點宕機,副節(jié)點將會取而代之。在不同的AZ中也有一個副本,這將保護你免受災難時間的影響,比如整個AZ失敗。
如果你打算使用Redis企業(yè)集群,所有的這些對你都是抽象的,你將擁有分片和高可用性,而不需要額外的代碼。你可以通過編碼連接到一個Redis實例。
復雜數(shù)據(jù)結(jié)構
Redis不僅可以處理字符串,還可以處理不同的數(shù)據(jù)結(jié)構,如:二進制安全字符串,列表,集合,排序集合,位圖,超級日志,流等等。這使得Redis不僅是一個鍵值存儲,更是一個完整的數(shù)據(jù)結(jié)構服務器。
不是銀彈
一切聽起來都非常棒,但是作為一個事實,沒什么東西是銀彈,Redis也不是。主要的缺點是所有的數(shù)據(jù)都應該裝進內(nèi)存中。這使Redis適合那些有足夠內(nèi)存進行存儲的數(shù)據(jù)。如果沒有,那就必須將數(shù)據(jù)拆分。但是你會失去一下保證,如事務,管道,或發(fā)布/訂閱。
結(jié)論
在很長一段時間里,Redis被認為只是一個緩存。一個非常好的分布式緩存,但仍然只是一個應用程序和主數(shù)據(jù)庫之間的緩存。正如你所看到的,Redis不僅僅是一個緩存,它試圖擺脫這個誤解。Redis不是一個緩存,它是一個分布式數(shù)據(jù)存儲。它可以以線程安全模式以令人難以置信的速度處理不同的數(shù)據(jù)結(jié)構,并為數(shù)據(jù)持久性提供了不同的機制。
考慮到所有這些,即使Redis被非常成功地用作緩存,它還是可以做更多的事情。如果你不需要一些像關系數(shù)據(jù)和高存儲的SQL屬性,為什么你要在應用程序中創(chuàng)建一個復雜的三層系統(tǒng)?Redis作為緩存和還是數(shù)據(jù)庫?在這些情況下,你可以只使用Redis作為主要的持久層。
原文鏈接:https://dzone.com/articles/redis-is-not-just-a-cache
到此這篇關于Redis不僅僅是緩存,還是……的文章就介紹到這了,更多相關Redis 緩存 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
您可能感興趣的文章:- java操作Redis緩存設置過期時間的方法
- Redis緩存及熱點key問題解決方案
- SpringBoot2整合Redis緩存三步驟代碼詳解
- SpringBoot Redis緩存數(shù)據(jù)實現(xiàn)解析
- spring boot注解方式使用redis緩存操作示例
- Spring Cache手動清理Redis緩存