NoSQL數據庫回顧:服務於特定背景的專用數據庫,向外提供特定的API,而不是提供通用的SQL接口,因此效率更加高效。html
Redis適用於數據全In memory的場景,支持schema free,auto sharing機制,重要的是其提供了一種disk-backed功能,更像一個增強版的memcached。mysql
Redis最爲經常使用的數據類型主要有如下五種:sql
String數據庫
Hash數據結構
List運維
Setmemcached
Redis因爲支持很是豐富的內存數據結構類型,如何把這些複雜的內存組織方式持久化到磁盤上是一個難題,因此Redis的持久化方式與傳統數據庫的方式有比較多的差異,Redis一共支持四種持久化方式,分別是:大數據
在設計思路上,前兩種是基於所有數據都在內存中,即小數據量下提供磁盤落地功能,然後兩種方式則是做者在嘗試存儲數據超過物理內存時,即大數據量的數據存 儲,截止到本文,後兩種持久化方式仍然是在實驗階段,而且vm方式基本已經被做者放棄,因此實際能在生產環境用的只有前兩種,換句話說Redis目前還只 能做爲小數據量存儲(所有數據可以加載在內存中),海量數據存儲方面並非Redis所擅長的領域。下面分別介紹下這幾種持久化方式:url
定時快照方式(snapshot):
該持久化方式實際是在Redis內部一個定時器事件,每隔固定時間去檢查當前數據發生的改變次數與時間是否知足配置的持久化觸發的條件,若是知足則經過操 做系統fork調用來建立出一個子進程,這個子進程默認會與父進程共享相同的地址空間,這時就能夠經過子進程來遍歷整個內存來進行存儲操做,而主進程則仍 然能夠提供服務,當有寫入時由操做系統按照內存頁(page)爲單位來進行copy-on-write保證父子進程之間不會互相影響。
該持久化的主要缺點是定時快照只是表明一段時間內的內存映像,因此係統重啓會丟失上次快照與重啓之間全部的數據。
基於語句追加方式(aof):
aof方式實際相似mysql的基於語句的binlog方式,即每條會使Redis內存數據發生改變的命令都會追加到一個log文件中,也就是說這個log文件就是Redis的持久化數據。
aof的方式的主要缺點是追加log文件可能致使體積過大,當系統重啓恢復數據時若是是aof的方式則加載數據會很是慢,幾十G的數據可能須要幾小時才能 加載完,固然這個耗時並非由於磁盤文件讀取速度慢,而是因爲讀取的全部命令都要在內存中執行一遍。另外因爲每條命令都要寫log,因此使用aof的方 式,Redis的讀寫性能也會有所降低。
虛擬內存方式:
虛擬內存方式是Redis來進行用戶空間的數據換入換出的一個策略,此種方式在實現的效果上比較差,主要問題是代碼複雜,重啓慢,複製慢等等,目前已經被做者放棄。
diskstore方式:
diskstore方式是做者放棄了虛擬內存方式後選擇的一種新的實現方式,也就是傳統的B-tree的方式,目前仍在實驗階段,後續是否可用咱們能夠拭目以待。
有Redis線上運維經驗的人會發現Redis在物理內存使用比較多,但尚未超過實際物理內存總容量時就會發生不穩定甚至崩潰的問題,有人認爲是基於快 照方式持久化的fork系統調用形成內存佔用加倍而致使的,這種觀點是不許確的,由於fork 調用的copy-on-write機制是基於操做系統頁這個單位的,也就是隻有有寫入的髒頁會被複制,可是通常你的系統不會在短期內全部的頁都發生了寫 入而致使複製,那麼是什麼緣由致使Redis崩潰的呢?
答案是Redis的持久化使用了Buffer IO形成的,所謂Buffer IO是指Redis對持久化文件的寫入和讀取操做都會使用物理內存的Page Cache,而大多數數據庫系統會使用Direct IO來繞過這層Page Cache並自行維護一個數據的Cache,而當Redis的持久化文件過大(尤爲是快照文件),並對其進行讀寫時,磁盤文件中的數據都會被加載到物理內 存中做爲操做系統對該文件的一層Cache,而這層Cache的數據與Redis內存中管理的數據實際是重複存儲的,雖然內核在物理內存緊張時會作 Page Cache的剔除工做,但內核極可能認爲某塊Page Cache更重要,而讓你的進程開始Swap ,這時你的系統就會開始出現不穩定或者崩潰了。咱們的經驗是當你的Redis物理內存使用超過內存總容量的3/5時就會開始比較危險了
定時快照方式(snapshot)
基於語句追加文件的方式(aof)
虛擬內存(vm)
Diskstore方式