自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

關(guān)于Redis的n種妙用,不僅僅是緩存

數(shù)據(jù)庫 其他數(shù)據(jù)庫 Redis
redis是鍵值對的數(shù)據(jù)庫,常用的五種數(shù)據(jù)類型為字符串類型(string),散列類型(hash),列表類型(list),集合類型(set),有序集合類型(zset)。Redis用作緩存,主要兩個(gè)用途:高性能,高并發(fā),因?yàn)閮?nèi)存天然支持高并發(fā)。

關(guān)于Redis的n種妙用,不僅僅是緩存

redis是鍵值對的數(shù)據(jù)庫,常用的五種數(shù)據(jù)類型為字符串類型(string),散列類型(hash),列表類型(list),集合類型(set),有序集合類型(zset)。

Redis用作緩存,主要兩個(gè)用途:高性能,高并發(fā),因?yàn)閮?nèi)存天然支持高并發(fā)。

應(yīng)用場景

分布式鎖(string)

setnx key value,當(dāng)key不存在時(shí),將 key 的值設(shè)為 value ,返回1。若給定的 key 已經(jīng)存在,則setnx不做任何動作,返回0。

當(dāng)setnx返回1時(shí),表示獲取鎖,做完操作以后del key,表示釋放鎖,如果setnx返回0表示獲取鎖失敗,整體思路大概就是這樣,細(xì)節(jié)還是比較多的,有時(shí)間單開一篇來講解

計(jì)數(shù)器(string)

如知乎每個(gè)問題的被瀏覽器次數(shù)。

關(guān)于Redis的n種妙用,不僅僅是緩存(附有自學(xué)資料分享哦)
  1. set key 0 
  2. incr key // incr readcount::{帖子id} 每閱讀一次 
  3. get key // get readcount::{帖子id} 獲取閱讀量 

分布式全局唯一id(string)

分布式全局唯一id的實(shí)現(xiàn)方式有很多,這里只介紹用redis實(shí)現(xiàn)。

關(guān)于Redis的n種妙用,不僅僅是緩存(附有自學(xué)資料分享哦) 

每次獲取userId的時(shí)候,對userId加1再獲取,可以改進(jìn)為如下形式:

關(guān)于Redis的n種妙用,不僅僅是緩存(附有自學(xué)資料分享哦) 

直接獲取一段userId的最大值,緩存到本地慢慢累加,快到了userId的最大值時(shí),再去獲取一段,一個(gè)用戶服務(wù)宕機(jī)了,也頂多一小段userId沒有用到

  1. set userId 0 
  2. incr usrId //返回1 
  3. incrby userId 1000 //返回10001 

消息隊(duì)列(list)

在list里面一邊進(jìn),一邊出即可

  1. # 實(shí)現(xiàn)方式一 
  2. # 一直往list左邊放 
  3. lpush key value  
  4. key這個(gè)list有元素時(shí),直接彈出,沒有元素被阻塞,直到等待超時(shí)或發(fā)現(xiàn)可彈出元素為止,上面例子超時(shí)時(shí)間為10s 
  5. brpop key value 10  
  6. # 實(shí)現(xiàn)方式二 
  7. rpush key value 
  8. blpop key value 10 

關(guān)于Redis的n種妙用,不僅僅是緩存(附有自學(xué)資料分享哦) 

新浪/Twitter用戶消息列表(list)

關(guān)于Redis的n種妙用,不僅僅是緩存(附有自學(xué)資料分享哦) 

假如說小編li關(guān)注了2個(gè)微博a和b,a發(fā)了一條微博(編號為100)就執(zhí)行如下命令:

  1. lpush msg::li 100 

b發(fā)了一條微博(編號為200)就執(zhí)行如下命令:

  1. lpush msg::li 200 

假如想拿最近的10條消息就可以執(zhí)行如下命令(最新的消息一定在list的最左邊):

  1. # 下標(biāo)從0開始,[start,stop]是閉區(qū)間,都包含 
  2. lrange msg::li 0 9  

抽獎活動(set)

  1. # 參加抽獎活動 
  2. sadd key {userId}  
  3. # 獲取所有抽獎用戶,大輪盤轉(zhuǎn)起來 
  4. smembers key  
  5. # 抽取count名中獎?wù)?,并從抽獎活動中移?nbsp;
  6. spop key count  
  7. # 抽取count名中獎?wù)?,不從抽獎活動中移?nbsp;
  8. srandmember key count 

實(shí)現(xiàn)點(diǎn)贊,簽到,like等功能(set)

