久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

精選 21道 Redis 最常問面試題,!收藏一波 !

 補丁牛仔褲 2021-04-15

來源:網(wǎng)絡(luò)

  • 1、什么是redis?
  • 2,、Reids的特點
  • 3,、使用redis有哪些好處?
  • 4,、redis相比memcached有哪些優(yōu)勢,?
  • 5、Memcache與Redis的區(qū)別都有哪些,?
  • 6,、redis適用于的場景?
  • 7、redis的緩存失效策略和主鍵失效機制
  • 8,、為什么redis需要把所有數(shù)據(jù)放到內(nèi)存中?
  • 9,、Redis是單進程單線程的
  • 10、redis的并發(fā)競爭問題如何解決?
  • 11、redis常見性能問題和解決方案
  • 12,、redis事物的了解CAS(check-and-set 操作實現(xiàn)樂觀鎖 )?
  • 13,、WATCH命令和基于CAS的樂觀鎖?
  • 14、使用過Redis分布式鎖么,,它是什么回事,?
  • 15、假如Redis里面有1億個key,,其中有10w個key是以某個固定的已知的前綴開頭的,,如果將它們?nèi)空页鰜恚?/strong>
  • 16、使用過Redis做異步隊列么,,你是怎么用的,?
  • 17、如果有大量的key需要設(shè)置同一時間過期,,一般需要注意什么,?
  • 18、Redis如何做持久化的,?
  • 19,、Pipeline有什么好處,為什么要用pipeline,?
  • 20,、Redis的同步機制了解么?
  • 21,、是否使用過Redis集群,,集群的原理是什么?

1,、什么是redis?

redis是一個高性能的key-value數(shù)據(jù)庫,,它是完全開源免費的,而且redis是一個NOSQL類型數(shù)據(jù)庫,,是為了解決高并發(fā),、高擴展,大數(shù)據(jù)存儲等一系列的問題而產(chǎn)生的數(shù)據(jù)庫解決方案,,是一個非關(guān)系型的數(shù)據(jù)庫

2,、Reids的特點

Redis本質(zhì)上是一個Key-Value類型的內(nèi)存數(shù)據(jù)庫,很像memcached,,整個數(shù)據(jù)庫統(tǒng)統(tǒng)加載在內(nèi)存當中進行操作,,定期通過異步操作把數(shù)據(jù)庫數(shù)據(jù)flush到硬盤上進行保存。因為是純內(nèi)存操作,,Redis的性能非常出色,,每秒可以處理超過 10萬次讀寫操作,,是已知性能最快的Key-Value DB。

Redis的出色之處不僅僅是性能,,Redis最大的魅力是支持保存多種數(shù)據(jù)結(jié)構(gòu),,此外單個value的最大限制是1GB,不像 memcached只能保存1MB的數(shù)據(jù),,因此Redis可以用來實現(xiàn)很多有用的功能,,比方說用他的List來做FIFO雙向鏈表,實現(xiàn)一個輕量級的高性 能消息隊列服務(wù),,用他的Set可以做高性能的tag系統(tǒng)等等,。另外Redis也可以對存入的Key-Value設(shè)置expire時間,因此也可以被當作一 個功能加強版的memcached來用,。

Redis的主要缺點是數(shù)據(jù)庫容量受到物理內(nèi)存的限制,,不能用作海量數(shù)據(jù)的高性能讀寫,因此Redis適合的場景主要局限在較小數(shù)據(jù)量的高性能操作和運算上,。

3,、使用redis有哪些好處?

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

3.2 支持豐富數(shù)據(jù)類型,,支持string,,list,set,,sorted set,,hash

String

常用命令 :set/get/decr/incr/mget等;

應(yīng)用場景 :String是最常用的一種數(shù)據(jù)類型,,普通的key/value存儲都可以歸為此類,;

