Redis不單單是緩存,仍是……

你須要一個經典數據庫嗎?redis

一段時間以來,巨大數量的數據處理迫使全部的應用程序在數據庫層前添加緩存策略。即便經典數據庫進行了大量的下劃線優化,仍然不能提供足夠的速度和可用性。主要緣由在於數據存儲越遠,獲取數據就越困難。另外一個緣由是由於數據庫中的數據一般保存在磁盤中,而不是在內存。經典數據庫倒是在內存上嵌入了緩存來優化,可是擁有一個專用的獨立緩存也是一種很經常使用的策略。數據庫

在解決訪問數據庫的性能問題,一般的解決方案是緩存。緩存並不新鮮,緩存其實是把常常訪問的少許數據保存在離你更近的地方。咱們在處理器上有緩存,數據庫中也有緩存,你甚至能夠在本身的應用中編寫緩存。緩存

但隨着事情的發展,如今咱們有來高可用的分佈式內存緩存,能夠被不一樣的實例同時使用。安全

緩存——Redis服務器

也許最流行的分佈式內存數據存儲是Redis,它不是緩存,但被看成緩存使用。 引用官方的描述以下:數據結構

Redis是一個開源的(BSD協議),內存中的數據結構存儲,它能夠用做數據庫,緩存,消息代理。它支持的數據結構包括字符串,哈希,列表,集合,有序集合,位圖,超級日誌,具備半徑查詢和流的地理空間索引和流,Redis具備內置複製,Lua腳本,LRU驅逐,事務和不一樣級別的磁盤持久化,並經過Redis哨兵和Redis集羣自動分區。架構

Redis速度很快,它被認爲是目前最快的數據存儲之一。它對CPU緩存進行了優化,而且沒有上下文切換。從一開始它就被設計成了內存數據庫,這不只意味着將數據從磁盤移動到內存,它從一開始就針對性的優化了。分佈式

因爲Redis速度很是快,能夠存儲各類數據結構,所以它是分佈式緩存的一個很好的備選。性能

由於做爲緩存,Redis得到了很是高的人氣。有一些緩存加載器庫在使用Redis做爲應用程序和數據庫之間的緩存層。以Redisson地圖加載器爲例:優化

所以,使用分佈式緩存能夠極大的提升性能。可是代碼和架構變得更復雜了。數據被複制到數據庫和緩存中,咱們必須保持它們的數據同步。代碼應該管理整個緩存策略,控制緩存失效,從新填充緩存,都是爲了保持數據的一致性。咱們實現了更高的性能和可伸縮性,但引入了高風險的複雜性。

數據是重複的

你可能會問爲何要在兩個地方都保存數據?不能只保存Redis中的數據嗎?若是這樣作咱們能夠減小代碼的複雜性。但首先讓咱們看看經典數據庫的一下特色和優點,看看咱們是否能夠直接使用Redis實現這些。

關係型數據庫的優勢 

傳統來講,緩存是不會長期保存數據的。咱們將數據保存在緩存中只是爲了快速的訪問,可是爲了長時間的持久性,咱們一般使用一箇中央數據庫。

除了數據的持久性之外,關係型數據庫提供了數據一致性等其餘特色。使用關係型數據庫,你能夠定義數據間的關係,約束,複雜查詢,構建它是爲了保證多個相關表間的一致性。

它有一些重要的優點,即便NoSQL數據庫很流行,關係型數據庫也不會很快消失。

可是使用Redis做爲緩存和關係型數據庫搭配使用,增長了一層複雜性,由於你必須經過代碼保持二者的數據同步。

考慮到你的緩存策略,你不得不構建一些複雜的代碼在Redis和數據庫間進行數據發送。不要誤解個人意思,有時候你必須這麼作。就像以前提到的,關係型數據庫有它的優勢,咱們不能把它扔掉。

可是咱們必須每次都這麼作嗎?若是不一樣數據間不須要很是複雜的關係,而只存儲一個鍵映射就足夠了呢?咱們是否是能夠不用關係型數據庫了?

 Redis做爲中央數據存儲

 如前所述,關係型數據庫的優勢是一致性和持久性。若是咱們不須要數據之間的關係映射,那麼它將只保留持久性。有不少NoSQL數據庫提供鍵映射存儲,但咱們能夠直接使用Redis。

Redis持久化

Redis有兩種持久化模型:RDB和AOF。

