你所不知道的Redis背后的故事

redis 簡(jiǎn)介

簡(jiǎn)單來(lái)說(shuō) redis 就是一個(gè)數(shù)據(jù)庫(kù)雇庙,不過(guò)與傳統(tǒng)數(shù)據(jù)庫(kù)不同的是 redis 的數(shù)據(jù)是存在內(nèi)存中的,所以讀寫速度非常快屋谭,因此 redis 被廣泛應(yīng)用于緩存方向辅斟。另外转晰,redis 也經(jīng)常用來(lái)做分布式鎖。redis 提供了多種數(shù)據(jù)類型來(lái)支持不同的業(yè)務(wù)場(chǎng)景。除此之外挽霉,redis 支持事務(wù) 防嗡、持久化、LUA腳本侠坎、LRU驅(qū)動(dòng)事件蚁趁、多種集群方案。

為什么要用 redis/為什么要用緩存

主要從“高性能”和“高并發(fā)”這兩點(diǎn)來(lái)看待這個(gè)問(wèn)題实胸。

高性能:

假如用戶第一次訪問(wèn)數(shù)據(jù)庫(kù)中的某些數(shù)據(jù)他嫡。這個(gè)過(guò)程會(huì)比較慢,因?yàn)槭菑挠脖P上讀取的庐完。將該用戶訪問(wèn)的數(shù)據(jù)存在數(shù)緩存中钢属,這樣下一次再訪問(wèn)這些數(shù)據(jù)的時(shí)候就可以直接從緩存中獲取了。操作緩存就是直接操作內(nèi)存门躯,所以速度相當(dāng)快淆党。如果數(shù)據(jù)庫(kù)中的對(duì)應(yīng)數(shù)據(jù)改變的之后,同步改變緩存中相應(yīng)的數(shù)據(jù)即可讶凉!

image

高并發(fā):

直接操作緩存能夠承受的請(qǐng)求是遠(yuǎn)遠(yuǎn)大于直接訪問(wèn)數(shù)據(jù)庫(kù)的染乌,所以我們可以考慮把數(shù)據(jù)庫(kù)中的部分?jǐn)?shù)據(jù)轉(zhuǎn)移到緩存中去,這樣用戶的一部分請(qǐng)求會(huì)直接到緩存這里而不用經(jīng)過(guò)數(shù)據(jù)庫(kù)懂讯。

image

為什么要用 redis 而不用 map/guava 做緩存?

下面的內(nèi)容來(lái)自 segmentfault 一位網(wǎng)友的提問(wèn)荷憋,地址:https://segmentfault.com/q/1010000009106416

緩存分為本地緩存和分布式緩存。以 Java 為例褐望,使用自帶的 map 或者 guava 實(shí)現(xiàn)的是本地緩存勒庄,最主要的特點(diǎn)是輕量以及快速,生命周期隨著 jvm 的銷毀而結(jié)束瘫里,并且在多實(shí)例的情況下实蔽,每個(gè)實(shí)例都需要各自保存一份緩存,緩存不具有一致性减宣。

使用 redis 或 memcached 之類的稱為分布式緩存盐须,在多實(shí)例的情況下,各實(shí)例共用一份緩存數(shù)據(jù)漆腌,緩存具有一致性贼邓。缺點(diǎn)是需要保持 redis 或 memcached服務(wù)的高可用,整個(gè)程序架構(gòu)上較為復(fù)雜闷尿。

redis 和 memcached 的區(qū)別

對(duì)于 redis 和 memcached 我總結(jié)了下面四點(diǎn)∷芫叮現(xiàn)在公司一般都是用 redis 來(lái)實(shí)現(xiàn)緩存,而且 redis 自身也越來(lái)越強(qiáng)大了填具!

  1. redis支持更豐富的數(shù)據(jù)類型(支持更復(fù)雜的應(yīng)用場(chǎng)景):Redis不僅僅支持簡(jiǎn)單的k/v類型的數(shù)據(jù)统舀,同時(shí)還提供list匆骗,set,zset誉简,hash等數(shù)據(jù)結(jié)構(gòu)的存儲(chǔ)碉就。memcache支持簡(jiǎn)單的數(shù)據(jù)類型,String闷串。
  2. Redis支持?jǐn)?shù)據(jù)的持久化瓮钥,可以將內(nèi)存中的數(shù)據(jù)保持在磁盤中,重啟的時(shí)候可以再次加載進(jìn)行使用,而Memecache把數(shù)據(jù)全部存在內(nèi)存之中烹吵。
  3. 集群模式:memcached沒(méi)有原生的集群模式碉熄,需要依靠客戶端來(lái)實(shí)現(xiàn)往集群中分片寫入數(shù)據(jù);但是 redis 目前是原生支持 cluster 模式的.
  4. Memcached是多線程肋拔,非阻塞IO復(fù)用的網(wǎng)絡(luò)模型锈津;Redis使用單線程的多路 IO 復(fù)用模型。