關(guān)于Redis的n種妙用,不僅僅是緩存(附有自學(xué)資料分享哦) 

  1. # 1001用戶給8001帖子點(diǎn)贊 
  2. sadd like::8001 1001 
  3. # 取消點(diǎn)贊 
  4. srem like::8001 1001 
  5. # 檢查用戶是否點(diǎn)過贊 
  6. sismember like::8001 1001  
  7. # 獲取點(diǎn)贊的用戶列表 
  8. smembers like::8001  
  9. # 獲取點(diǎn)贊用戶數(shù) 
  10. scard like::8001  
  11. 實(shí)現(xiàn)關(guān)注模型,可能認(rèn)識的人(set) 

關(guān)于Redis的n種妙用,不僅僅是緩存(附有自學(xué)資料分享哦)

seven關(guān)注的人

sevenSub -> {qing, mic, james}

青山關(guān)注的人

qingSub->{seven,jack,mic,james}

Mic關(guān)注的人

MicSub->{seven,james,qing,jack,tom}

  1. # 返回sevenSub和qingSub的交集,即seven和青山的共同關(guān)注 
  2. sinter sevenSub qingSub -> {mic,james} 
  3. # 我關(guān)注的人也關(guān)注他,下面例子中我是seven 
  4. # qing在micSub中返回1,否則返回0 
  5. sismember micSub qing 
  6. sismember jamesSub qing 
  7. # 我可能認(rèn)識的人,下面例子中我是seven 
  8. # 求qingSub和sevenSub的差集,并存在sevenMayKnow集合中 
  9. sdiffstore sevenMayKnow qingSub sevenSub -> {seven,jack} 

電商商品篩選(set)

關(guān)于Redis的n種妙用,不僅僅是緩存(附有自學(xué)資料分享哦)

每個(gè)商品入庫的時(shí)候即會建立他的靜態(tài)標(biāo)簽列表如,品牌,尺寸,處理器,內(nèi)存。

  1. # 將拯救者y700P-001和ThinkPad-T480這兩個(gè)元素放到集合brand::lenovo 
  2. sadd brand::lenovo 拯救者y700P-001 ThinkPad-T480 
  3. sadd screenSize::15.6 拯救者y700P-001 機(jī)械革命Z2AIR 
  4. sadd processor::i7 拯救者y700P-001 機(jī)械革命X8TIPlus 
  5. # 獲取品牌為聯(lián)想,屏幕尺寸為15.6,并且處理器為i7的電腦品牌(sinter為獲取集合的交集) 
  6. sinter brand::lenovo screenSize::15.6 processor::i7 -> 拯救者y700P-001 

排行版(zset)

redis的zset天生是用來做排行榜的、好友列表, 去重, 歷史記錄等業(yè)務(wù)需求。

關(guān)于Redis的n種妙用,不僅僅是緩存(附有自學(xué)資料分享哦)

  1. # user1的用戶分?jǐn)?shù)為 10 
  2. zadd ranking 10 user1 
  3. zadd ranking 20 user2 
  4. # 取分?jǐn)?shù)最高的3個(gè)用戶 
  5. zrevrange ranking 0 2 withscores 

過期策略

定期刪除

redis 會將每個(gè)設(shè)置了過期時(shí)間的 key 放入到一個(gè)獨(dú)立的字典中,以后會定期遍歷這個(gè)字典來刪除到期的 key。

定期刪除策略

Redis 默認(rèn)會每秒進(jìn)行十次過期掃描(100ms一次),過期掃描不會遍歷過期字典中所有的 key,而是采用了一種簡單的貪心策略。

從過期字典中隨機(jī) 20 個(gè) key;

刪除這 20 個(gè) key 中已經(jīng)過期的 key;

如果過期的 key 比率超過 1/4,那就重復(fù)步驟 1;

惰性刪除

除了定期遍歷之外,它還會使用惰性策略來刪除過期的 key,所謂惰性策略就是在客戶端訪問這個(gè) key 的時(shí)候,redis 對 key 的過期時(shí)間進(jìn)行檢查,如果過期了就立即刪除,不會給你返回任何東西。

定期刪除是集中處理,惰性刪除是零散處理。

為什么要采用定期刪除+惰性刪除2種策略呢?

如果過期就刪除。假設(shè)redis里放了10萬個(gè)key,都設(shè)置了過期時(shí)間,你每隔幾百毫秒,就檢查10萬個(gè)key,那redis基本上就死了,cpu負(fù)載會很高的,消耗在你的檢查過期key上了

但是問題是,定期刪除可能會導(dǎo)致很多過期key到了時(shí)間并沒有被刪除掉,那咋整呢?所以就是惰性刪除了。這就是說,在你獲取某個(gè)key的時(shí)候,redis會檢查一下 ,這個(gè)key如果設(shè)置了過期時(shí)間那么是否過期了?如果過期了此時(shí)就會刪除,不會給你返回任何東西。