RDB在指定的時間間隔保存數據快照。它們很是適合快速恢復備份。RDB最大化了Redis的性能,由於父進程所作的惟一工做就是fork建立快照的子進程。

可是因爲RDB在必定時間間隔執行計劃,若是你沒法承受丟失一些數據,那麼這就不是一個好的選擇。fork是一個高成本的操做,不能在每次數據變化都進行fork,所以可能會出現最近的數據沒有被保存在快照中的狀況。

AOF是一個不一樣的持久化模型。它是由一個只能追加的文件組成,只在其中添加全部數據。它更持久,由於fsync策略一般比整個RDB更有計劃性。因爲該文件僅用於追加,所以數據是不可更改的。即便在最後一條數據沒有徹底寫完而出現斷電,也能夠很容易的從新斷電前的構建狀態。

可是它也有缺點。第一個是AOF文件一般比RDB更大。另外,若是fsync策略被調度的太頻繁,舉個例子,在每次寫命令以後,那麼性能會大打折扣。在默認狀況下,fsync每秒運行一次。

你應該使用哪一個?

若是你想要一個相似Postgres提供的安全級別,你將不得不兩種狀況都使用。使用RDB可讓你在重啓後更快的恢復備份;使用AOF能夠避免數據丟失。可是若是你能承受一些數據損失,那能夠只使用RDB。記住,Redis會把它們合併成一個單一的持久化模型。

其餘優點

 將來是屬於字節尋址的

因爲磁盤旋轉在很長一段時間都是持久化單元,因此當前的大多數數據庫仍然在適應磁盤的旋轉方面進行優化。好比數據定位,以減小磁盤旋轉滯後,甚至選擇了專門的格式,將索引放在了盤片的特定部分。可是這些優化對於當前的技術,好比SSD,是沒有意義的。Redis存儲數據是爲字節尋址優化的。將來是屬於字節尋址的,而Redis已經在那裏了。

可伸縮性和高可用性

Redis提供了不一樣的方式來實現伸縮性和高可用性。

你能夠在不一樣的Redis節點上分割數據來實現水平的可擴展性。分片將減輕單個實例的負擔,你將受益於多核和計算能力。可是你應該知道分片的侷限性,由於不能支持多鍵操做和事務。

經過複製得到高可用性。主節點是同步複製的,能夠免受節點故障,數據中心故障和Redis進程故障。若是主節點宕機,副節點將會取而代之。在不一樣的AZ中也有一個副本,這將保護你免受災難時間的影響,好比整個AZ失敗。

若是你打算使用Redis企業集羣,全部的這些對你都是抽象的,你將擁有分片和高可用性,而不須要額外的代碼。你能夠經過編碼鏈接到一個Redis實例。

複雜數據結構

Redis不只能夠處理字符串,還能夠處理不一樣的數據結構,如:二進制安全字符串,列表,集合,排序集合,位圖,超級日誌,流等等。這使得Redis不只是一個鍵值存儲,更是一個完整的數據結構服務器。

不是銀彈

一切聽起來都很是棒,可是做爲一個事實,沒什麼東西是銀彈,Redis也不是。主要的缺點是全部的數據都應該裝進內存中。這使Redis適合那些有足夠內存進行存儲的數據。若是沒有,那就必須將數據拆分。可是你會失去一下保證,如事務,管道,或發佈/訂閱。

結論

在很長一段時間裏,Redis被認爲只是一個緩存。一個很是好的分佈式緩存,但仍然只是一個應用程序和主數據庫之間的緩存。正如你所看到的,Redis不只僅是一個緩存,它試圖擺脫這個誤解。Redis不是一個緩存,它是一個分佈式數據存儲。它能夠以線程安全模式以使人難以置信的速度處理不一樣的數據結構,併爲數據持久性提供了不一樣的機制。

考慮到全部這些,即便Redis被很是成功地用做緩存,它仍是能夠作更多的事情。若是你不須要一些像關係數據和高存儲的SQL屬性,爲何你要在應用程序中建立一個複雜的三層系統?Redis做爲緩存和仍是數據庫?在這些狀況下,你能夠只使用Redis做爲主要的持久層。

歡迎關注個人公衆號,若是你有喜歡的外文技術文章,能夠經過公衆號留言推薦給我。

原文連接:https://dzone.com/articles/redis-is-not-just-a-cache

相關文章
相關標籤/搜索