來(lái)自網(wǎng)絡(luò)上的一張圖凉蜂,這里分享給大家琼梆!

redis 和 memcached 的區(qū)別

redis 常見(jiàn)數(shù)據(jù)結(jié)構(gòu)以及使用場(chǎng)景分析

1.String

常用命令: set,get,decr,incr,mget 等。

String數(shù)據(jù)結(jié)構(gòu)是簡(jiǎn)單的key-value類型跃惫,value其實(shí)不僅可以是String叮叹,也可以是數(shù)字。
常規(guī)key-value緩存應(yīng)用爆存;
常規(guī)計(jì)數(shù):微博數(shù),粉絲數(shù)等蝗砾。

2.Hash

常用命令: hget,hset,hgetall 等先较。

hash 是一個(gè) string 類型的 field 和 value 的映射表,hash 特別適合用于存儲(chǔ)對(duì)象悼粮,后續(xù)操作的時(shí)候闲勺,你可以直接僅僅修改這個(gè)對(duì)象中的某個(gè)字段的值。 比如我們可以 hash 數(shù)據(jù)結(jié)構(gòu)來(lái)存儲(chǔ)用戶信息扣猫,商品信息等等菜循。比如下面我就用 hash 類型存放了我本人的一些信息:

key=JavaUser293847
value={
  “id”: 1,
  “name”: “SnailClimb”,
  “age”: 22,
  “l(fā)ocation”: “Wuhan, Hubei”
}

3.List

常用命令: lpush,rpush,lpop,rpop,lrange等

list 就是鏈表,Redis list 的應(yīng)用場(chǎng)景非常多申尤,也是Redis最重要的數(shù)據(jù)結(jié)構(gòu)之一癌幕,比如微博的關(guān)注列表,粉絲列表昧穿,消息列表等功能都可以用Redis的 list 結(jié)構(gòu)來(lái)實(shí)現(xiàn)勺远。

Redis list 的實(shí)現(xiàn)為一個(gè)雙向鏈表,即可以支持反向查找和遍歷时鸵,更方便操作胶逢,不過(guò)帶來(lái)了部分額外的內(nèi)存開(kāi)銷。

另外可以通過(guò) lrange 命令,就是從某個(gè)元素開(kāi)始讀取多少個(gè)元素初坠,可以基于 list 實(shí)現(xiàn)分頁(yè)查詢和簸,這個(gè)很棒的一個(gè)功能,基于 redis 實(shí)現(xiàn)簡(jiǎn)單的高性能分頁(yè)碟刺,可以做類似微博那種下拉不斷分頁(yè)的東西(一頁(yè)一頁(yè)的往下走)比搭,性能高。

4.Set

常用命令:
sadd,spop,smembers,sunion 等

set 對(duì)外提供的功能與list類似是一個(gè)列表的功能南誊,特殊之處在于 set 是可以自動(dòng)排重的身诺。

當(dāng)你需要存儲(chǔ)一個(gè)列表數(shù)據(jù),又不希望出現(xiàn)重復(fù)數(shù)據(jù)時(shí)抄囚,set是一個(gè)很好的選擇霉赡,并且set提供了判斷某個(gè)成員是否在一個(gè)set集合內(nèi)的重要接口,這個(gè)也是list所不能提供的幔托⊙鳎可以基于 set 輕易實(shí)現(xiàn)交集、并集重挑、差集的操作嗓化。

