Redis面試題及答案整理

1. Redis有哪些數(shù)據(jù)結構黍翎?

字符串String、字典Hash腻要、列表List复罐、集合Set、有序集合SortedSet雄家。

如果你是Redis中高級用戶效诅,還需要加上下面幾種數(shù)據(jù)結構HyperLogLog、Geo咳短、Pub/Sub填帽。

2. 使用過Redis分布式鎖么,它是什么回事咙好?

先拿setnx來爭搶鎖篡腌,搶到之后,再用expire給鎖加一個過期時間防止鎖忘記了釋放勾效。這時候對方會告訴你說你回答得不錯嘹悼,然后接著問如果在setnx之后執(zhí)行expire之前進程意外crash或者要重啟維護了,那會怎么樣层宫?

這時候你要給予驚訝的反饋:唉杨伙,是喔,這個鎖就永遠得不到釋放了萌腿。緊接著你需要抓一抓自己得腦袋限匣,故作思考片刻,好像接下來的結果是你主動思考出來的毁菱,然后回答:我記得set指令有非常復雜的參數(shù)米死,這個應該是可以同時把setnx和expire合成一條指令來用的!對方這時會顯露笑容贮庞,心里開始默念:摁峦筒,這小子還不錯。

jedis.set(String key, String value, String nx, String expx, int time),這個set()方法一共有五個形參:

第一個為key,我們使用key來當鎖职车,因為key是唯一的。

第二個為value峦失,我們傳的是requestId,很多童鞋可能不明白伏伐,有key作為鎖不就夠了嗎宠进,為什么還要用到value?原因就是我們在上面講到可靠性時藐翎,分布式鎖要滿足第四個條件解鈴還須系鈴人材蹬,通過給value賦值為requestId实幕,我們就知道這把鎖是哪個請求加的了,在解鎖的時候就可以有依據(jù)堤器。requestId可以使用UUID.randomUUID().toString()方法生成昆庇。

第三個為nx,這個參數(shù)我們填的是NX闸溃,意思是SET IF NOT EXIST整吆,即當key不存在時,我們進行set操作辉川;若key已經(jīng)存在表蝙,則不做任何操作;

第四個為expx乓旗,這個參數(shù)我們傳的是PX府蛇,意思是我們要給這個key加一個過期的設置,具體時間由第五個參數(shù)決定屿愚。

第五個為time汇跨,與第四個參數(shù)相呼應,代表key的過期時間妆距。

總的來說穷遂,執(zhí)行上面的set()方法就只會導致兩種結果:1. 當前沒有鎖(key不存在),那么就進行加鎖操作娱据,并對鎖設置個有效期蚪黑,同時value表示加鎖的客戶端。2. 已有鎖存在中剩,不做任何操作祠锣。

3. 假如Redis里面有1億個key,其中有10w個key是以某個固定的已知的前綴開頭的咽安,如果將它們全部找出來?

使用keys指令可以掃出指定模式的key列表:keys pre*

4. 如果這個redis正在給線上的業(yè)務提供服務蓬推,那使用keys指令會有什么問題妆棒?

這個時候你要回答redis關鍵的一個特性:redis的單線程的。keys指令會導致線程阻塞一段時間沸伏,線上服務會停頓糕珊,直到指令執(zhí)行完畢,服務才能恢復毅糟。這個時候可以使用scan指令红选,scan指令可以無阻塞的提取出指定模式的key列表,但是會有一定的重復概率姆另,在客戶端做一次去重就可以了喇肋,但是整體所花費的時間會比直接用keys指令長坟乾。

5. 使用過Redis做異步隊列么,你是怎么用的蝶防?

一般使用list結構作為隊列甚侣,rpush生產(chǎn)消息,lpop消費消息间学。當lpop沒有消息的時候殷费,要適當sleep一會再重試。

如果對方追問可不可以不用sleep呢低葫?list還有個指令叫blpop详羡,在沒有消息的時候,它會阻塞住直到消息到來嘿悬。

如果對方追問能不能生產(chǎn)一次消費多次呢实柠?使用pub/sub主題訂閱者模式,可以實現(xiàn)1:N的消息隊列鹊漠。

如果對方追問pub/sub有什么缺點主到?在消費者下線的情況下,生產(chǎn)的消息會丟失躯概,得使用專業(yè)的消息隊列如rabbitmq等登钥。redis中pub/sub缺陷

6. 如果對方追問redis如何實現(xiàn)延時隊列?

