Redis基礎(chǔ)與應(yīng)用

Redis基本介紹

Remote Dictionary Server 高性能key-value數(shù)據(jù)庫(kù),支持BSD協(xié)議

官網(wǎng)

Redis基本使用

數(shù)據(jù)類(lèi)型
String

Redis使用SDS(Simple Dynamic String)動(dòng)態(tài)字符串保存痛单,可以根據(jù)不同的字符串長(zhǎng)度使用不同的結(jié)構(gòu)體

使用場(chǎng)景:

  • 保存Session實(shí)現(xiàn)單點(diǎn)登錄
  • 計(jì)數(shù)器,記錄網(wǎng)站的瀏覽量或者點(diǎn)贊數(shù)等信息肝集,然后按照一定的規(guī)則持久化到數(shù)據(jù)庫(kù)中
  • 緩存數(shù)據(jù)导俘,常用的是把緩存對(duì)象轉(zhuǎn)為Json格式的字符串保存,讀取的時(shí)候再反序列化
List 有序列表

Redis底層是使用QuickList保存夭委,相當(dāng)于Java中的LinkedList,每個(gè)節(jié)點(diǎn)都是ZipList的雙向鏈表保存若河,所以從列表的兩端取數(shù)據(jù)效率很高能岩,查詢(xún)數(shù)據(jù)的時(shí)間復(fù)雜度為O(n)

使用場(chǎng)景:

  • 粉絲列表
  • 文章評(píng)論列表等,可以使用lrange命令萧福,進(jìn)行分頁(yè)查詢(xún)拉鹃,提高應(yīng)用分頁(yè)查詢(xún)的速度
  • 消息隊(duì)列,使用LPush和BRPop命令可以實(shí)現(xiàn)簡(jiǎn)單的消息隊(duì)列功能

常用命令

命令 作用
LPUSH 從列表頭部插入一條數(shù)據(jù)
BRPOP 從列表尾部移除一條數(shù)據(jù)鲫忍,如果沒(méi)有數(shù)據(jù)膏燕,則會(huì)一直阻塞等待到超時(shí)或者有元素為止
BRPOPLPUSH 從列表中彈出一個(gè)值,并且將他插入到另外一個(gè)列表的頭部悟民,如果列表中沒(méi)有元素坝辫,則會(huì)一直阻塞等待到超時(shí)或者有元素為止
RPOP 從列表中取出指定下標(biāo)的元素
Set 集合

內(nèi)部使用value為空的Hashtable實(shí)現(xiàn),查詢(xún)的時(shí)間復(fù)雜度為O(1)

使用場(chǎng)景:

  • 去重
SortedSet 有序集合

基于跳躍表實(shí)現(xiàn)射亏,具體查看此文章近忙,他給每一個(gè)元素設(shè)置一個(gè)score分?jǐn)?shù),然后根據(jù)分?jǐn)?shù)進(jìn)行排序智润。

使用場(chǎng)景:

  • 各種排行榜
  • 帶權(quán)重的隊(duì)列及舍,可以讓線(xiàn)程根據(jù)權(quán)重優(yōu)先執(zhí)行某些任務(wù)。
Hash

內(nèi)部使用ziplist或者Hashtable實(shí)現(xiàn)窟绷,相當(dāng)于Java中的HashMap击纬,使用數(shù)據(jù)+鏈表的方式解決Hash沖突的問(wèn)題

使用場(chǎng)景:

  • 一般可以把java對(duì)象緩存到hash里面,然后通過(guò)key-value的方式取值钾麸,但是實(shí)際開(kāi)發(fā)中的對(duì)象一般比較復(fù)雜,嵌套類(lèi)型炕桨,所以使用hash較少
過(guò)期時(shí)間

Expire key secondskey設(shè)置過(guò)期時(shí)間

刪除策略

  • 消極方法
    • 當(dāng)用戶(hù)get獲取值的時(shí)候饭尝,判斷當(dāng)前key是否過(guò)期,如果過(guò)期就刪除献宫,不返回給用戶(hù)
  • 積極方法
    • 周期性的從設(shè)置了過(guò)期時(shí)間的key中隨機(jī)的選擇20個(gè)進(jìn)行檢查
    • 刪除已經(jīng)過(guò)期的鍵
    • 如果有25%的key過(guò)期钥平,則重復(fù)一次該操作