比如:在微博應(yīng)用中,可以將一個(gè)用戶所有的關(guān)注人存在一個(gè)集合中谬哀,將其所有粉絲存在一個(gè)集合刺覆。Redis可以非常方便的實(shí)現(xiàn)如共同關(guān)注、共同粉絲史煎、共同喜好等功能谦屑。這個(gè)過(guò)程也就是求交集的過(guò)程,具體命令如下:

sinterstore key1 key2 key3     將交集存在key1內(nèi)

5.Sorted Set

常用命令: zadd,zrange,zrem,zcard等

和set相比篇梭,sorted set增加了一個(gè)權(quán)重參數(shù)score氢橙,使得集合中的元素能夠按score進(jìn)行有序排列。

舉例: 在直播系統(tǒng)中恬偷,實(shí)時(shí)排行信息包含直播間在線用戶列表悍手,各種禮物排行榜,彈幕消息(可以理解為按消息維度的消息排行榜)等信息袍患,適合使用 Redis 中的 Sorted Set 結(jié)構(gòu)進(jìn)行存儲(chǔ)坦康。

redis 設(shè)置過(guò)期時(shí)間

Redis中有個(gè)設(shè)置時(shí)間過(guò)期的功能,即對(duì)存儲(chǔ)在 redis 數(shù)據(jù)庫(kù)中的值可以設(shè)置一個(gè)過(guò)期時(shí)間协怒。作為一個(gè)緩存數(shù)據(jù)庫(kù)涝焙,這是非常實(shí)用的。如我們一般項(xiàng)目中的 token 或者一些登錄信息孕暇,尤其是短信驗(yàn)證碼都是有時(shí)間限制的仑撞,按照傳統(tǒng)的數(shù)據(jù)庫(kù)處理方式赤兴,一般都是自己判斷過(guò)期,這樣無(wú)疑會(huì)嚴(yán)重影響項(xiàng)目性能隧哮。

我們 set key 的時(shí)候桶良,都可以給一個(gè) expire time,就是過(guò)期時(shí)間沮翔,通過(guò)過(guò)期時(shí)間我們可以指定這個(gè) key 可以存活的時(shí)間陨帆。

如果假設(shè)你設(shè)置了一批 key 只能存活1個(gè)小時(shí),那么接下來(lái)1小時(shí)后采蚀,redis是怎么對(duì)這批key進(jìn)行刪除的疲牵?

定期刪除+惰性刪除。

通過(guò)名字大概就能猜出這兩個(gè)刪除方式的意思了榆鼠。

  • 定期刪除:redis默認(rèn)是每隔 100ms 就隨機(jī)抽取一些設(shè)置了過(guò)期時(shí)間的key纲爸,檢查其是否過(guò)期,如果過(guò)期就刪除妆够。注意這里是隨機(jī)抽取的识啦。為什么要隨機(jī)呢?你想一想假如 redis 存了幾十萬(wàn)個(gè) key 神妹,每隔100ms就遍歷所有的設(shè)置過(guò)期時(shí)間的 key 的話颓哮,就會(huì)給 CPU 帶來(lái)很大的負(fù)載!
  • 惰性刪除 :定期刪除可能會(huì)導(dǎo)致很多過(guò)期 key 到了時(shí)間并沒(méi)有被刪除掉鸵荠。所以就有了惰性刪除冕茅。假如你的過(guò)期 key,靠定期刪除沒(méi)有被刪除掉腰鬼,還停留在內(nèi)存里嵌赠,除非你的系統(tǒng)去查一下那個(gè) key,才會(huì)被redis給刪除掉熄赡。這就是所謂的惰性刪除,也是夠懶的哈齿税!

但是僅僅通過(guò)設(shè)置過(guò)期時(shí)間還是有問(wèn)題的彼硫。我們想一下:如果定期刪除漏掉了很多過(guò)期 key,然后你也沒(méi)及時(shí)去查凌箕,也就沒(méi)走惰性刪除拧篮,此時(shí)會(huì)怎么樣?如果大量過(guò)期key堆積在內(nèi)存里牵舱,導(dǎo)致redis內(nèi)存塊耗盡了串绩。怎么解決這個(gè)問(wèn)題呢? redis 內(nèi)存淘汰機(jī)制芜壁。