實現(xiàn)方式:String在redis內(nèi)部存儲默認就是一個字符串,被redisObject所引用,,當遇到incr,、decr等操作時會轉(zhuǎn)成數(shù)值型進行計算,此時redisObject的encoding字段為int,。

Hash

常用命令 :hget/hset/hgetall等

應(yīng)用場景 :我們要存儲一個用戶信息對象數(shù)據(jù),其中包括用戶ID,、用戶姓名,、年齡和生日,通過用戶ID我們希望獲取該用戶的姓名或者年齡或者生日,;

實現(xiàn)方式:Redis的Hash實際是內(nèi)部存儲的Value為一個HashMap,,并提供了直接存取這個Map成員的接口,。如圖所示,Key是用戶ID, value是一個Map,。這個Map的key是成員的屬性名,,value是屬性值。這樣對數(shù)據(jù)的修改和存取都可以直接通過其內(nèi)部Map的Key(Redis里稱內(nèi)部Map的key為field),,也就是通過 key(用戶ID) + field(屬性標簽) 就可以操作對應(yīng)屬性數(shù)據(jù),。當前HashMap的實現(xiàn)有兩種方式:當HashMap的成員比較少時Redis為了節(jié)省內(nèi)存會采用類似一維數(shù)組的方式來緊湊存儲,而不會采用真正的HashMap結(jié)構(gòu),,這時對應(yīng)的value的redisObject的encoding為zipmap,,當成員數(shù)量增大時會自動轉(zhuǎn)成真正的HashMap,此時redisObject的encoding字段為int。

List

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

應(yīng)用場景 :Redis list的應(yīng)用場景 非常多,,也是Redis最重要的數(shù)據(jù)結(jié)構(gòu)之一,比如twitter的關(guān)注列表,,粉絲列表等都可以用Redis的list結(jié)構(gòu)來實現(xiàn),;

實現(xiàn)方式:Redis list的實現(xiàn)為一個雙向鏈表,即可以支持反向查找和遍歷,,更方便操作,,不過帶來了部分額外的內(nèi)存開銷,Redis內(nèi)部的很多實現(xiàn),,包括發(fā)送緩沖隊列等也都是用的這個數(shù)據(jù)結(jié)構(gòu),。

Set

常用命令 :sadd/spop/smembers/sunion等;

應(yīng)用場景 :Redis set對外提供的功能與list類似是一個列表的功能,,特殊之處在于set是可以自動排重的,,當你需要存儲一個列表數(shù)據(jù),又不希望出現(xiàn)重復(fù)數(shù)據(jù)時,,set是一個很好的選擇,,并且set提供了判斷某個成員是否在一個set集合內(nèi)的重要接口,這個也是list所不能提供的,;

實現(xiàn)方式:set 的內(nèi)部實現(xiàn)是一個 value永遠為null的HashMap,,實際就是通過計算hash的方式來快速排重的,這也是set能提供判斷一個成員是否在集合內(nèi)的原因,。

Sorted Set

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

應(yīng)用場景 :Redis sorted set的使用場景與set類似,區(qū)別是set不是自動有序的,,而sorted set可以通過用戶額外提供一個優(yōu)先級(score)的參數(shù)來為成員排序,,并且是插入有序的,即自動排序,。當你需要一個有序的并且不重復(fù)的集合列表,,那么可以選擇sorted set數(shù)據(jù)結(jié)構(gòu),,比如twitter 的public timeline可以以發(fā)表時間作為score來存儲,這樣獲取時就是自動按時間排好序的,。

實現(xiàn)方式:Redis sorted set的內(nèi)部使用HashMap和跳躍表(SkipList)來保證數(shù)據(jù)的存儲和有序,,HashMap里放的是成員到score的映射,而跳躍表里存放的是所有的成員,,排序依據(jù)是HashMap里存的score,使用跳躍表的結(jié)構(gòu)可以獲得比較高的查找效率,,并且在實現(xiàn)上比較簡單。