我估計現(xiàn)在你很想把面試官一棒打死如果你手上有一根棒球棍的話娶靡,怎么問的這么詳細牧牢。但是你很克制,然后神態(tài)自若的回答道:使用有序集合姿锭,拿時間戳作為score塔鳍,消息內容作為key調用zadd來生產(chǎn)消息,消費者用zrangebyscore指令獲取N秒之前的數(shù)據(jù)輪詢進行處理呻此。

7. 如果有大量的key需要設置同一時間過期轮纫,一般需要注意什么

如果大量的key過期時間設置的過于集中,到過期的那個時間點焚鲜,redis可能會出現(xiàn)短暫的卡頓現(xiàn)象掌唾。一般需要在時間上加一個隨機值,使得過期時間分散一些忿磅。

8. Redis如何做持久化的糯彬?

8.1. RDB做鏡像全量持久化,AOF做增量持久化葱她。

RDB持久化也分兩種:SAVE和BGSAVE撩扒。

SAVE是阻塞式的RDB持久化,當執(zhí)行這個命令時redis的主進程把內存里的數(shù)據(jù)庫狀態(tài)寫入到RDB文件中吨些,直到該文件創(chuàng)建完畢的這段時間內redis將不能處理任何命令請求搓谆;

BGSAVE屬于非阻塞式的持久化炒辉,它會創(chuàng)建一個子進程專門去把內存中的數(shù)據(jù)庫狀態(tài)寫入RDB文件里,同時主進程還可以處理來自客戶端的命令請求挽拔。但子進程基本是復制的父進程辆脸,這等于兩個相同大小的redis進程在系統(tǒng)上運行,會造成內存使用率的大幅增加螃诅。

8.2. AOF的持久化是通過命令追加啡氢、文件寫入和文件同步三個步驟實現(xiàn)的。

當reids開啟AOF后(redis備份方式默認是RDB)术裸,

服務端每執(zhí)行一次寫操作(如set倘是、sadd、rpush)就會把該條命令追加到一個單獨的AOF緩沖區(qū)的末尾袭艺,這就是命令追加搀崭;

然后把AOF緩沖區(qū)的內容寫入AOF文件里』啵看上去第二步就已經(jīng)完成AOF持久化了那第三步是干什么的呢瘤睹?這就需要從系統(tǒng)的文件寫入機制說起:一般我們現(xiàn)在所使用的操作系統(tǒng),為了提高文件的寫入效率答倡,都會有一個寫入策略轰传,即當你往硬盤寫入數(shù)據(jù)時,操作系統(tǒng)不是實時的將數(shù)據(jù)寫入硬盤瘪撇,而是先把數(shù)據(jù)暫時的保存在一個內存緩沖區(qū)里获茬,等到這個內存緩沖區(qū)的空間被填滿或者是超過了設定的時限后才會真正的把緩沖區(qū)內的數(shù)據(jù)寫入硬盤中。也就是說當redis進行到第二步文件寫入的時候倔既,從用戶的角度看是已經(jīng)把AOF緩沖區(qū)里的數(shù)據(jù)寫入到AOF文件了恕曲,但對系統(tǒng)而言只不過是把AOF緩沖區(qū)的內容放到了另一個內存緩沖區(qū)里而已,之后redis還需要進行文件同步把該內存緩沖區(qū)里的數(shù)據(jù)真正寫入硬盤上才算是完成了一次持久化渤涌。而何時進行文件同步則是根據(jù)配置的appendfsync來進行:appendfsync有三個選項:always佩谣、everysec和no:

對方追問那如果突然機器掉電會怎樣?取決于aof日志sync屬性的配置实蓬,如果不要求性能稿存,在每條寫指令時都sync一下磁盤,就不會丟失數(shù)據(jù)瞳秽。但是在高性能的要求下每次都sync是不現(xiàn)實的,一般都使用定時sync率翅,比如1s1次练俐,這個時候最多就會丟失1s的數(shù)據(jù)。

對方追問bgsave的原理是什么冕臭?你給出兩個詞匯就可以了腺晾,fork和cow燕锥。fork是指redis通過創(chuàng)建子進程來進行bgsave操作,cow指的是copy on write悯蝉,子進程創(chuàng)建后归形,父子進程共享數(shù)據(jù)段,父進程繼續(xù)提供讀寫服務鼻由,寫臟的頁面數(shù)據(jù)會逐漸和子進程分離開來暇榴。

Pipeline有什么好處,為什么要用pipeline蕉世?