redis 內(nèi)存淘汰機(jī)制(MySQL里有2000w數(shù)據(jù)礁凡,Redis中只存20w的數(shù)據(jù)高氮,如何保證Redis中的數(shù)據(jù)都是熱點(diǎn)數(shù)據(jù)?)

redis 配置文件 redis.conf 中有相關(guān)注釋,我這里就不貼了顷牌,大家可以自行查閱或者通過(guò)這個(gè)網(wǎng)址查看: http://download.redis.io/redis-stable/redis.conf

redis 提供 6種數(shù)據(jù)淘汰策略:

  1. volatile-lru:從已設(shè)置過(guò)期時(shí)間的數(shù)據(jù)集(server.db[i].expires)中挑選最近最少使用的數(shù)據(jù)淘汰
  2. volatile-ttl:從已設(shè)置過(guò)期時(shí)間的數(shù)據(jù)集(server.db[i].expires)中挑選將要過(guò)期的數(shù)據(jù)淘汰
  3. volatile-random:從已設(shè)置過(guò)期時(shí)間的數(shù)據(jù)集(server.db[i].expires)中任意選擇數(shù)據(jù)淘汰
  4. allkeys-lru:當(dāng)內(nèi)存不足以容納新寫入數(shù)據(jù)時(shí)剪芍,在鍵空間中,移除最近最少使用的key(這個(gè)是最常用的)
  5. allkeys-random:從數(shù)據(jù)集(server.db[i].dict)中任意選擇數(shù)據(jù)淘汰
  6. no-eviction:禁止驅(qū)逐數(shù)據(jù)窟蓝,也就是說(shuō)當(dāng)內(nèi)存不足以容納新寫入數(shù)據(jù)時(shí)罪裹,新寫入操作會(huì)報(bào)錯(cuò)。這個(gè)應(yīng)該沒(méi)人使用吧运挫!

4.0版本后增加以下兩種:

  1. volatile-lfu:從已設(shè)置過(guò)期時(shí)間的數(shù)據(jù)集(server.db[i].expires)中挑選最不經(jīng)常使用的數(shù)據(jù)淘汰
  2. allkeys-lfu:當(dāng)內(nèi)存不足以容納新寫入數(shù)據(jù)時(shí)状共,在鍵空間中,移除最不經(jīng)常使用的key

備注: 關(guān)于 redis 設(shè)置過(guò)期時(shí)間以及內(nèi)存淘汰機(jī)制谁帕,我這里只是簡(jiǎn)單的總結(jié)一下峡继,后面會(huì)專門寫一篇文章來(lái)總結(jié)!

redis 持久化機(jī)制(怎么保證 redis 掛掉之后再重啟數(shù)據(jù)可以進(jìn)行恢復(fù))

很多時(shí)候我們需要持久化數(shù)據(jù)也就是將內(nèi)存中的數(shù)據(jù)寫入到硬盤里面雇卷,大部分原因是為了之后重用數(shù)據(jù)(比如重啟機(jī)器鬓椭、機(jī)器故障之后恢復(fù)數(shù)據(jù)),或者是為了防止系統(tǒng)故障而將數(shù)據(jù)備份到一個(gè)遠(yuǎn)程位置关划。

Redis不同于Memcached的很重一點(diǎn)就是小染,Redis支持持久化,而且支持兩種不同的持久化操作贮折。Redis的一種持久化方式叫快照(snapshotting裤翩,RDB),另一種方式是只追加文件(append-only file,AOF)调榄。這兩種方法各有千秋踊赠,下面我會(huì)詳細(xì)這兩種持久化方法是什么,怎么用每庆,如何選擇適合自己的持久化方法。

快照(snapshotting)持久化(RDB)

Redis可以通過(guò)創(chuàng)建快照來(lái)獲得存儲(chǔ)在內(nèi)存里面的數(shù)據(jù)在某個(gè)時(shí)間點(diǎn)上的副本伦籍。Redis創(chuàng)建快照之后腮出,可以對(duì)快照進(jìn)行備份帖鸦,可以將快照復(fù)制到其他服務(wù)器從而創(chuàng)建具有相同數(shù)據(jù)的服務(wù)器副本(Redis主從結(jié)構(gòu),主要用來(lái)提高Redis性能)胚嘲,還可以將快照留在原地以便重啟服務(wù)器的時(shí)候使用馋劈。