并不是key到時(shí)間就被刪除掉,而是你查詢這個(gè)key的時(shí)候,redis再懶惰的檢查一下。

通過上述兩種手段結(jié)合起來,保證過期的key一定會被干掉。

所以說用了上述2種策略后,下面這種現(xiàn)象就不難解釋了:數(shù)據(jù)明明都過期了,但是還占有著內(nèi)存。

內(nèi)存淘汰策略

這個(gè)問題可能有小伙伴們遇到過,放到Redis中的數(shù)據(jù)怎么沒了?

因?yàn)镽edis將數(shù)據(jù)放到內(nèi)存中,內(nèi)存是有限的,比如redis就只能用10個(gè)G,你要是往里面寫了20個(gè)G的數(shù)據(jù),會咋辦?當(dāng)然會干掉10個(gè)G的數(shù)據(jù),然后就保留10個(gè)G的數(shù)據(jù)了。那干掉哪些數(shù)據(jù)?保留哪些數(shù)據(jù)?當(dāng)然是干掉不常用的數(shù)據(jù),保留常用的數(shù)據(jù)了。

Redis提供的內(nèi)存淘汰策略有如下幾種:

  1. noeviction 不會繼續(xù)服務(wù)寫請求 (DEL 請求可以繼續(xù)服務(wù)),讀請求可以繼續(xù)進(jìn)行。這樣可以保證不會丟失數(shù)據(jù),但是會讓線上的業(yè)務(wù)不能持續(xù)進(jìn)行。這是默認(rèn)的淘汰策略。
  2. volatile-lru 嘗試淘汰設(shè)置了過期時(shí)間的 key,最少使用的 key 優(yōu)先被淘汰。沒有設(shè)置過期時(shí)間的 key 不會被淘汰,這樣可以保證需要持久化的數(shù)據(jù)不會突然丟失。(這個(gè)是使用最多的)
  3. volatile-ttl 跟上面一樣,除了淘汰的策略不是 LRU,而是 key 的剩余壽命 ttl 的值,ttl 越小越優(yōu)先被淘汰。
  4. volatile-random 跟上面一樣,不過淘汰的 key 是過期 key 集合中隨機(jī)的 key。
  5. allkeys-lru 區(qū)別于 volatile-lru,這個(gè)策略要淘汰的 key 對象是全體的 key 集合,而不只是過期的 key 集合。這意味著沒有設(shè)置過期時(shí)間的 key 也會被淘汰。
  6. allkeys-random 跟上面一樣,不過淘汰的策略是隨機(jī)的 key。allkeys-random 跟上面一樣,不過淘汰的策略是隨機(jī)的 key。

持久化策略

Redis的數(shù)據(jù)是存在內(nèi)存中的,如果Redis發(fā)生宕機(jī),那么數(shù)據(jù)會全部丟失,因此必須提供持久化機(jī)制。

Redis 的持久化機(jī)制有兩種,第一種是快照(RDB),第二種是 AOF 日志??煺帐且淮稳總浞?,AOF 日志是連續(xù)的增量備份??煺帐莾?nèi)存數(shù)據(jù)的二進(jìn)制序列化形式,在存儲上非常緊湊,而 AOF 日志記錄的是內(nèi)存數(shù)據(jù)修改的指令記錄文本。AOF 日志在長期的運(yùn)行過程中會變的無比龐大,數(shù)據(jù)庫重啟時(shí)需要加載 AOF 日志進(jìn)行指令重放,這個(gè)時(shí)間就會無比漫長。所以需要定期進(jìn)行 AOF 重寫,給 AOF 日志進(jìn)行瘦身。

RDB是通過Redis主進(jìn)程fork子進(jìn)程,讓子進(jìn)程執(zhí)行磁盤 IO 操作來進(jìn)行 RDB 持久化,AOF 日志存儲的是 Redis 服務(wù)器的順序指令序列,AOF 日志只記錄對內(nèi)存進(jìn)行修改的指令記錄。即RDB記錄的是數(shù)據(jù),AOF記錄的是指令