可以將多次IO往返的時間縮減為一次蔼紧,前提是pipeline執(zhí)行的指令之間沒有因果相關性。使用redis-benchmark進行壓測的時候可以發(fā)現(xiàn)影響redis的QPS峰值的一個重要因素是pipeline批次指令的數(shù)目狠轻。

Redis的同步機制了解么奸例?

Redis可以使用主從同步,從從同步向楼。第一次同步時查吊,主節(jié)點做一次bgsave,并同時將后續(xù)修改操作記錄到內存buffer湖蜕,待完成后將rdb文件全量同步到復制節(jié)點逻卖,復制節(jié)點接受完成后將rdb鏡像加載到內存。加載完成后重荠,再通知主節(jié)點將期間修改的操作記錄同步到復制節(jié)點進行重放就完成了同步過程箭阶。

是否使用過Redis集群,集群的原理是什么戈鲁?

Redis Sentinal著眼于高可用仇参,在master宕機時會自動將slave提升為master,繼續(xù)提供服務婆殿。

Redis Cluster著眼于擴展性诈乒,在單個redis內存不足時,使用Cluster進行分片存儲婆芦。

3.使用redis有哪些好處怕磨?

(1) 速度快,因為數(shù)據(jù)存在內存中消约,類似于HashMap肠鲫,HashMap的優(yōu)勢就是查找和操作的時間復雜度都是O(1)

(2) 支持豐富數(shù)據(jù)類型,支持string或粮,list导饲,set,sorted set,hash

(3) 支持事務渣锦,操作都是原子性硝岗,所謂的原子性就是對數(shù)據(jù)的更改要么全部執(zhí)行,要么全部不執(zhí)行

(4) 豐富的特性:可用于緩存袋毙,消息型檀,按key設置過期時間,過期后將會自動刪除

4.redis相比memcached有哪些優(yōu)勢听盖?

(1) memcached所有的值均是簡單的字符串胀溺,redis作為其替代者,支持更為豐富的數(shù)據(jù)類型

(2) redis的速度比memcached快很多

(3) redis可以持久化其數(shù)據(jù)

5.Memcache與Redis的區(qū)別都有哪些媳溺?

1)月幌、存儲方式 Memecache把數(shù)據(jù)全部存在內存之中,斷電后會掛掉悬蔽,數(shù)據(jù)不能超過內存大小扯躺。 Redis有部份存在硬盤上,這樣能保證數(shù)據(jù)的持久性蝎困。

2)录语、數(shù)據(jù)支持類型 Memcache對數(shù)據(jù)類型支持相對簡單。 Redis有復雜的數(shù)據(jù)類型禾乘。

3)澎埠、使用底層模型不同 它們之間底層實現(xiàn)方式 以及與客戶端之間通信的應用協(xié)議不一樣。 Redis直接自己構建了VM 機制 始藕,因為一般的系統(tǒng)調用系統(tǒng)函數(shù)的話蒲稳,會浪費一定的時間去移動和請求。


6.redis常見性能問題和解決方案:

1).Master寫內存快照伍派,save命令調度rdbSave函數(shù)江耀,會阻塞主線程的工作,當快照比較大時對性能影響是非常大的诉植,會間斷性暫停服務祥国,所以Master最好不要寫內存快照。

2).Master AOF持久化晾腔,如果不重寫AOF文件舌稀,這個持久化方式對性能的影響是最小的,但是AOF文件會不斷增大灼擂,AOF文件過大會影響Master重啟的恢復速度壁查。Master最好不要做任何持久化工作,包括內存快照和AOF日志文件剔应,特別是不要啟用內存快照做持久化,如果數(shù)據(jù)比較關鍵睡腿,某個Slave開啟AOF備份數(shù)據(jù)康谆,策略為每秒同步一次。

3).Master調用BGREWRITEAOF重寫AOF文件嫉到,AOF在重寫的時候會占大量的CPU和內存資源,導致服務load過高月洛,出現(xiàn)短暫服務暫秃味瘢現(xiàn)象。

4). Redis主從復制的性能問題嚼黔,為了主從復制的速度和連接的穩(wěn)定性细层,Slave和Master最好在同一個局域網(wǎng)內

mySQL里有2000w數(shù)據(jù),redis中只存20w的數(shù)據(jù)唬涧,如何保證redis中的數(shù)據(jù)都是熱點數(shù)據(jù)