快照持久化是Redis默認(rèn)采用的持久化方式攻锰,在redis.conf配置文件中默認(rèn)有此下配置:


save 900 1           #在900秒(15分鐘)之后晾嘶,如果至少有1個(gè)key發(fā)生變化,Redis就會(huì)自動(dòng)觸發(fā)BGSAVE命令創(chuàng)建快照口注。

save 300 10          #在300秒(5分鐘)之后寝志,如果至少有10個(gè)key發(fā)生變化,Redis就會(huì)自動(dòng)觸發(fā)BGSAVE命令創(chuàng)建快照毫缆。

save 60 10000        #在60秒(1分鐘)之后乐导,如果至少有10000個(gè)key發(fā)生變化,Redis就會(huì)自動(dòng)觸發(fā)BGSAVE命令創(chuàng)建快照旺拉。

AOF(append-only file)持久化

與快照持久化相比棵磷,AOF持久化 的實(shí)時(shí)性更好,因此已成為主流的持久化方案沉桌。默認(rèn)情況下Redis沒(méi)有開(kāi)啟AOF(append only file)方式的持久化算吩,可以通過(guò)appendonly參數(shù)開(kāi)啟:

appendonly yes

開(kāi)啟AOF持久化后每執(zhí)行一條會(huì)更改Redis中的數(shù)據(jù)的命令偎巢,Redis就會(huì)將該命令寫入硬盤中的AOF文件。AOF文件的保存位置和RDB文件的位置相同挎扰,都是通過(guò)dir參數(shù)設(shè)置的巢音,默認(rèn)的文件名是appendonly.aof尽超。

在Redis的配置文件中存在三種不同的 AOF 持久化方式似谁,它們分別是:

appendfsync always    #每次有數(shù)據(jù)修改發(fā)生時(shí)都會(huì)寫入AOF文件,這樣會(huì)嚴(yán)重降低Redis的速度
appendfsync everysec  #每秒鐘同步一次掠哥,顯示地將多個(gè)寫命令同步到硬盤
appendfsync no        #讓操作系統(tǒng)決定何時(shí)進(jìn)行同步

為了兼顧數(shù)據(jù)和寫入性能续搀,用戶可以考慮 appendfsync everysec選項(xiàng) 菠净,讓Redis每秒同步一次AOF文件,Redis性能幾乎沒(méi)受到任何影響牵咙。而且這樣即使出現(xiàn)系統(tǒng)崩潰洁桌,用戶最多只會(huì)丟失一秒之內(nèi)產(chǎn)生的數(shù)據(jù)侯嘀。當(dāng)硬盤忙于執(zhí)行寫入操作的時(shí)候,Redis還會(huì)優(yōu)雅的放慢自己的速度以便適應(yīng)硬盤的最大寫入速度吠谢。

Redis 4.0 對(duì)于持久化機(jī)制的優(yōu)化

Redis 4.0 開(kāi)始支持 RDB 和 AOF 的混合持久化(默認(rèn)關(guān)閉溪食,可以通過(guò)配置項(xiàng) aof-use-rdb-preamble 開(kāi)啟)错沃。

如果把混合持久化打開(kāi),AOF 重寫的時(shí)候就直接把 RDB 的內(nèi)容寫到 AOF 文件開(kāi)頭玉掸。這樣做的好處是可以結(jié)合 RDB 和 AOF 的優(yōu)點(diǎn), 快速加載同時(shí)避免丟失過(guò)多的數(shù)據(jù)醒叁。當(dāng)然缺點(diǎn)也是有的把沼, AOF 里面的 RDB 部分是壓縮格式不再是 AOF 格式,可讀性較差租谈。

補(bǔ)充內(nèi)容:AOF 重寫

AOF重寫可以產(chǎn)生一個(gè)新的AOF文件捆愁,這個(gè)新的AOF文件和原有的AOF文件所保存的數(shù)據(jù)庫(kù)狀態(tài)一樣,但體積更小呻逆。

AOF重寫是一個(gè)有歧義的名字咖城,該功能是通過(guò)讀取數(shù)據(jù)庫(kù)中的鍵值對(duì)來(lái)實(shí)現(xiàn)的,程序無(wú)須對(duì)現(xiàn)有AOF文件進(jìn)行任何讀入滓彰、分析或者寫入操作州袒。