4,、redis相比memcached有哪些優(yōu)勢,?

4.1 memcached所有的值均是簡單的字符串,redis作為其替代者,,支持更為豐富的數(shù)據(jù)類型4.2 redis的速度比memcached快很多 (3) redis可以持久化其數(shù)據(jù)

5,、Memcache與Redis的區(qū)別都有哪些?

5.1 存儲方式 Memecache把數(shù)據(jù)全部存在內(nèi)存之中,,斷電后會掛掉,,數(shù)據(jù)不能超過內(nèi)存大小。Redis有部份存在硬盤上,,這樣能保證數(shù)據(jù)的持久性,。

5.2 數(shù)據(jù)支持類型 Memcache對數(shù)據(jù)類型支持相對簡單。Redis有復(fù)雜的數(shù)據(jù)類型,。

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

6、redis適用于的場景?

Redis最適合所有數(shù)據(jù)in-momory的場景,,如:

6.1 會話緩存(Session Cache)

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

6.2 全頁緩存(FPC)

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

6.3 隊列

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

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

6.4 排行榜/計數(shù)器

Redis在內(nèi)存中對數(shù)字進行遞增或遞減的操作實現(xiàn)的非常好。集合(Set)和有序集合(Sorted Set)也使得我們在執(zhí)行這些操作的時候變的非常簡單,,Redis只是正好提供了這兩種數(shù)據(jù)結(jié)構(gòu),。所以,我們要從排序集合中獲取到排名最靠前的10個用戶–我們稱之為“user_scores”,,我們只需要像下面一樣執(zhí)行即可:

當然,,這是假定你是根據(jù)你用戶的分數(shù)做遞增的排序。如果你想返回用戶及用戶的分數(shù),,你需要這樣執(zhí)行:

ZRANGE user_scores 0 10 WITHSCORES

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

6.5 發(fā)布/訂閱

最后(但肯定不是最不重要的)是Redis的發(fā)布/訂閱功能。發(fā)布/訂閱的使用場景確實非常多,。

7,、redis的緩存失效策略和主鍵失效機制

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

在Redis當中,,有生存期的key被稱為volatile,。在創(chuàng)建緩存時,要為給定的key設(shè)置生存期,,當key過期的時候(生存期為0),,它可能會被刪除。

1,、影響生存時間的一些操作

生存時間可以通過使用 DEL 命令來刪除整個 key 來移除,,或者被 SET 和 GETSET 命令覆蓋原來的數(shù)據(jù),也就是說,,修改key對應(yīng)的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之內(nèi),,主鍵失效的時間復(fù)雜度是O(1),

EXPIRE和TTL命令搭配使用,,TTL可以查看key的當前生存時間,。設(shè)置成功返回 1;當 key 不存在或者不能為 key 設(shè)置生存時間時,,返回 0 ,。

最大緩存配置 在 redis 中,允許用戶設(shè)置最大使用內(nèi)存大小 server.maxmemory 默認為0,,沒有指定最大緩存,,如果有新的數(shù)據(jù)添加,超過最大內(nèi)存,,則會使redis崩潰,,所以一定要設(shè)置。redis 內(nèi)存數(shù)據(jù)集大小上升到一定大小的時候,,就會實行數(shù)據(jù)淘汰策略,。redis 提供 6種數(shù)據(jù)淘汰策略:

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

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