RDB和AOF到底該如何選擇?

  1. 不要僅僅使用 RDB,因?yàn)槟菢訒?dǎo)致你丟失很多數(shù)據(jù),因?yàn)镽DB是隔一段時(shí)間來備份數(shù)據(jù)。
  2. 也不要僅僅使用 AOF,因?yàn)槟菢佑袃蓚€(gè)問題,第一,通過 AOF 做冷備沒有RDB恢復(fù)速度快; 第二,RDB 每次簡單粗暴生成數(shù)據(jù)快照,更加健壯,可以避免 AOF 這種復(fù)雜的備份和恢復(fù)機(jī)制的 bug。
  3. 用RDB恢復(fù)內(nèi)存狀態(tài)會丟失很多數(shù)據(jù),重放AOP日志又很慢。Redis4.0推出了混合持久化來解決這個(gè)問題。將 rdb 文件的內(nèi)容和增量的 AOF 日志文件存在一起。這里的 AOF 日志不再是全量的日志,而是自持久化開始到持久化結(jié)束的這段時(shí)間發(fā)生的增量 AOF 日志,通常這部分 AOF 日志很小。于是在 Redis 重啟的時(shí)候,可以先加載 rdb 的內(nèi)容,然后再重放增量 AOF 日志就可以完全替代之前的 AOF 全量文件重放,重啟效率因此大幅得到提升。

緩存雪崩和緩存穿透

緩存雪崩是什么?

假設(shè)有如下一個(gè)系統(tǒng),高峰期請求為5000次/秒,4000次走了緩存,只有1000次落到了數(shù)據(jù)庫上,數(shù)據(jù)庫每秒1000的并發(fā)是一個(gè)正常的指標(biāo),完全可以正常工作,但如果緩存宕機(jī)了,每秒5000次的請求會全部落到數(shù)據(jù)庫上,數(shù)據(jù)庫立馬就死掉了,因?yàn)閿?shù)據(jù)庫一秒最多抗2000個(gè)請求,如果DBA重啟數(shù)據(jù)庫,立馬又會被新的請求打死了,這就是緩存雪崩。

關(guān)于Redis的n種妙用,不僅僅是緩存(附有自學(xué)資料分享哦)

如何解決緩存雪崩

事前:redis高可用,主從+哨兵,redis cluster,避免全盤崩潰。

事中:本地ehcache緩存 + hystrix限流&降級,避免MySQL被打死。

事后:redis持久化,快速恢復(fù)緩存數(shù)據(jù)。

緩存穿透是什么?

假如客戶端每秒發(fā)送5000個(gè)請求,其中4000個(gè)為黑客的惡意攻擊,即在數(shù)據(jù)庫中也查不到。舉個(gè)例子,用戶id為正數(shù),黑客構(gòu)造的用戶id為負(fù)數(shù),

如果黑客每秒一直發(fā)送這4000個(gè)請求,緩存就不起作用,數(shù)據(jù)庫也很快被打死。

關(guān)于Redis的n種妙用,不僅僅是緩存(附有自學(xué)資料分享哦)

如何解決緩存穿透

查詢不到的數(shù)據(jù)也放到緩存,value為空,如set -999 “”

總而言之,緩存雪崩就是緩存失效,請求全部全部打到數(shù)據(jù)庫,數(shù)據(jù)庫瞬間被打死。緩存穿透就是查詢了一個(gè)一定不存在的數(shù)據(jù),并且從存儲層查不到的數(shù)據(jù)沒有寫入緩存,這將導(dǎo)致這個(gè)不存在的數(shù)據(jù)每次請求都要到存儲層去查詢,失去了緩存的意義。

 

責(zé)任編輯:龐桂玉 來源: 今日頭條
相關(guān)推薦

2019-01-09 09:13:40

2020-01-15 06:00:52

物聯(lián)網(wǎng)IOT大數(shù)據(jù)

2013-07-04 15:22:46

華為WLAN接入

2009-10-19 10:50:20

內(nèi)部云

2019-07-18 15:21:40

Linux容器IT

2020-12-16 09:27:05

數(shù)據(jù)湖大數(shù)據(jù)數(shù)據(jù)

2013-12-18 12:45:59

2013-08-22 11:27:32

云服務(wù)云存儲

2012-11-06 16:53:55

歐朋Opera瀏覽器

2015-12-01 14:26:57

2022-10-11 16:35:34

加密貨幣區(qū)塊鏈代幣

2010-03-23 10:59:14

2018-07-06 05:03:13

2012-05-11 16:46:00

激光打印機(jī)推薦

2011-12-01 16:18:09

數(shù)據(jù)治理informatica數(shù)據(jù)集成

2022-08-31 10:14:00

JavaScript網(wǎng)絡(luò)異步性

2022-06-21 10:04:25

比特幣去中心化金融體系

2020-08-24 19:00:20

國產(chǎn)操作系統(tǒng)操作系統(tǒng)

2020-01-16 08:20:44

數(shù)據(jù)隱私機(jī)密性數(shù)據(jù)安全
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號