在執(zhí)行 BGREWRITEAOF 命令時(shí)郎哭,Redis 服務(wù)器會(huì)維護(hù)一個(gè) AOF 重寫緩沖區(qū),該緩沖區(qū)會(huì)在子進(jìn)程創(chuàng)建新AOF文件期間邦蜜,記錄服務(wù)器執(zhí)行的所有寫命令亥至。當(dāng)子進(jìn)程完成創(chuàng)建新AOF文件的工作之后姐扮,服務(wù)器會(huì)將重寫緩沖區(qū)中的所有內(nèi)容追加到新AOF文件的末尾,使得新舊兩個(gè)AOF文件所保存的數(shù)據(jù)庫(kù)狀態(tài)一致壤靶。最后惊搏,服務(wù)器用新的AOF文件替換舊的AOF文件恬惯,以此來(lái)完成AOF文件重寫操作

更多內(nèi)容可以查看我的這篇文章:

redis 事務(wù)

Redis 通過(guò) MULTI、EXEC亲铡、WATCH 等命令來(lái)實(shí)現(xiàn)事務(wù)(transaction)功能。事務(wù)提供了一種將多個(gè)命令請(qǐng)求打包,然后一次性吆鹤、按順序地執(zhí)行多個(gè)命令的機(jī)制洲守,并且在事務(wù)執(zhí)行期間梗醇,服務(wù)器不會(huì)中斷事務(wù)而改去執(zhí)行其他客戶端的命令請(qǐng)求,它會(huì)將事務(wù)中的所有命令都執(zhí)行完畢温鸽,然后才去處理其他客戶端的命令請(qǐng)求手负。

在傳統(tǒng)的關(guān)系式數(shù)據(jù)庫(kù)中竟终,常常用 ACID 性質(zhì)來(lái)檢驗(yàn)事務(wù)功能的可靠性和安全性。在 Redis 中榆芦,事務(wù)總是具有原子性(Atomicity)喘鸟、一致性(Consistency)和隔離性(Isolation)迷守,并且當(dāng) Redis 運(yùn)行在某種特定的持久化模式下時(shí),事務(wù)也具有持久性(Durability)凯力。

緩存雪崩和緩存穿透問(wèn)題解決方案

緩存雪崩

簡(jiǎn)介:緩存同一時(shí)間大面積的失效咐鹤,所以圣絮,后面的請(qǐng)求都會(huì)落到數(shù)據(jù)庫(kù)上,造成數(shù)據(jù)庫(kù)短時(shí)間內(nèi)承受大量請(qǐng)求而崩掉捧请。

解決辦法(中華石杉老師在他的視頻中提到過(guò)疹蛉,視頻地址在最后一個(gè)問(wèn)題中有提到):

  • 事前:盡量保證整個(gè) redis 集群的高可用性,發(fā)現(xiàn)機(jī)器宕機(jī)盡快補(bǔ)上育韩。選擇合適的內(nèi)存淘汰策略闺鲸。
  • 事中:本地ehcache緩存 + hystrix限流&降級(jí)摸恍,避免MySQL崩掉
  • 事后:利用 redis 持久化機(jī)制保存的數(shù)據(jù)盡快恢復(fù)緩存
image

緩存穿透

簡(jiǎn)介:一般是黑客故意去請(qǐng)求緩存中不存在的數(shù)據(jù)误墓,導(dǎo)致所有的請(qǐng)求都落到數(shù)據(jù)庫(kù)上,造成數(shù)據(jù)庫(kù)短時(shí)間內(nèi)承受大量請(qǐng)求而崩掉然想。

解決辦法: 有很多種方法可以有效地解決緩存穿透問(wèn)題变泄,最常見(jiàn)的則是采用布隆過(guò)濾器恼琼,將所有可能存在的數(shù)據(jù)哈希到一個(gè)足夠大的bitmap中晴竞,一個(gè)一定不存在的數(shù)據(jù)會(huì)被 這個(gè)bitmap攔截掉,從而避免了對(duì)底層存儲(chǔ)系統(tǒng)的查詢壓力颤难。另外也有一個(gè)更為簡(jiǎn)單粗暴的方法(我們采用的就是這種)已维,如果一個(gè)查詢返回的數(shù)據(jù)為空(不管是數(shù) 據(jù)不存在垛耳,還是系統(tǒng)故障)飘千,我們?nèi)匀话堰@個(gè)空結(jié)果進(jìn)行緩存护奈,但它的過(guò)期時(shí)間會(huì)很短甫恩,最長(zhǎng)不超過(guò)五分鐘磺箕。