volatile-random: 從已設(shè)置過期時間的數(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(驅(qū)逐): 禁止驅(qū)逐數(shù)據(jù)

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

使用策略規(guī)則:

1,、 如果數(shù)據(jù)呈現(xiàn)冪律分布,,也就是一部分數(shù)據(jù)訪問頻率高,一部分數(shù)據(jù)訪問頻率低,,則使用allkeys-lru2,、 如果數(shù)據(jù)呈現(xiàn)平等分布,也就是所有的數(shù)據(jù)訪問頻率都相同,,則使用allkeys-random

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

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

8,、為什么redis需要把所有數(shù)據(jù)放到內(nèi)存中?

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

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

9,、Redis是單進程單線程的

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

10,、redis的并發(fā)競爭問題如何解決?

Redis為單進程單線程模式,,采用隊列模式將并發(fā)訪問變?yōu)榇性L問。Redis本身沒有鎖的概念,,Redis對于多個客戶端連接并不存在競爭,,但是在Jedis客戶端對Redis進行并發(fā)訪問時會發(fā)生連接超時、數(shù)據(jù)轉(zhuǎn)換錯誤,、阻塞,、客戶端關(guān)閉連接等問題,這些問題均是

由于客戶端連接混亂造成,。對此有2種解決方法:

10.1 客戶端角度,,為保證每個客戶端間正常有序與Redis進行通信,對連接進行池化,,同時對客戶端讀寫Redis操作采用內(nèi)部鎖synchronized,。

10.2 服務(wù)器角度,利用setnx實現(xiàn)鎖。注:對于第一種,,需要應(yīng)用程序自己處理資源的同步,,可以使用的方法比較通俗,可以使用synchronized也可以使用lock,;第二種需要用到Redis的setnx命令,,但是需要注意一些問題,。

11、redis常見性能問題和解決方案

11.1 Master寫內(nèi)存快照,save命令調(diào)度rdbSave函數(shù),,會阻塞主線程的工作,,當快照比較大時對性能影響是非常大的,,會間斷性暫停服務(wù),,所以Master最好不要寫內(nèi)存快照。

11.2 Master AOF持久化,,如果不重寫AOF文件,,這個持久化方式對性能的影響是最小的,,但是AOF文件會不斷增大,,AOF文件過大會影響Master重啟的恢復(fù)速度,。Master最好不要做任何持久化工作,,包括內(nèi)存快照和AOF日志文件,特別是不要啟用內(nèi)存快照做持久

化,如果數(shù)據(jù)比較關(guān)鍵,,某個Slave開啟AOF備份數(shù)據(jù),策略為每秒同步一次,。

11.3 Master調(diào)用BGREWRITEAOF重寫AOF文件,,AOF在重寫的時候會占大量的CPU和內(nèi)存資源,導(dǎo)致服務(wù)load過高,,出現(xiàn)短暫服務(wù)暫?,F(xiàn)象。

11.4 Redis主從復(fù)制的性能問題,,為了主從復(fù)制的速度和連接的穩(wěn)定性,,Slave和Master最好在同一個局域網(wǎng)內(nèi),。

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

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

Redis中

事務(wù)的實現(xiàn)特征:

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

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

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

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

12.5 當使用Append-Only模式時,Redis會通過調(diào)用系統(tǒng)函數(shù)write將該事務(wù)內(nèi)的所有寫操作在本次調(diào)用中全部寫入磁盤。然而如果在寫入的過程中出現(xiàn)系統(tǒng)崩潰,,如電源故障導(dǎo)致的宕機,,那么此時也許只有部分數(shù)據(jù)被寫入到磁盤,,而另外一部分數(shù)據(jù)卻已經(jīng)丟失,。Redis服務(wù)器會在重新啟動時執(zhí)行一系列必要的一致性檢測,,一旦發(fā)現(xiàn)類似問題,就會立即退出并給出相應(yīng)的錯誤提示,。此時,,我們就要充分利用Redis工具包中提供的redis-check-aof工具,,該工具可以幫助我們定位到數(shù)據(jù)不一致的錯誤,,并將已經(jīng)寫入的部分數(shù)據(jù)進行回滾,。修復(fù)之后我們就可以再次重新啟動Redis服務(wù)器了,。

13,、WATCH命令和基于CAS的樂觀鎖?