相關知識:redis 內存數(shù)據(jù)集大小上升到一定大小的時候疫赎,就會施行數(shù)據(jù)淘汰策略(回收策略)。

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

volatile-lru:從已設置過期時間的數(shù)據(jù)集(server.db[i].expires)中挑選最近最少使用的數(shù)據(jù)淘汰

volatile-ttl:從已設置過期時間的數(shù)據(jù)集(server.db[i].expires)中挑選將要過期的數(shù)據(jù)淘汰

volatile-random:從已設置過期時間的數(shù)據(jù)集(server.db[i].expires)中任意選擇數(shù)據(jù)淘汰

allkeys-lru:從數(shù)據(jù)集(server.db[i].dict)中挑選最近最少使用的數(shù)據(jù)淘汰

allkeys-random:從數(shù)據(jù)集(server.db[i].dict)中任意選擇數(shù)據(jù)淘汰

no-enviction(驅逐):禁止驅逐數(shù)據(jù)

8.請用Redis和任意語言實現(xiàn)一段惡意登錄保護的代碼碎节,限制1小時內每用戶Id最多只能登錄5次捧搞。具體登錄函數(shù)或功能用空函數(shù)即可,不用詳細寫出狮荔。

 用列表實現(xiàn):列表中每個元素代表登陸時間,只要最后的第5次登陸時間和現(xiàn)在時間差不超過1小時就禁止登陸.用java(jedis)寫的代碼如下:

 實現(xiàn)方式有很多胎撇,比如說使用redis的使用redis的列表實現(xiàn)一個隊列,


9.為什么redis需要把所有數(shù)據(jù)放到內存中?

Redis為了達到最快的讀寫速度將數(shù)據(jù)都讀到內存中殖氏,并通過異步的方式將數(shù)據(jù)寫入磁盤晚树。所以redis具有快速和數(shù)據(jù)持久化的特征。如果不將數(shù)據(jù)放在內存中雅采,磁盤I/O速度為嚴重影響redis的性能爵憎。在內存越來越便宜的今天,redis將會越來越受歡迎婚瓜。

 如果設置了最大使用的內存宝鼓,則數(shù)據(jù)已有記錄數(shù)達到內存限值后不能繼續(xù)插入新值。

10.Redis是單進程單線程的

redis利用隊列技術將并發(fā)訪問變?yōu)榇性L問闰渔,消除了傳統(tǒng)數(shù)據(jù)庫串行控制的開銷席函。

11.redis的并發(fā)競爭問題如何解決?

Redis為單進程單線程模式,采用隊列模式將并發(fā)訪問變?yōu)榇性L問冈涧。Redis本身沒有鎖的概念茂附,Redis對于多個客戶端連接并不存在競爭,但是在Jedis客戶端對Redis進行并發(fā)訪問時會發(fā)生連接超時督弓、數(shù)據(jù)轉換錯誤营曼、阻塞、客戶端關閉連接等問題愚隧,這些問題均是由于客戶端連接混亂造成蒂阱。對此有2種解決方法:

1).客戶端角度,為保證每個客戶端間正常有序與Redis進行通信,對連接進行池化录煤,同時對客戶端讀寫Redis操作采用內部鎖synchronized鳄厌。

2).服務器角度,利用setnx實現(xiàn)鎖妈踊。

注:對于第一種了嚎,需要應用程序自己處理資源的同步,可以使用的方法比較通俗廊营,可以使用synchronized也可以使用lock歪泳;第二種需要用到Redis的setnx命令,但是需要注意一些問題露筒。

12.redis事物的了解CAS(check-and-set 操作實現(xiàn)樂觀鎖 )?