參考:

如何解決 Redis 的并發(fā)競(jìng)爭(zhēng) Key 問(wèn)題

所謂 Redis 的并發(fā)競(jìng)爭(zhēng) Key 的問(wèn)題也就是多個(gè)系統(tǒng)同時(shí)對(duì)一個(gè) key 進(jìn)行操作抛虫,但是最后執(zhí)行的順序和我們期望的順序不同建椰,這樣也就導(dǎo)致了結(jié)果的不同!

推薦一種方案:分布式鎖(zookeeper 和 redis 都可以實(shí)現(xiàn)分布式鎖)屠列。(如果不存在 Redis 的并發(fā)競(jìng)爭(zhēng) Key 問(wèn)題伞矩,不要使用分布式鎖乃坤,這樣會(huì)影響性能)

基于zookeeper臨時(shí)有序節(jié)點(diǎn)可以實(shí)現(xiàn)的分布式鎖。大致思想為:每個(gè)客戶端對(duì)某個(gè)方法加鎖時(shí)狱杰,在zookeeper上的與該方法對(duì)應(yīng)的指定節(jié)點(diǎn)的目錄下仿畸,生成一個(gè)唯一的瞬時(shí)有序節(jié)點(diǎn)朗和。 判斷是否獲取鎖的方式很簡(jiǎn)單例隆,只需要判斷有序節(jié)點(diǎn)中序號(hào)最小的一個(gè)。 當(dāng)釋放鎖的時(shí)候船逮,只需將這個(gè)瞬時(shí)節(jié)點(diǎn)刪除即可吴侦。同時(shí)备韧,其可以避免服務(wù)宕機(jī)導(dǎo)致的鎖無(wú)法釋放,而產(chǎn)生的死鎖問(wèn)題叠艳。完成業(yè)務(wù)流程后易阳,刪除對(duì)應(yīng)的子節(jié)點(diǎn)釋放鎖潦俺。

在實(shí)踐中,當(dāng)然是從以可靠性為主早像。所以首推Zookeeper卢鹦。

參考:

如何保證緩存與數(shù)據(jù)庫(kù)雙寫時(shí)的數(shù)據(jù)一致性?

你只要用緩存遏匆,就可能會(huì)涉及到緩存與數(shù)據(jù)庫(kù)雙存儲(chǔ)雙寫幅聘,你只要是雙寫,就一定會(huì)有數(shù)據(jù)一致性的問(wèn)題荐糜,那么你如何解決一致性問(wèn)題葛超?

一般來(lái)說(shuō)绣张,就是如果你的系統(tǒng)不是嚴(yán)格要求緩存+數(shù)據(jù)庫(kù)必須一致性的話侥涵,緩存可以稍微的跟數(shù)據(jù)庫(kù)偶爾有不一致的情況宋雏,最好不要做這個(gè)方案磨总,讀請(qǐng)求和寫請(qǐng)求串行化笼沥,串到一個(gè)內(nèi)存隊(duì)列里去奔浅,這樣就可以保證一定不會(huì)出現(xiàn)不一致的情況