在Redis的事務(wù)中,,WATCH命令可用于提供CAS(check-and-set)功能。假設(shè)我們通過WATCH命令在事務(wù)執(zhí)行之前監(jiān)控了多個Keys,,倘若在WATCH之后有任何Key的值發(fā)生了變化,,EXEC命令執(zhí)行的事務(wù)都將被放棄,同時返回Null multi-bulk應(yīng)答以通知調(diào)用者事務(wù)

執(zhí)行失敗,。例如,,我們再次假設(shè)Redis中并未提供incr命令來完成鍵值的原子性遞增,如果要實現(xiàn)該功能,,我們只能自行編寫相應(yīng)的代碼,。其偽碼如下:

val = GET mykey val = val + 1 SET mykey $val

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

WATCH mykey val = GET mykey val = val + 1 MULTI SET mykey $val EXEC

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

14,、使用過Redis分布式鎖么,它是什么回事,?

先拿setnx來爭搶鎖,,搶到之后,,再用expire給鎖加一個過期時間防止鎖忘記了釋放。

這時候?qū)Ψ綍嬖V你說你回答得不錯,,然后接著問如果在setnx之后執(zhí)行expire之前進程意外crash或者要重啟維護了,那會怎么樣,?

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

15,、假如Redis里面有1億個key,,其中有10w個key是以某個固定的已知的前綴開頭的,如果將它們?nèi)空页鰜恚?/h2>

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

對方接著追問:如果這個redis正在給線上的業(yè)務(wù)提供服務(wù),,那使用keys指令會有什么問題,?

這個時候你要回答redis關(guān)鍵的一個特性:redis的單線程的。keys指令會導(dǎo)致線程阻塞一段時間,,線上服務(wù)會停頓,,直到指令執(zhí)行完畢,服務(wù)才能恢復(fù),。這個時候可以使用scan指令,,scan指令可以無阻塞的提取出指定模式的key列表,但是會有一定的重復(fù)概率,,在客戶端做一次去重就可以了,,但是整體所花費的時間會比直接用keys指令長。

16,、使用過Redis做異步隊列么,,你是怎么用的?

一般使用list結(jié)構(gòu)作為隊列,,rpush生產(chǎn)消息,,lpop消費消息。當lpop沒有消息的時候,,要適當sleep一會再重試,。

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

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

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

如果對方追問redis如何實現(xiàn)延時隊列,?我估計現(xiàn)在你很想把面試官一棒打死如果你手上有一根棒球棍的話,怎么問的這么詳細,。但是你很克制,然后神態(tài)自若的回答道:使用sortedset,,拿時間戳作為score,,消息內(nèi)容作為key調(diào)用zadd來生產(chǎn)消息,消費者用zrangebyscore指令獲取N秒之前的數(shù)據(jù)輪詢進行處理,。

到這里,,面試官暗地里已經(jīng)對你豎起了大拇指,。但是他不知道的是此刻你卻豎起了中指,在椅子背后,。

17,、如果有大量的key需要設(shè)置同一時間過期,一般需要注意什么,?

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

18,、Redis如何做持久化的,?

bgsave做鏡像全量持久化,aof做增量持久化,。因為bgsave會耗費較長時間,,不夠?qū)崟r,在停機的時候會導(dǎo)致大量丟失數(shù)據(jù),,所以需要aof來配合使用,。在redis實例重啟時,會使用bgsave持久化文件重新構(gòu)建內(nèi)存,,再使用aof重放近期的操作指令來實現(xiàn)完整恢復(fù)重啟之前的狀態(tài),。

對方追問那如果突然機器掉電會怎樣?取決于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ù)提供讀寫服務(wù),寫臟的頁面數(shù)據(jù)會逐漸和子進程分離開來,。

19,、Pipeline有什么好處,為什么要用pipeline,?

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

20,、Redis的同步機制了解么?

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

21,、是否使用過Redis集群,,集群的原理是什么?

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

Redis Cluster著眼于擴展性,,在單個redis內(nèi)存不足時,,使用Cluster進行分片存儲。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點擊一鍵舉報,。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多