和眾多其它數(shù)據(jù)庫一樣呐伞,Redis作為NoSQL數(shù)據(jù)庫也同樣提供了事務機制。在Redis中慎式,MULTI/EXEC/DISCARD/WATCH這四個命令是我們實現(xiàn)事務的基石伶氢。相信對有關系型數(shù)據(jù)庫開發(fā)經(jīng)驗的開發(fā)者而言這一概念并不陌生,即便如此瞬捕,我們還是會簡要的列出Redis中事務的實現(xiàn)特征:

 1). 在事務中的所有命令都將會被串行化的順序執(zhí)行鞍历,事務執(zhí)行期間,Redis不會再為其它客戶端的請求提供任何服務肪虎,從而保證了事物中的所有命令被原子的執(zhí)行劣砍。

 2). 和關系型數(shù)據(jù)庫中的事務相比,在Redis事務中如果有某一條命令執(zhí)行失敗刑枝,其后的命令仍然會被繼續(xù)執(zhí)行。

 3). 我們可以通過MULTI命令開啟一個事務迅腔,有關系型數(shù)據(jù)庫開發(fā)經(jīng)驗的人可以將其理解為"BEGIN TRANSACTION"語句。在該語句之后執(zhí)行的命令都將被視為事務之內的操作,最后我們可以通過執(zhí)行EXEC/DISCARD命令來提交/回滾該事務內的所有操作婿牍。這兩個Redis命令可被視為等同于關系型數(shù)據(jù)庫中的COMMIT/ROLLBACK語句。

 4). 在事務開啟之前粉楚,如果客戶端與服務器之間出現(xiàn)通訊故障并導致網(wǎng)絡斷開,其后所有待執(zhí)行的語句都將不會被服務器執(zhí)行壹瘟。然而如果網(wǎng)絡中斷事件是發(fā)生在客戶端執(zhí)行EXEC命令之后,那么該事務中的所有命令都會被服務器執(zhí)行踱讨。

 5). 當使用Append-Only模式時,Redis會通過調用系統(tǒng)函數(shù)write將該事務內的所有寫操作在本次調用中全部寫入磁盤饼问。然而如果在寫入的過程中出現(xiàn)系統(tǒng)崩潰影兽,如電源故障導致的宕機,那么此時也許只有部分數(shù)據(jù)被寫入到磁盤莱革,而另外一部分數(shù)據(jù)卻已經(jīng)丟失峻堰。

Redis服務器會在重新啟動時執(zhí)行一系列必要的一致性檢測,一旦發(fā)現(xiàn)類似問題盅视,就會立即退出并給出相應的錯誤提示捐名。此時,我們就要充分利用Redis工具包中提供的redis-check-aof工具闹击,該工具可以幫助我們定位到數(shù)據(jù)不一致的錯誤镶蹋,并將已經(jīng)寫入的部分數(shù)據(jù)進行回滾。修復之后我們就可以再次重新啟動Redis服務器了赏半。

13.WATCH命令和基于CAS的樂觀鎖:

在Redis的事務中梅忌,WATCH命令可用于提供CAS(check-and-set)功能。假設我們通過WATCH命令在事務執(zhí)行之前監(jiān)控了多個Keys除破,倘若在WATCH之后有任何Key的值發(fā)生了變化牧氮,EXEC命令執(zhí)行的事務都將被放棄,同時返回Null multi-bulk應答以通知調用者事務執(zhí)行失敗瑰枫。例如踱葛,我們再次假設Redis中并未提供incr命令來完成鍵值的原子性遞增,如果要實現(xiàn)該功能光坝,我們只能自行編寫相應的代碼尸诽。其偽碼如下:

  val = GET mykey

  val = val + 1

  SET mykey $val

  以上代碼只有在單連接的情況下才可以保證執(zhí)行結果是正確的,因為如果在同一時刻有多個客戶端在同時執(zhí)行該段代碼盯另,那么就會出現(xiàn)多線程程序中經(jīng)常出現(xiàn)的一種錯誤場景–競態(tài)爭用(race condition)性含。比如,客戶端A和B都在同一時刻讀取了mykey的原有值鸳惯,假設該值為10商蕴,此后兩個客戶端又均將該值加一后set回Redis服務器叠萍,這樣就會導致mykey的結果為11,而不是我們認為的12绪商。為了解決類似的問題苛谷,我們需要借助WATCH命令的幫助,見如下代碼:

  WATCH mykey

  val = GET mykey

  val = val + 1

  MULTI

  SET mykey $val

  EXEC

  和此前代碼不同的是格郁,新代碼在獲取mykey的值之前先通過WATCH命令監(jiān)控了該鍵腹殿,此后又將set命令包圍在事務中,這樣就可以有效的保證每個連接在執(zhí)行EXEC之前例书,如果當前連接獲取的mykey的值被其它連接的客戶端修改锣尉,那么當前連接的EXEC命令將執(zhí)行失敗。這樣調用者在判斷返回值后就可以獲悉val是否被重新設置成功决采。

14.redis持久化的幾種方式

1).快照(snapshots)

  缺省情況情況下悟耘,Redis把數(shù)據(jù)快照存放在磁盤上的二進制文件中,文件名為dump.rdb织狐。你可以配置Redis的持久化策略,例如數(shù)據(jù)集中每N秒鐘有超過M次更新筏勒,就將數(shù)據(jù)寫入磁盤移迫;或者你可以手工調用命令SAVE或BGSAVE。