pub/sub

publish channel message 發(fā)布一條消息到channel通道

subscribe channel[channel...] 訂閱一個(gè)或者多個(gè)通道的消息

發(fā)布消息后就刪除了,不能實(shí)現(xiàn)消息的持久化以及重發(fā)等功能,需要專(zhuān)門(mén)的消息隊(duì)列中間件來(lái)實(shí)現(xiàn)(Kafka涉瘾、RocketMQ知态、RabbitMQ

自增

使用incr命令可以進(jìn)行原子遞增

getset

設(shè)置一個(gè)key的value并獲取設(shè)置前的值,

Redis內(nèi)存回收策略

  • noeviction 不淘汰任何鍵值對(duì)立叛,如果進(jìn)行讀操作則正常工作负敏,進(jìn)行寫(xiě)操作返回錯(cuò)誤。Redis默認(rèn)策略
  • allkeys-lru 淘汰最近最少使用的鍵值對(duì)
  • allkeys-random 對(duì)所有的鍵采用隨機(jī)刪除策略
  • volatile-lru 在設(shè)置了過(guò)期時(shí)間的鍵中采用最近最少使用策略刪除鍵
  • volatile-random 在設(shè)置了過(guò)期時(shí)間的鍵中采用隨機(jī)刪除的策略刪除鍵值對(duì)
  • volatile-ttl 在設(shè)置了過(guò)期時(shí)間的鍵中秘蛇,具有更早過(guò)期時(shí)間的key優(yōu)先移除

JoinGroup過(guò)程

RDB方式:當(dāng)一定的條件觸發(fā)后其做,Redis會(huì)fork一個(gè)子進(jìn)程來(lái)進(jìn)行持久化操作,會(huì)把內(nèi)存中的數(shù)據(jù)集以快照形式寫(xiě)入磁盤(pán)赁还,采用二進(jìn)制壓縮存儲(chǔ)妖泄,將所有的數(shù)據(jù)寫(xiě)入到一個(gè)臨時(shí)文件中,等寫(xiě)入完成后會(huì)替換上次持久化的文件艘策。

觸發(fā)條件

  • 用戶(hù)配置(默認(rèn)下面save seconds 操作次數(shù))
    • save 900 1
    • save 300 10
    • save 60 10000
  • bgsave蹈胡、save 調(diào)用save方法或者bgsave方法
  • flushall 清空數(shù)據(jù)
  • replication 主從同步數(shù)據(jù)

AOF: 每隔一秒或者每次更改redis數(shù)據(jù)就將命令追加到AOF文件中

  • 默認(rèn)不開(kāi)啟,使用配置中appendonly yes打開(kāi)AOF
  • AOF文件體積過(guò)大時(shí)朋蔫,會(huì)自動(dòng)的在后臺(tái)對(duì)AOF進(jìn)行重寫(xiě)罚渐,重寫(xiě)后新的AOF文件包含了恢復(fù)當(dāng)前數(shù)據(jù)集所需要的最小命令集;主進(jìn)程會(huì)fork一個(gè)子進(jìn)程進(jìn)行重寫(xiě)斑举,類(lèi)似于RDB快照的方式搅轿。
  • auto-aof-rewrite-percentage 表示表示當(dāng)前的AOF文件大小 超過(guò)上一次重寫(xiě)時(shí)的AOF文件大小的百分之多少時(shí)會(huì)再次進(jìn)行重寫(xiě),如果之前沒(méi)有重寫(xiě)過(guò)富玷,則以啟動(dòng)時(shí)AOF文件大小為依據(jù)璧坟。
  • Auto-aof-rewrite-min-size 表示限制了允許重寫(xiě)的最小AOF文件大小

RDB和AOF的優(yōu)缺點(diǎn):

  • 當(dāng)服務(wù)發(fā)生故障,RDB方式會(huì)丟失上次備份之后的所有數(shù)據(jù)赎懦,AOF最多丟失1秒內(nèi)的數(shù)據(jù)
  • Redis重啟時(shí)雀鹃,首先通過(guò)RDB加載數(shù)據(jù)到內(nèi)存中,速度比較快励两,然后通過(guò)AOF文件中的近期操作指令黎茎,將數(shù)據(jù)恢復(fù)到重啟之前的狀態(tài)
  • AOF文件可讀性比較好,但是相同內(nèi)容的數(shù)據(jù)当悔,會(huì)比RDB大很多

Redis 單線(xiàn)程

Redis為什么這么塊
  • Redis是在內(nèi)存中操作數(shù)據(jù)傅瞻,而且存儲(chǔ)的數(shù)據(jù)結(jié)構(gòu)類(lèi)似于Java中的HashMap,查詢(xún)的時(shí)間復(fù)雜度為O(1)盲憎;
  • 單線(xiàn)程嗅骄,不需要在線(xiàn)程間切換,減少了上下文切換的資源消耗饼疙,單線(xiàn)程也不需要考慮鎖的使用溺森,減少了獲取鎖和釋放鎖的資源消耗
  • 使用I/O多路復(fù)用,同步非阻塞IO

Lua腳本

Redis是單線(xiàn)程的,在內(nèi)部不會(huì)存在線(xiàn)程安全的問(wèn)題屏积,但是如果有多個(gè)客戶(hù)端同時(shí)訪(fǎng)問(wèn)医窿,就相當(dāng)于多線(xiàn)程,多個(gè)客戶(hù)端之間沒(méi)有請(qǐng)求的同步炊林,實(shí)際順序不一樣就可能產(chǎn)生線(xiàn)程安全問(wèn)題姥卢。使用Lua腳本可以滿(mǎn)足原子性

基本使用

eval "redis.call(’set’,’hello’,’world')" 0不帶參數(shù)

eval “redis.call(’set’,KEYS[1],ARGV[1])” 1 hello world 帶參數(shù)

Lua腳本的好處
  • 減少網(wǎng)絡(luò)開(kāi)銷(xiāo)铛铁,在Lua腳本中可以把多個(gè)命令放在同一個(gè)腳本中運(yùn)行
  • 原子操作隔显,Redis會(huì)將整個(gè)腳本作為一個(gè)整體執(zhí)行,中間不會(huì)被其他命令插入
  • 復(fù)用性饵逐,客戶(hù)端發(fā)送的腳本會(huì)存儲(chǔ)在Redis中括眠,其他客戶(hù)端可以復(fù)用這一腳本完成同樣的邏輯。

Pinelining 管道

Redis是一種基于客戶(hù)端-服務(wù)端模型以及請(qǐng)求/響應(yīng)協(xié)議的TCP服務(wù)倍权,通常會(huì)遵循以下步驟

  • 客戶(hù)端發(fā)送一個(gè)查詢(xún)請(qǐng)求掷豺,并監(jiān)聽(tīng)socket返回,通常是阻塞模式薄声,等待服務(wù)端響應(yīng)
  • 服務(wù)端處理命令当船,然后將結(jié)果返回給客戶(hù)端

如果客戶(hù)端需要發(fā)送批量的命令的時(shí)候,往返時(shí)間就會(huì)變的很長(zhǎng)(RTT Round Trip Time)默辨,使用pipeline可以減少RTT的時(shí)間德频,服務(wù)端也可以見(jiàn)減少I(mǎi)/O的調(diào)用次數(shù)(用戶(hù)態(tài)->內(nèi)核態(tài))

分布式鎖的實(shí)現(xiàn)

setnx命令可以設(shè)置一個(gè)key-value鍵值對(duì),如果當(dāng)前Redis中已經(jīng)有該key缩幸,會(huì)返回失敗壹置。多個(gè)進(jìn)程同時(shí)進(jìn)行setnx操作的時(shí)候,只會(huì)有一個(gè)可以設(shè)置成功表谊。

  • setnx 需要設(shè)置一個(gè)超時(shí)時(shí)間钞护,防止獲取鎖的進(jìn)程掛掉后導(dǎo)致死鎖
  • 存在一種情況,當(dāng)一個(gè)客戶(hù)端A獲取鎖成功后爆办,由于某種原因阻塞了难咕,然后超時(shí)時(shí)間到了,自動(dòng)釋放鎖了距辆,然后另一個(gè)客戶(hù)端B獲取了鎖余佃,此時(shí)客戶(hù)端A阻塞結(jié)束并且運(yùn)行結(jié)束后,會(huì)嘗試釋放鎖跨算,這時(shí)候可能會(huì)把客戶(hù)端A的鎖釋放了咙冗。解決辦法:setnx key randomValue設(shè)置一個(gè)隨機(jī)值,每個(gè)客戶(hù)端不同漂彤,釋放鎖的時(shí)候,首先判斷一下當(dāng)前value是否與自己客戶(hù)端相同,如果相同才能釋放鎖挫望。

Redis集群

1.如何配置

master節(jié)點(diǎn)不用做任何修改立润,只需要在slave節(jié)點(diǎn)中,修改redis.conf文件中添加slaveof master-ip master-port

2.數(shù)據(jù)如何同步
  • slave初始化階段媳板,Redis會(huì)觸發(fā)全量復(fù)制桑腮,slave需要將master節(jié)點(diǎn)上的所有數(shù)據(jù)
  • Master服務(wù)器執(zhí)行bgsave命令(子線(xiàn)程),生成快照蛉幸,同時(shí)記錄在此期間的寫(xiě)命令破讨,快照發(fā)送到Slave節(jié)點(diǎn)并載入后,再把緩存的寫(xiě)命令發(fā)送過(guò)來(lái)執(zhí)行命令
  • min-slaves-to-write 3 表示只有當(dāng)3個(gè)slave同步完成奕纫,master才是可寫(xiě)的
  • min-slaves-max-lag 10 表示允許slave最長(zhǎng)失去連接的時(shí)間是10秒提陶,10秒還沒(méi)收到slave響應(yīng),master就認(rèn)為slave已經(jīng)斷開(kāi)
  • master node 會(huì)在內(nèi)存中創(chuàng)建一個(gè)backlog匹层,masterslave都會(huì)保存要給replica offset還有一個(gè)master id隙笆,如果slave斷開(kāi)連接,重連后slave會(huì)讓master從上次的replica offset開(kāi)始繼續(xù)復(fù)制數(shù)據(jù)升筏,如果沒(méi)有對(duì)應(yīng)的offset撑柔,則會(huì)進(jìn)行一次全量同步
image-20200408133241856.png

Redis哨兵(Sentinel)

Redis集群之后,如果master節(jié)點(diǎn)掛了您访,需要從slave節(jié)點(diǎn)中選舉master铅忿,Redis沒(méi)有提供相關(guān)的功能,需要哨兵來(lái)進(jìn)行監(jiān)控灵汪。

哨兵是一個(gè)單獨(dú)的進(jìn)程檀训,一般使用三個(gè)哨兵集群,保證哨兵的高可用识虚。此時(shí)哨兵不僅會(huì)監(jiān)控masterslave肢扯,還會(huì)互相監(jiān)控。

配置:在redis-sentinel.conf文件中配置 sentinel monitor name ip port quorum担锤,只需要配置master節(jié)點(diǎn)即可

哨兵之間相互感知
  • 所有的sentinel向他們的監(jiān)視的master節(jié)點(diǎn)訂閱channel sentinel
  • 新加入的sentinel節(jié)點(diǎn)向master的這個(gè)節(jié)點(diǎn)發(fā)布一條消息蔚晨,其他訂閱了這個(gè)channelsentinel會(huì)發(fā)現(xiàn)這個(gè)新的sentinel
  • 新加入的sentinel和其他sentinel節(jié)點(diǎn)建立長(zhǎng)連接
故障發(fā)現(xiàn)

sentinel節(jié)點(diǎn)定期向master節(jié)點(diǎn)發(fā)送心跳包判斷是否存活,一旦發(fā)現(xiàn)master沒(méi)有正確響應(yīng)肛循,sentinel就會(huì)把master設(shè)為主觀(guān)不可用狀態(tài)铭腕,然后把狀態(tài)發(fā)送給其他sentinel確認(rèn),當(dāng)確認(rèn)的sentinel超過(guò)quorum時(shí)多糠,就認(rèn)為master節(jié)點(diǎn)客觀(guān)不可用累舷,接著就進(jìn)入選舉新的master的流程,這里使用到了Raft算法夹孔,基于投票的算法被盈,只要保證過(guò)半數(shù)節(jié)點(diǎn)通過(guò)提議即可析孽。

哨兵的主要功能
  • 集群監(jiān)控 哨兵可以監(jiān)控master節(jié)點(diǎn)和slave節(jié)點(diǎn)的運(yùn)行情況
  • 消息通知 當(dāng)集群中有某一個(gè)節(jié)點(diǎn)掛了之后,可以通知管理員
  • 故障轉(zhuǎn)移 當(dāng)master節(jié)點(diǎn)掛了之后只怎,哨兵會(huì)從slave節(jié)點(diǎn)中重新選舉一個(gè)做為master節(jié)點(diǎn)
  • 配置中心 如果發(fā)生故障轉(zhuǎn)移袜瞬,通知客戶(hù)端新的master節(jié)點(diǎn)地址

Redis分片(Cluster)

image-20200402164755059.png

主從同步的集群中,每個(gè)節(jié)點(diǎn)都存有集群中的所有數(shù)據(jù)身堡,存在著單機(jī)存儲(chǔ)量的瓶頸問(wèn)題邓尤,形成了木桶效應(yīng)。對(duì)Redis進(jìn)行分片集群贴谎,可以提高Redis的性能和存儲(chǔ)能力汞扎。

集群結(jié)構(gòu)如上圖,一個(gè)Redis Cluster由多個(gè)Redis節(jié)點(diǎn)構(gòu)成擅这,不同節(jié)點(diǎn)組服務(wù)沒(méi)有交集澈魄,也就是每一個(gè)節(jié)點(diǎn)組對(duì)應(yīng)數(shù)據(jù)sharding的一個(gè)分片。節(jié)點(diǎn)組內(nèi)部分為主備兩類(lèi)節(jié)點(diǎn)蕾哟,對(duì)應(yīng)master和slave節(jié)點(diǎn)一忱。兩者數(shù)據(jù)準(zhǔn)實(shí)時(shí)一直,通過(guò)異步化的主備復(fù)制機(jī)制來(lái)保證谭确。一個(gè)節(jié)點(diǎn)組有且只有一個(gè)master節(jié)點(diǎn)帘营,同時(shí)可以有0到n個(gè)slave節(jié)點(diǎn),在這個(gè)節(jié)點(diǎn)組中逐哈,只有master節(jié)點(diǎn)可以提供讀寫(xiě)服務(wù)芬迄,slave只能提供讀服務(wù)。

集群的數(shù)據(jù)分片

Redis 集群沒(méi)有使用一致性hash, 而是引入了 哈希槽的概念.

Redis 集群有16384個(gè)哈希槽,每個(gè)key通過(guò)CRC16校驗(yàn)后對(duì)16384取模來(lái)決定放置哪個(gè)槽.集群的每個(gè)節(jié)點(diǎn)負(fù)責(zé)一部分hash槽,舉個(gè)例子,比如當(dāng)前集群有3個(gè)節(jié)點(diǎn),那么:

  • 節(jié)點(diǎn) A 包含 0 到 5500號(hào)哈希槽.
  • 節(jié)點(diǎn) B 包含5501 到 11000 號(hào)哈希槽.
  • 節(jié)點(diǎn) C 包含11001 到 16384號(hào)哈希槽.

這種結(jié)構(gòu)很容易添加或者刪除節(jié)點(diǎn). 比如如果我想新添加個(gè)節(jié)點(diǎn)D, 我需要從節(jié)點(diǎn) A, B, C中得部分槽到D上. 如果我想移除節(jié)點(diǎn)A,需要將A中的槽移到B和C節(jié)點(diǎn)上,然后將沒(méi)有任何槽的A節(jié)點(diǎn)從集群中移除即可. 由于從一個(gè)節(jié)點(diǎn)將哈希槽移動(dòng)到另一個(gè)節(jié)點(diǎn)并不會(huì)停止服務(wù),所以無(wú)論添加刪除或者改變某個(gè)節(jié)點(diǎn)的哈希槽的數(shù)量都不會(huì)造成集群不可用的狀態(tài).

如何把一次操作的所有值保存到一個(gè)節(jié)點(diǎn)中

Redis中引入了HashTag的概念昂秃,可以是得數(shù)據(jù)分布算法可以根據(jù)key的某一個(gè)部分進(jìn)行計(jì)算禀梳,

舉個(gè)簡(jiǎn)單的例子,加入對(duì)于用戶(hù)的信息進(jìn)行存儲(chǔ)肠骆, user:user1:id算途、user:user1:name/ 那么通過(guò)hashtag的方式, user:{user1}:id蚀腿、user:{user1}.name; 表示

當(dāng)一個(gè)key包含 {} 的時(shí)候嘴瓤,就不對(duì)整個(gè)key做hash,而僅對(duì) {} 包括的字符串做hash莉钙。

擴(kuò)容

  • 槽位遷移
  • 數(shù)據(jù)遷移

Redis緩存問(wèn)題(緩存擊穿廓脆、緩存穿透、緩存雪崩磁玉、緩存不一致)

緩存擊穿

當(dāng)Redis緩存中的某個(gè)熱點(diǎn)key失效停忿,導(dǎo)致大量的請(qǐng)求穿過(guò)緩存,到達(dá)DB

緩存穿透

大量的無(wú)效請(qǐng)求到達(dá)數(shù)據(jù)庫(kù)蚊伞,比如請(qǐng)求參數(shù)id = -1席赂,redis和數(shù)據(jù)庫(kù)中都沒(méi)有數(shù)據(jù)吮铭,但是會(huì)一直查詢(xún)數(shù)據(jù)庫(kù)。

解決辦法
  • 熱點(diǎn)數(shù)據(jù)設(shè)置永不失效
  • 多級(jí)緩存
  • 熔斷降級(jí)
  • nginx拉黑多次請(qǐng)求的同一ip
  • 參數(shù)校驗(yàn)氧枣,永遠(yuǎn)不要相信用戶(hù)
  • 當(dāng)查詢(xún)到數(shù)據(jù)庫(kù)中沒(méi)有的值沐兵,可以設(shè)置一個(gè)為null或其他提示的數(shù)據(jù)到緩存中,下次請(qǐng)求就不會(huì)到數(shù)據(jù)庫(kù)中了便监,緩存的失效時(shí)間設(shè)置短一點(diǎn)如30秒
  • 使用互斥鎖
  • 布隆過(guò)濾器
緩存雪崩

同一時(shí)間Redis緩存的key大面積失效,導(dǎo)致所有的請(qǐng)求都到達(dá)了數(shù)據(jù)庫(kù)

  • 一般這種情況是redis的過(guò)期時(shí)間到了碳想,可以設(shè)置一個(gè)隨機(jī)值烧董,讓key在一定范圍內(nèi)失效
  • Redis分片,將key保存到不同的節(jié)點(diǎn)上胧奔,防止出現(xiàn)大面積失效的情況
緩存更新方式

這是決定在使用緩存時(shí)就該考慮的問(wèn)題逊移。

緩存的數(shù)據(jù)在數(shù)據(jù)源發(fā)生變更時(shí)需要對(duì)緩存進(jìn)行更新,數(shù)據(jù)源可能是 DB龙填,也可能是遠(yuǎn)程服務(wù)胳泉。更新的方式可以是主動(dòng)更新。數(shù)據(jù)源是 DB 時(shí)岩遗,可以在更新完 DB 后就直接更新緩存扇商。

當(dāng)數(shù)據(jù)源不是 DB 而是其他遠(yuǎn)程服務(wù),可能無(wú)法及時(shí)主動(dòng)感知數(shù)據(jù)變更宿礁,這種情況下一般會(huì)選擇對(duì)緩存數(shù)據(jù)設(shè)置失效期案铺,也就是數(shù)據(jù)不一致的最大容忍時(shí)間。

這種場(chǎng)景下梆靖,可以選擇失效更新控汉,key 不存在或失效時(shí)先請(qǐng)求數(shù)據(jù)源獲取最新數(shù)據(jù),然后再次緩存返吻,并更新失效期姑子。

但這樣做有個(gè)問(wèn)題,如果依賴(lài)的遠(yuǎn)程服務(wù)在更新時(shí)出現(xiàn)異常测僵,則會(huì)導(dǎo)致數(shù)據(jù)不可用街佑。改進(jìn)的辦法是異步更新,就是當(dāng)失效時(shí)先不清除數(shù)據(jù)恨课,繼續(xù)使用舊的數(shù)據(jù)舆乔,然后由異步線(xiàn)程去執(zhí)行更新任務(wù)。這樣就避免了失效瞬間的空窗期剂公。另外還有一種純異步更新方式希俩,定時(shí)對(duì)數(shù)據(jù)進(jìn)行分批更新。實(shí)際使用時(shí)可以根據(jù)業(yè)務(wù)場(chǎng)景選擇更新方式纲辽。

數(shù)據(jù)不一致

第二個(gè)問(wèn)題是數(shù)據(jù)不一致的問(wèn)題颜武,可以說(shuō)只要使用緩存璃搜,就要考慮如何面對(duì)這個(gè)問(wèn)題。緩存不一致產(chǎn)生的原因一般是主動(dòng)更新失敗鳞上,例如更新 DB 后这吻,更新 Redis 因?yàn)榫W(wǎng)絡(luò)原因請(qǐng)求超時(shí);或者是異步更新失敗導(dǎo)致篙议。

