redis系列文章目錄
Redis學習筆記(九)redis實現時時直播列表緩存,支持分頁[熱點數據存儲]
Redis學習筆記(五)jedis(JedisCluster)操作Redis集群 redis-cluster
redis學習筆記(二)JedisCluster + redis 3.2.5集群
redis與數據庫數據一致性問題是個老生常談的問題了,這里也沒啥新鮮玩意,就是總結一下
我們在使用redis過程中,或者網上一些資料,通常會這樣做:先讀取緩存,如果緩存不存在,則讀取數據庫。偽代碼如下:
Object stuObj =newObject();publicStugetStuFromCache(String key){? ? ? ? Stu stu = (Stu) redis.get(key);if(stu ==null){synchronized(stuObj) {? ? ? ? ? ? ? ? stu = (Stu) redis.get(key);if(stu ==null){? ? ? ? ? ? ? ? ? ? Stu stuDb = db.query();? ? ? ? ? ? ? ? ? ? redis.set(key, stuDb);? ? ? ? ? ? ? ? }? ? ? ? ? ? }? ? ? ? }returnstu;? ? }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
上面加鎖是為了防止過多的查詢走到數據庫層
寫數據庫偽代碼:
publicvoidsetStu(){? ? redis.del(key);? ? db.write(obj);}
1
2
3
4
不管是先寫庫,再刪除緩存;還是先刪緩存,再寫庫,都有可能出現數據不一致的情況?
因為寫和讀是并發的,沒法保證順序,如果刪了緩存,還沒有來得及寫庫,另一個線程就來讀取,發現緩存為空,則去數據庫中讀取數據寫入緩存,此時緩存中為臟數據。如果先寫了庫,再刪除緩存前,寫庫的線程宕機了,沒有刪除掉緩存,則也會出現數據不一致情況。?
如果是redis集群,或者主從模式,寫主讀從,由于redis復制存在一定的時間延遲,也有可能導致數據不一致。
在寫庫前后都進行redis.del(key)操作,并且設定合理的超時時間。這樣最差的情況是在超時時間內存在不一致,當然這種情況極其少見,可能的原因就是服務宕機。此種情況可以滿足絕大多數需求。?
當然這種策略要考慮redis和數據庫主從同步的耗時,所以在第二次刪除前最好休眠一定時間,比如500毫秒,這樣毫無疑問又增加了寫請求的耗時
通過讀取binlog的方式,異步淘汰緩存。?
好處:業務代碼侵入性低,將緩存與數據庫不一致的時間盡可能縮小。
版權聲明:本文為博主原創文章,未經博主允許不得轉載,轉載請注明出處. 博主博客地址是 http://blog.csdn.net/liubenlong007
本文已收錄于以下專欄: