Redis
Redis是一個key-value存儲系統(tǒng)。
Redis支持五種數(shù)據(jù)類型:
string(字符串)
list(列表)
hash(hash表)
set(集合)
zset(有序集合)
和memcached類似,redis支持的數(shù)據(jù)類型更豐富、數(shù)據(jù)能持久化。
memcached把數(shù)據(jù)全部存儲在內(nèi)存中,斷電后會掛掉,數(shù)據(jù)不能超過內(nèi)存大小。
而redis`數(shù)據(jù)會定期備份到硬盤上。
落地策略
RDB持久化(snapshotting):快照,整體備份。在指定的時間間隔內(nèi)將內(nèi)存中的數(shù)據(jù)集快照寫入磁盤,實(shí)際上是fork一個子線程,先將數(shù)據(jù)集寫入臨時文件,寫入成功后,再替換之前的文件,用二進(jìn)制壓縮存儲。
AOF持久化(append-only-file):以日志的形式記錄服務(wù)器所處理的每一個寫、刪除操作,查詢操作不會記錄,以文本的方式記錄,可以打開文件看到詳細(xì)的操作記錄。
過期策略
- 定期刪除:
redis會把設(shè)置了過期時間的key放在單獨(dú)的字典中,定時遍歷來刪除到期的key
- 每100ms從過期字典中隨機(jī)挑選20個,把其中過期的
key刪除
- 如果過期的
key占比超過1/4,重復(fù)步驟1
- 惰性刪除
- 過期的
key并不一定會馬上刪除,還會占用著內(nèi)存。當(dāng)你真正查詢這個key時,redis會檢查一下,這個設(shè)置了過期時間的key是否過期了,如果過期了就會刪除,返回空。
- 內(nèi)存淘汰機(jī)制
當(dāng)redis內(nèi)存超出物理內(nèi)存限制時,會和磁盤產(chǎn)生swap,這種情況性能極差,一般是不允許的。
(1)noeviction:拒絕寫操作,讀、刪除可以正常使用。默認(rèn)策略
(2)allkeys-lru:移除最近最少使用的key,最常用的策略
(3)allkeys-random:隨機(jī)刪除某個key
(4)volatile-lru:在設(shè)置了過期時間的key中,移除最近最少使用的key
(5)volatile-random:在設(shè)置了過期時間的key中,隨機(jī)刪除某個key
(6)volatile-ttl:在設(shè)置了過期時間的key中,把最早要過期的key優(yōu)先刪除
Redis緩存和MySQL數(shù)據(jù)一致性方案
在高并發(fā)的業(yè)務(wù)場景下,數(shù)據(jù)庫大多數(shù)情況都是用戶并發(fā)訪問最薄弱的環(huán)節(jié)。所以,就需要使用redis做一個緩沖操作,讓請求先訪問到redis,而不是直接訪問MySQL數(shù)據(jù)庫
請求先訪問redis緩存,如果緩存中有數(shù)據(jù),直接加載數(shù)據(jù),如果緩存中沒有數(shù)據(jù),再訪問數(shù)據(jù)庫,數(shù)據(jù)庫會將數(shù)據(jù)放入redis中,然后加載數(shù)據(jù)。
讀取緩存一般沒有什么問題,但是一旦涉及到數(shù)據(jù)更新:數(shù)據(jù)庫和緩存更新,就容易出現(xiàn)緩存redis和數(shù)據(jù)庫MySQL間的數(shù)據(jù)一致性問題。
- 如果先刪除了緩存
Redis,還沒有來得及寫庫MySQL,另一個線程就來讀取,發(fā)現(xiàn)緩存為空,則去數(shù)據(jù)庫中讀取數(shù)據(jù)寫入緩存,此時緩存中沒臟數(shù)據(jù)。
- 如果先寫了庫,在刪除緩存之前,寫庫的線程宕機(jī)了,沒有刪除掉緩存,則也會出現(xiàn)數(shù)據(jù)不一致情況。
因?yàn)閷懞妥x是并發(fā)的,沒法保證順序,就會出現(xiàn)緩存和數(shù)據(jù)庫的數(shù)據(jù)不一致的問題。
解決方案:異步更新緩存(基于訂閱binlog的同步機(jī)制)
MySQL的binlog增量訂閱消費(fèi)+消息隊(duì)列+增量數(shù)據(jù) 更新到redis。
(1)讀redis:熱數(shù)據(jù)基本都在redis
(2)寫MySQL:增刪改都是操作MySQL
(3)更新redis數(shù)據(jù):MySQL的數(shù)據(jù)操作binlog,來更新到redis
注意:MySQL實(shí)現(xiàn)主從一致性,也是基于訂閱binlog來實(shí)現(xiàn)增量操作。
binlog:是MySQL的二進(jìn)制文件,用于記錄MySQL的數(shù)據(jù)更新(insert、update、delete操作)。
|