Redis(Remote Dictionary Server) 是一個使用 C 語言編寫的,開源的(BSD許可)高性能非關(guān)系型(NoSQL)的鍵值對數(shù)據(jù)庫,鍵的類型只能為字符串。
支持五種基本的數(shù)據(jù)類型:字符串(String)、列表(List)、集合(Set)、散列表(Hash)、有序集合(Sort Set)。
其他高級數(shù)據(jù)類型:HyperLogLog,發(fā)布訂閱,事務(wù),腳本,GEO, Stream優(yōu)點
讀寫性能優(yōu)異, Redis能讀的速度是110000次/s,寫的速度是81000次/s。
支持數(shù)據(jù)持久化,支持AOF和RDB兩種持久化方式。
支持事務(wù),Redis的所有操作都是原子性的,同時Redis還支持對幾個操作合并后的原子性執(zhí)行。
數(shù)據(jù)結(jié)構(gòu)豐富,除了支持string類型的value外還支持hash、set、zset、list等數(shù)據(jù)結(jié)構(gòu)。
支持主從復(fù)制,主機會自動將數(shù)據(jù)同步到從機,可以進行讀寫分離。
- Redis應(yīng)用場景
- 計數(shù)器
可以對 String 進行自增自減運算,從而實現(xiàn)計數(shù)器功能。Redis 這種內(nèi)存型數(shù)據(jù)庫的讀寫性能非常高,很適合存儲頻繁讀寫的計數(shù)量。 - 緩存
緩存一些熱點數(shù)據(jù)等,也可以緩存序列化后的對象數(shù)據(jù) - 回話緩存
- 全頁緩存(?)
- 查找表(?)
- 消息隊列(訂閱/發(fā)布)
- 分布式鎖功能
- 其他
Set 可以實現(xiàn)交集、并集等操作,從而實現(xiàn)共同好友等功能。ZSet 可以實現(xiàn)有序性操作,從而實現(xiàn)排行榜等功能。
- 持久化
- RDB(默認:如果開啟了持久化,且沒有配置策略)
按照一定的時間將內(nèi)存的數(shù)據(jù)以快照的形式保存到硬盤中,對應(yīng)產(chǎn)生的數(shù)據(jù)文件為dump.rdb。通過配置文件中的save參數(shù)來定義快照的周期。
優(yōu)點:
1. 只有一個文件 dump.rdb,方便持久化。
2. 容災(zāi)性好,一個文件可以保存到安全的磁盤。
3. 性能最大化,fork 子進程來完成寫操作,讓主進程繼續(xù)處理命令,所以是 IO 最大化。使用單獨子進程來進行持久化,主進程不會進行任何 IO 操作,保證了 redis 的高性能。
4. 相對于數(shù)據(jù)集大時,啟動恢復(fù)數(shù)據(jù)時比 AOF 的效率更高。
缺點:
1、數(shù)據(jù)安全性低。RDB 是間隔一段時間進行持久化,如果持久化之間 redis 發(fā)生故障,會發(fā)生數(shù)據(jù)丟失。所以這種方式更適合數(shù)據(jù)要求不嚴謹?shù)臅r候)
2、AOF(Append-only file)持久化方式:是指所有的命令行記錄以 redis 命令請 求協(xié)議的格式完全持久化存儲)保存為 aof 文件。
- AOF
AOF持久化(即Append Only File持久化),則是將Redis執(zhí)行的每次寫命令記錄到單獨的日志文件中,當重啟Redis會重新將持久化的日志中文件恢復(fù)數(shù)據(jù)。
當兩種方式同時開啟時,數(shù)據(jù)恢復(fù)Redis會優(yōu)先選擇AOF恢復(fù)。
優(yōu)點:
1、數(shù)據(jù)安全,aof 持久化可以配置 appendfsync 屬性,有 always,每進行一次 命令操作就記錄到 aof 文件中一次。
2、通過 append 模式寫文件,即使中途服務(wù)器宕機,可以通過 redis-check-aof 工具解決數(shù)據(jù)一致性問題。
3、AOF 機制的 rewrite 模式。AOF 文件沒被 rewrite 之前(文件過大時會對命令 進行合并重寫),可以刪除其中的某些命令(比如誤操作的 flushall))
缺點:
1、AOF 文件比 RDB 文件大,且恢復(fù)速度慢。
2、數(shù)據(jù)集大的時候,比 rdb 啟動效率低。
優(yōu)缺點是什么?
AOF文件比RDB更新頻率高,優(yōu)先使用AOF還原數(shù)據(jù)。
AOF比RDB更安全也更大
RDB性能比AOF好
如果兩個都配了優(yōu)先加載AOF
-
Redis的過期鍵的刪除策略
Redis的過期策略就是指當Redis中緩存的key過期了,Redis如何處理。
過期策略通常有以下三種:- 定時過期:每個設(shè)置過期時間的key都需要創(chuàng)建一個定時器,到過期時間就會立即清除。該策略可以立即清除過期的數(shù)據(jù),對內(nèi)存很友好;但是會占用大量的CPU資源去處理過期的數(shù)據(jù),從而影響緩存的響應(yīng)時間和吞吐量
- 惰性過期:只有當訪問一個key時,才會判斷該key是否已過期,過期則清除。該策略可以最大化地節(jié)省CPU資源,卻對內(nèi)存非常不友好。極端情況可能出現(xiàn)大量的過期key沒有再次被訪問,從而不會被清除,占用大量內(nèi)存。
- 定期過期:每隔一定的時間,會掃描一定數(shù)量的數(shù)據(jù)庫的expires字典中一定數(shù)量的key,并清除其中已過期的key。該策略是前兩者的一個折中方案。通過調(diào)整定時掃描的時間間隔和每次掃描的限定耗時,可以在不同情況下使得CPU和內(nèi)存資源達到最優(yōu)的平衡效果。
(expires字典會保存所有設(shè)置了過期時間的key的過期時間數(shù)據(jù),其中,key是指向鍵空間中的某個鍵的指針,value是該鍵的毫秒精度的UNIX時間戳表示的過期時間。鍵空間是指該Redis集群中保存的所有鍵。)
Redis中同時使用了惰性過期和定期過期兩種過期策略。
Redis key的過期時間和永久有效分別怎么設(shè)置?
EXPIRE和PERSIST命令
- 緩存異常
- 緩存雪崩
緩存雪崩是指緩存同一時間大面積的失效,所以,后面的請求都會落到數(shù)據(jù)庫上,造成數(shù)據(jù)庫短時間內(nèi)承受大量請求而崩掉。
解決方案
- 緩存數(shù)據(jù)的過期時間設(shè)置隨機,防止同一時間大量數(shù)據(jù)過期現(xiàn)象發(fā)生。
- 一般并發(fā)量不是特別多的時候,使用最多的解決方案是加鎖排隊。
- 給每一個緩存數(shù)據(jù)增加相應(yīng)的緩存標記,記錄緩存的是否失效,如果緩存標記失效,則更新數(shù)據(jù)緩存。
- 緩存穿透
緩存穿透是指緩存和數(shù)據(jù)庫中都沒有的數(shù)據(jù),導(dǎo)致所有的請求都落到數(shù)據(jù)庫上,造成數(shù)據(jù)庫短時間內(nèi)承受大量請求而崩掉。
解決方案
- 接口層增加校驗,如用戶鑒權(quán)校驗,id做基礎(chǔ)校驗,id<=0的直接攔截;
- 從緩存取不到的數(shù)據(jù),在數(shù)據(jù)庫中也沒有取到,這時也可以將key-value對寫為key-null,緩存有效時間可以設(shè)置短點,如30秒(設(shè)置太長會導(dǎo)致正常情況也沒法使用)。這樣可以防止攻擊用戶反復(fù)用同一個id暴力攻擊
- 采用布隆過濾器,將所有可能存在的數(shù)據(jù)哈希到一個足夠大的 bitmap 中,一個一定不存在的數(shù)據(jù)會被這個 bitmap 攔截掉,從而避免了對底層存儲系統(tǒng)的查詢壓力