工作原理

 」苄小. Redis forks.

 〕瘛. 子進程開始將數(shù)據(jù)寫到臨時RDB文件中。

 【枨辍. 當子進程完成寫RDB文件荡陷,用新文件替換老文件。

 ⊙镐獭. 這種方式可以使Redis使用copy-on-write技術废赞。

2).AOF

  快照模式并不健壯,當系統(tǒng)停止叮姑,或者無意中Redis被kill掉唉地,最后寫入Redis的數(shù)據(jù)就會丟失。這對某些應用也許不是大問題传透,但對于要求高可靠性的應用來說耘沼,Redis就不是一個合適的選擇。Append-only文件模式是另一種選擇朱盐。你可以在配置文件中打開AOF模式群嗤。

3).虛擬內存方式

  當你的key很小而value很大時,使用VM的效果會比較好.因為這樣節(jié)約的內存比較大.

  當你的key不小時,可以考慮使用一些非常方法將很大的key變成很大的value,比如你可以考慮將key,value組合成一個新的value.

  vm-max-threads這個參數(shù),可以設置訪問swap文件的線程數(shù),設置最好不要超過機器的核數(shù),如果設置為0,那么所有對swap文件的操作都是串行的.可能會造成比較長時間的延遲,但是對數(shù)據(jù)完整性有很好的保證.

15.redis的緩存失效策略和主鍵失效機制

作為緩存系統(tǒng)都要定期清理無效數(shù)據(jù),就需要一個主鍵失效和淘汰策略.

  在Redis當中兵琳,有生存期的key被稱為expire狂秘。在創(chuàng)建緩存時骇径,要為給定的key設置生存期,當key過期的時候(生存期為0)赃绊,它可能會被刪除既峡,并不是立刻刪除,因為刪除過期時間有三種不同的策略碧查,參見博客redis過期鍵刪除策略运敢。

  1).影響生存時間的一些操作

  生存時間可以通過使用 DEL 命令來刪除整個 key 來移除,或者被 SET 命令覆蓋原來的數(shù)據(jù)忠售,也就是說传惠,修改key對應的value和使用另外相同的key和value來覆蓋以后,當前數(shù)據(jù)的生存時間不同稻扬。

  比如說卦方,對一個 key 執(zhí)行INCR命令,對一個列表進行LPUSH命令泰佳,或者對一個哈希表執(zhí)行HSET命令盼砍,這類操作都不會修改 key 本身的生存時間。另一方面逝她,如果使用RENAME對一個 key 進行改名浇坐,那么改名后的 key的生存時間和改名前一樣。

  RENAME命令的另一種可能是黔宛,嘗試將一個帶生存時間的 key 改名成另一個帶生存時間的 another_key 近刘,這時舊的 another_key (以及它的生存時間)會被刪除,然后舊的 key 會改名為 another_key 臀晃,因此觉渴,新的 another_key 的生存時間也和原本的 key 一樣。使用PERSIST命令可以在不刪除 key 的情況下徽惋,移除 key 的生存時間案淋,讓 key 重新成為一個persistent key 。

  2).如何更新生存時間

  可以對一個已經(jīng)帶有生存時間的 key 執(zhí)行EXPIRE命令险绘,新指定的生存時間會取代舊的生存時間哎迄。過期時間的精度已經(jīng)被控制在1ms之內,主鍵失效的時間復雜度是O(1)隆圆,

  EXPIRE和TTL命令搭配使用漱挚,TTL可以查看key的當前生存時間。設置成功返回 1渺氧;當 key 不存在或者不能為 key 設置生存時間時旨涝,返回 0 。

  3).最大緩存配置

  在 redis 中,允許用戶設置最大使用內存大小server.maxmemory白华,默認為0慨默,沒有指定最大緩存,如果有新的數(shù)據(jù)添加弧腥,超過最大內存厦取,則會使redis崩潰,所以一定要設置管搪。redis 內存數(shù)據(jù)集大小上升到一定大小的時候虾攻,就會實行數(shù)據(jù)淘汰策略。

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

 「场. volatile-lru:從已設置過期時間的數(shù)據(jù)集(server.db[i].expires)中挑選最近最少使用的數(shù)據(jù)淘汰

 ■俊. volatile-ttl:從已設置過期時間的數(shù)據(jù)集(server.db[i].expires)中挑選將要過期的數(shù)據(jù)淘汰

  . volatile-random:從已設置過期時間的數(shù)據(jù)集(server.db[i].expires)中任意選擇數(shù)據(jù)淘汰

 ≡栉. allkeys-lru:從數(shù)據(jù)集(server.db[i].dict)中挑選最近最少使用的數(shù)據(jù)淘汰

 ∑怠. allkeys-random:從數(shù)據(jù)集(server.db[i].dict)中任意選擇數(shù)據(jù)淘汰

  . no-enviction(驅逐):禁止驅逐數(shù)據(jù)

  注意這里的6種機制媒至,volatile和allkeys規(guī)定了是對已設置過期時間的數(shù)據(jù)集淘汰數(shù)據(jù)還是從全部數(shù)據(jù)集淘汰數(shù)據(jù)顶别,后面的lru、ttl以及random是三種不同的淘汰策略拒啰,再加上一種no-enviction永不回收的策略驯绎。

  使用策略規(guī)則:

  1、如果數(shù)據(jù)呈現(xiàn)冪律分布图呢,也就是一部分數(shù)據(jù)訪問頻率高,一部分數(shù)據(jù)訪問頻率低骗随,則使用allkeys-lru

  2蛤织、如果數(shù)據(jù)呈現(xiàn)平等分布,也就是所有的數(shù)據(jù)訪問頻率都相同鸿染,則使用allkeys-random

  三種數(shù)據(jù)淘汰策略:

  ttl和random比較容易理解指蚜,實現(xiàn)也會比較簡單。主要是Lru最近最少使用淘汰策略涨椒,設計上會對key 按失效時間排序摊鸡,然后取最先失效的key進行淘汰