解決的辦法是唾糯,如果服務(wù)對(duì)耗時(shí)不是特別敏感可以增加重試;如果服務(wù)對(duì)耗時(shí)敏感可以通過(guò)異步補(bǔ)償任務(wù)來(lái)處理失敗的更新鬼贱,或者短期的數(shù)據(jù)不一致不會(huì)影響業(yè)務(wù)移怯,那么只要下次更新時(shí)可以成功,能保證最終一致性就可以这难。

布隆過(guò)濾器

Redis使用中有哪些坑舟误??姻乓?

不能保證原子性
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末嵌溢,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子蹋岩,更是在濱河造成了極大的恐慌赖草,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,496評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件星澳,死亡現(xiàn)場(chǎng)離奇詭異疚顷,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)禁偎,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,187評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)腿堤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人如暖,你說(shuō)我怎么就攤上這事笆檀。” “怎么了盒至?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,091評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵酗洒,是天一觀(guān)的道長(zhǎng)。 經(jīng)常有香客問(wèn)我枷遂,道長(zhǎng)樱衷,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,458評(píng)論 1 283
  • 正文 為了忘掉前任酒唉,我火速辦了婚禮矩桂,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘痪伦。我一直安慰自己侄榴,他們只是感情好雹锣,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,542評(píng)論 6 385
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著癞蚕,像睡著了一般蕊爵。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上桦山,一...
    開(kāi)封第一講書(shū)人閱讀 49,802評(píng)論 1 290
  • 那天攒射,我揣著相機(jī)與錄音,去河邊找鬼恒水。 笑死匆篓,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的寇窑。 我是一名探鬼主播,決...
    沈念sama閱讀 38,945評(píng)論 3 407
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼箩张,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼甩骏!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起先慷,我...
    開(kāi)封第一講書(shū)人閱讀 37,709評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤饮笛,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后论熙,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體福青,經(jīng)...
    沈念sama閱讀 44,158評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,502評(píng)論 2 327
  • 正文 我和宋清朗相戀三年脓诡,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了无午。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,637評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡祝谚,死狀恐怖宪迟,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情交惯,我是刑警寧澤次泽,帶...
    沈念sama閱讀 34,300評(píng)論 4 329
  • 正文 年R本政府宣布,位于F島的核電站席爽,受9級(jí)特大地震影響意荤,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜只锻,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,911評(píng)論 3 313
  • 文/蒙蒙 一玖像、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧炬藤,春花似錦御铃、人聲如沸碴里。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,744評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)咬腋。三九已至,卻和暖如春睡互,著一層夾襖步出監(jiān)牢的瞬間根竿,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,982評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工就珠, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留寇壳,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,344評(píng)論 2 360
  • 正文 我出身青樓妻怎,卻偏偏與公主長(zhǎng)得像壳炎,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子逼侦,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,500評(píng)論 2 348