串行化之后,就會(huì)導(dǎo)致系統(tǒng)的吞吐量會(huì)大幅度的降低厕诡,用比正常情況下多幾倍的機(jī)器去支撐線上的一個(gè)請(qǐng)求。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末葛作,一起剝皮案震驚了整個(gè)濱河市赂蠢,隨后出現(xiàn)的幾起案子辨泳,更是在濱河造成了極大的恐慌菠红,老刑警劉巖,帶你破解...
    沈念sama閱讀 223,126評(píng)論 6 520
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蔑滓,死亡現(xiàn)場(chǎng)離奇詭異键袱,居然都是意外死亡蹄咖,警方通過(guò)查閱死者的電腦和手機(jī)付鹿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,421評(píng)論 3 400
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)慢叨,“玉大人务蝠,你說(shuō)我怎么就攤上這事馏段≡合玻” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 169,941評(píng)論 0 366
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)硫麻。 經(jīng)常有香客問(wèn)我拿愧,道長(zhǎng),這世上最難降的妖魔是什么券敌? 我笑而不...
    開(kāi)封第一講書人閱讀 60,294評(píng)論 1 300
  • 正文 為了忘掉前任待诅,我火速辦了婚禮咱士,結(jié)果婚禮上轧钓,老公的妹妹穿的比我還像新娘毕箍。我一直安慰自己,他們只是感情好文捶,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,295評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布种远。 她就那樣靜靜地躺著顽耳,像睡著了一般射富。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上限次,一...
    開(kāi)封第一講書人閱讀 52,874評(píng)論 1 314
  • 那天卖漫,我揣著相機(jī)與錄音懊亡,去河邊找鬼乎串。 笑死叹誉,一個(gè)胖子當(dāng)著我的面吹牛闷旧,可吹牛的內(nèi)容都是我干的忙灼。 我是一名探鬼主播该园,決...
    沈念sama閱讀 41,285評(píng)論 3 424
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼里初,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了淮阐?” 一聲冷哼從身側(cè)響起泣特,我...
    開(kāi)封第一講書人閱讀 40,249評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤状您,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后缴饭,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體颗搂,經(jīng)...
    沈念sama閱讀 46,760評(píng)論 1 321
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡丢氢,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,840評(píng)論 3 343
  • 正文 我和宋清朗相戀三年疚察,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了貌嫡。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片该溯。...
    茶點(diǎn)故事閱讀 40,973評(píng)論 1 354
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖狈茉,靈堂內(nèi)的尸體忽然破棺而出夫椭,到底是詐尸還是另有隱情,我是刑警寧澤氯庆,帶...
    沈念sama閱讀 36,631評(píng)論 5 351
  • 正文 年R本政府宣布蹭秋,位于F島的核電站,受9級(jí)特大地震影響堤撵,放射性物質(zhì)發(fā)生泄漏仁讨。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,315評(píng)論 3 336
  • 文/蒙蒙 一实昨、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦族跛、人聲如沸闰挡。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 32,797評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)长酗。三九已至,卻和暖如春桐绒,著一層夾襖步出監(jiān)牢的瞬間夺脾,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,926評(píng)論 1 275
  • 我被黑心中介騙來(lái)泰國(guó)打工茉继, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留咧叭,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,431評(píng)論 3 379
  • 正文 我出身青樓烁竭,卻偏偏與公主長(zhǎng)得像菲茬,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子派撕,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,982評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容

  • 一婉弹、Redis高可用概述 在介紹Redis高可用之前,先說(shuō)明一下在Redis的語(yǔ)境中高可用的含義终吼。 我們知道镀赌,在w...
    空語(yǔ)閱讀 1,599評(píng)論 0 2
  • 1.1 資料 ,最好的入門小冊(cè)子际跪,可以先于一切文檔之前看商佛,免費(fèi)。 作者Antirez的博客姆打,Antirez維護(hù)的R...
    JefferyLcm閱讀 17,071評(píng)論 1 51
  • NOSQL類型簡(jiǎn)介鍵值對(duì):會(huì)使用到一個(gè)哈希表威彰,表中有一個(gè)特定的鍵和一個(gè)指針指向特定的數(shù)據(jù),如redis穴肘,volde...
    MicoCube閱讀 4,003評(píng)論 2 27
  • 五種數(shù)據(jù)結(jié)構(gòu)簡(jiǎn)介 Redis是使用C編寫的,內(nèi)部實(shí)現(xiàn)了一個(gè)struct結(jié)構(gòu)體redisObject對(duì)象舔痕,通過(guò)結(jié)構(gòu)體...
    彥幀閱讀 6,952評(píng)論 0 14
  • 企業(yè)級(jí)redis集群架構(gòu)的特點(diǎn) 海量數(shù)據(jù) 高并發(fā) 高可用 要達(dá)到高可用评抚,持久化是不可減少的,持久化主要是做災(zāi)難恢復(fù)...
    lucode閱讀 2,208評(píng)論 0 7