16.redis 最適合的場景

Redis最適合所有數(shù)據(jù)in-momory的場景,雖然Redis也提供持久化功能蚕冬,但實際更多的是一個disk-backed的功能免猾,跟傳統(tǒng)意義上的持久化有比較大的差別,那么可能大家就會有疑問囤热,似乎Redis更像一個加強版的Memcached猎提,那么何時使用Memcached,何時使用Redis呢?

如果簡單地比較Redis與Memcached的區(qū)別旁蔼,大多數(shù)都會得到以下觀點:

  1 锨苏、Redis不僅僅支持簡單的k/v類型的數(shù)據(jù)疙教,同時還提供list,set伞租,zset贞谓,hash等數(shù)據(jù)結構的存儲。

  2 葵诈、Redis支持數(shù)據(jù)的備份裸弦,即master-slave模式的數(shù)據(jù)備份。

  3 驯击、Redis支持數(shù)據(jù)的持久化烁兰,可以將內存中的數(shù)據(jù)保持在磁盤中,重啟的時候可以再次加載進行使用徊都。

(1).會話緩存(Session Cache)

最常用的一種使用Redis的情景是會話緩存(session cache)沪斟。用Redis緩存會話比其他存儲(如Memcached)的優(yōu)勢在于:Redis提供持久化。

(2).全頁緩存(FPC)

除基本的會話token之外暇矫,Redis還提供很簡便的FPC平臺主之。回到一致性問題,即使重啟了Redis實例,因為有磁盤的持久化冤荆,用戶也不會看到頁面加載速度的下降芙代,這是一個極大改進,類似PHP本地FPC望抽。

  再次以Magento為例,Magento提供一個插件來使用Redis作為全頁緩存后端。

  此外夯接,對WordPress的用戶來說,Pantheon有一個非常好的插件 wp-redis纷妆,這個插件能幫助你以最快速度加載你曾瀏覽過的頁面盔几。

(3).隊列

Reids在內存存儲引擎領域的一大優(yōu)點是提供 list 和 set 操作,這使得Redis能作為一個很好的消息隊列平臺來使用掩幢。Redis作為隊列使用的操作逊拍,就類似于本地程序語言(如Python)對 list 的 push/pop 操作。

  如果你快速的在Google中搜索“Redis queues”际邻,你馬上就能找到大量的開源項目芯丧,這些項目的目的就是利用Redis創(chuàng)建非常好的后端工具,以滿足各種隊列需求世曾。例如注整,Celery有一個后臺就是使用Redis作為broker,你可以從這里去查看。

(4).排行榜/計數(shù)器

Redis在內存中對數(shù)字進行遞增或遞減的操作實現(xiàn)的非常好肿轨。集合(Set)和有序集合(Sorted Set)也使得我們在執(zhí)行這些操作的時候變的非常簡單寿冕,Redis只是正好提供了這兩種數(shù)據(jù)結構。所以椒袍,我們要從排序集合中獲取到排名最靠前的10個用戶–我們稱之為“user_scores”驼唱,我們只需要像下面一樣執(zhí)行即可:當然,這是假定你是根據(jù)你用戶的分數(shù)做遞增的排序驹暑。如果你想返回用戶及用戶的分數(shù)玫恳,你需要這樣執(zhí)行:

ZRANGE user_scores 0 10 WITHSCORES

Agora Games就是一個很好的例子,用Ruby實現(xiàn)的优俘,它的排行榜就是使用Redis來存儲數(shù)據(jù)的京办,你可以在這里看到。

(5).發(fā)布/訂閱

Redis的發(fā)布/訂閱功能帆焕。發(fā)布/訂閱的使用場景確實非常多惭婿。在社交網(wǎng)絡連接中使用,還可作為基于發(fā)布/訂閱的腳本觸發(fā)器叶雹,甚至用Redis的發(fā)布/訂閱功能來建立聊天系統(tǒng)财饥!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市折晦,隨后出現(xiàn)的幾起案子钥星,更是在濱河造成了極大的恐慌,老刑警劉巖满着,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件谦炒,死亡現(xiàn)場離奇詭異,居然都是意外死亡风喇,警方通過查閱死者的電腦和手機宁改,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來响驴,“玉大人透且,你說我怎么就攤上這事撕蔼』砝穑” “怎么了?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵鲸沮,是天一觀的道長琳骡。 經(jīng)常有香客問我,道長讼溺,這世上最難降的妖魔是什么楣号? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上炫狱,老公的妹妹穿的比我還像新娘藻懒。我一直安慰自己,他們只是感情好视译,可當我...
    茶點故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布嬉荆。 她就那樣靜靜地躺著,像睡著了一般酷含。 火紅的嫁衣襯著肌膚如雪鄙早。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天椅亚,我揣著相機與錄音限番,去河邊找鬼。 笑死呀舔,一個胖子當著我的面吹牛弥虐,可吹牛的內容都是我干的。 我是一名探鬼主播别威,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼躯舔,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了省古?” 一聲冷哼從身側響起粥庄,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎豺妓,沒想到半個月后惜互,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡琳拭,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年训堆,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片白嘁。...
    茶點故事閱讀 39,841評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡坑鱼,死狀恐怖,靈堂內的尸體忽然破棺而出絮缅,到底是詐尸還是另有隱情鲁沥,我是刑警寧澤,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布耕魄,位于F島的核電站画恰,受9級特大地震影響,放射性物質發(fā)生泄漏吸奴。R本人自食惡果不足惜允扇,卻給世界環(huán)境...
    茶點故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一缠局、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧考润,春花似錦狭园、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至俊戳,卻和暖如春揖赴,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背抑胎。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工燥滑, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人阿逃。 一個月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓铭拧,卻偏偏與公主長得像,于是被迫代替她去往敵國和親恃锉。 傳聞我的和親對象是個殘疾皇子搀菩,可洞房花燭夜當晚...
    茶點故事閱讀 44,781評論 2 354

推薦閱讀更多精彩內容

  • 企業(yè)級redis集群架構的特點 海量數(shù)據(jù) 高并發(fā) 高可用 要達到高可用,持久化是不可減少的破托,持久化主要是做災難恢復...
    lucode閱讀 2,206評論 0 7
  • 1.1 資料 肪跋,最好的入門小冊子,可以先于一切文檔之前看土砂,免費州既。 作者Antirez的博客,Antirez維護的R...
    JefferyLcm閱讀 17,056評論 1 51
  • 1.項目中緩存是如何使用的萝映?為什么要用緩存吴叶?緩存使用不當會造成什么后果? 面試題剖析 為什么要用緩存序臂? 用緩存蚌卤,主...
    jsbintask閱讀 9,171評論 0 217
  • Redis是啥 Redis是一個開源的key-value存儲系統(tǒng),由于擁有豐富的數(shù)據(jù)結構奥秆,又被其作者戲稱為數(shù)據(jù)結構...
    一凡呀閱讀 1,173評論 0 5
  • 熟透的蘋果掉下來 誰的光陰被輕輕砸了一下 一點疼被香甜吵醒吭练,誰彎腰撿起 將要腐爛的歲月 隔年的沙發(fā)走過來 接過風雨...
    古不為閱讀 1,504評論 39 51