1切端、redis和memcached什么區(qū)別?為什么高并發(fā)下有時(shí)單線程的redis比多線程的memcached效率要高?
區(qū)別:
memcached可緩存圖片和視頻掉分。redis支持除k/v更多的數(shù)據(jù)結(jié)構(gòu);
redis可以使用虛擬內(nèi)存,redis可持久化和aof災(zāi)難恢復(fù)酥郭,redis通過主從支持?jǐn)?shù)據(jù)備份华坦;
3.redis可以做消息隊(duì)列。
原因:memcached多線程模型引入了緩存一致性和鎖不从,加鎖帶來了性能損耗惜姐。
2、redis主從復(fù)制如何實(shí)現(xiàn)的椿息?redis的集群模式如何實(shí)現(xiàn)歹袁?redis的key是如何尋址的?
主從復(fù)制實(shí)現(xiàn):主節(jié)點(diǎn)將自己內(nèi)存中的數(shù)據(jù)做一份快照寝优,將快照發(fā)給從節(jié)點(diǎn)条舔,從節(jié)點(diǎn)將數(shù)據(jù)恢復(fù)到內(nèi)存中。之后再每次增加新數(shù)據(jù)的時(shí)候乏矾,主節(jié)點(diǎn)以類似于mysql的二進(jìn)制日志方式將語句發(fā)送給從節(jié)點(diǎn)孟抗,從節(jié)點(diǎn)拿到主節(jié)點(diǎn)發(fā)送過來的語句進(jìn)行重放。
分片方式:
- 客戶端分片
- 基于代理的分片
- Twemproxy
- codis
- 路由查詢分片
- Redis-cluster體身提供了自動(dòng)將數(shù)據(jù)分散到RedisCluster不同節(jié)點(diǎn)的能力钻心,整個(gè)數(shù)據(jù)集合的某個(gè)數(shù)據(jù)子集存儲(chǔ)在哪個(gè)節(jié)點(diǎn)對(duì)于用戶來說是透明的)
- redis-cluster分片原理:Cluster中有一個(gè)16384長度的槽(虛擬槽)夸浅,編號(hào)分別為0-16383。每個(gè)Master節(jié)點(diǎn)都會(huì)負(fù)責(zé)一部分的槽扔役,當(dāng)有某個(gè)key被映射到某個(gè)Master負(fù)責(zé)的槽帆喇,那么這個(gè)Master負(fù)責(zé)為這個(gè)key提供服務(wù),至于哪個(gè)Master節(jié)點(diǎn)負(fù)責(zé)哪個(gè)槽亿胸,可以由用戶指定坯钦,也可以在初始化的時(shí)候自動(dòng)生成,只有Master才擁有槽的所有權(quán)侈玄。Master節(jié)點(diǎn)維護(hù)著一個(gè)16384/8字節(jié)的位序列婉刀,Master節(jié)點(diǎn)用bit來標(biāo)識(shí)對(duì)于某個(gè)槽自己是否擁有。比如對(duì)于編號(hào)為1的槽序仙,Master只要判斷序列的第二位(索引從0開始)是不是為1即可突颊。這種結(jié)構(gòu)很容易添加或者刪除節(jié)點(diǎn)。比如如果我想新添加個(gè)節(jié)點(diǎn)D潘悼,我需要從節(jié)點(diǎn)A律秃、B、C中得部分槽到D上治唤。
3棒动、使用redis如何設(shè)計(jì)分布式鎖?說一下實(shí)現(xiàn)思路宾添?使用zk可以嗎船惨?如何實(shí)現(xiàn)柜裸?這兩種有什么區(qū)別?
redis:
線程Asetnx(上鎖的對(duì)象超時(shí)時(shí)的時(shí)間戳tl)粱锐,如果返回true疙挺,獲得鎖。
線程B用get獲取t1怜浅,與當(dāng)前時(shí)間戳比較铐然,判斷是是否超時(shí),沒超時(shí)false海雪,若超時(shí)執(zhí)行第3步锦爵;
計(jì)算新的超時(shí)時(shí)間t2舱殿,使用getset命令返回t3(該值可能其他線程已經(jīng)修改過)奥裸,如果t1==t3,獲得鎖沪袭,如果t1!=t3說明鎖被其他線程獲取了湾宙。
獲取鎖后,處理完業(yè)務(wù)邏輯冈绊,再去判斷鎖是否超時(shí)侠鳄,如果沒超時(shí)刪除鎖,如果已超時(shí)死宣,不用處理(防止刪除其他線程的鎖)伟恶。
zk:
客戶端對(duì)某個(gè)方法加鎖時(shí),在zk上的與該方法對(duì)應(yīng)的指定節(jié)點(diǎn)的目錄下毅该,生成一個(gè)唯一的瞬時(shí)有序節(jié)點(diǎn)node1博秫;
客戶端獲取該路徑下所有已經(jīng)創(chuàng)建的子節(jié)點(diǎn),如果發(fā)現(xiàn)自己創(chuàng)建的node1的序號(hào)是最小的眶掌,就認(rèn)為這個(gè)客戶端獲得了鎖挡育。
如果發(fā)現(xiàn)node1不是最小的,則監(jiān)聽比自己創(chuàng)建節(jié)點(diǎn)序號(hào)小的最大的節(jié)點(diǎn)朴爬,進(jìn)入等待即寒。
獲取鎖后,處理完邏輯召噩,刪除自己創(chuàng)建的node1即可母赵。區(qū)別:zk性能差一些,開銷大具滴,實(shí)現(xiàn)簡(jiǎn)單市咽。
4、知道redis的持久化嗎抵蚊?底層如何實(shí)現(xiàn)的施绎?有什么優(yōu)點(diǎn)缺點(diǎn)溯革?
RDB(RedisDataBase:在不同的時(shí)間點(diǎn)將redis的數(shù)據(jù)生成的快照同步到磁盤等介質(zhì)上):內(nèi)存到硬盤的快照,定期更新谷醉。缺點(diǎn):耗時(shí)致稀,耗性能(fork+io操作),易丟失數(shù)據(jù)俱尼。
AOF(AppendOnlyFile:將redis所執(zhí)行過的所有指令都記錄下來抖单,在下次redis重啟時(shí),只需要執(zhí)行指令就可以了):寫日志遇八。缺點(diǎn):體積大矛绘,恢復(fù)速度慢。
bgsave做鏡像全量持久化刃永,aof做增量持久化货矮。因?yàn)閎gsave會(huì)消耗比較長的時(shí)間,不夠?qū)崟r(shí)斯够,在停機(jī)的時(shí)候會(huì)導(dǎo)致大量的數(shù)據(jù)丟失囚玫,需要aof來配合,在redis實(shí)例重啟時(shí)读规,優(yōu)先使用aof來恢復(fù)內(nèi)存的狀態(tài)抓督,如果沒有aof日志,就會(huì)使用rdb文件來恢復(fù)束亏。Redis會(huì)定期做aof重寫铃在,壓縮aof文件日志大小。Redis4.0之后有了混合持久化的功能碍遍,將bgsave的全量和aof的增量做了融合處理定铜,這樣既保證了恢復(fù)的效率又兼顧了數(shù)據(jù)的安全性。bgsave的原理雀久,fork和cow宿稀,fork是指redis通過創(chuàng)建子進(jìn)程來進(jìn)行bgsave操作,cow指的是copyonwrite赖捌,子進(jìn)程創(chuàng)建后祝沸,父子進(jìn)程共享數(shù)據(jù)段,父進(jìn)程繼續(xù)提供讀寫服務(wù)越庇,寫臟的頁面數(shù)據(jù)會(huì)逐漸和子進(jìn)程分囲開來罩锐。
5、redis過期策略都有哪些卤唉?LRU算法知道嗎涩惑?寫一下java代碼實(shí)現(xiàn)?
過期策略:
定時(shí)過期(一key一定時(shí)器)桑驱,惰性過期:只有使用key時(shí)才判斷key是否已過期竭恬,過期則清除跛蛋。定期過期:前兩者折中。
LRU:newLinkedHashMap<K痊硕,V>(capacity赊级,DEFAULT_LOAD_FACTORY,true)岔绸;第三個(gè)參數(shù)置為true理逊,代表linkedlist按訪問順序排序,可作為LRU緩存盒揉;設(shè)為false代表按插入順序排序晋被,可作為FIFO緩存
LRU算法實(shí)現(xiàn):
通過雙向鏈表來實(shí)現(xiàn),新數(shù)據(jù)插入到鏈表頭部刚盈;
每當(dāng)緩存命中(即緩存數(shù)據(jù)被訪問)羡洛,則將數(shù)據(jù)移到鏈表頭部;
當(dāng)鏈表滿的時(shí)候扁掸,將鏈表尾部的數(shù)據(jù)丟棄翘县。
LinkedHashMap:HashMap和雙向鏈表合二為一即是LinkedHashMap最域。HashMap是無序的谴分,LinkedHashMap通過維護(hù)一個(gè)額外的雙向鏈表保證了迭代順序。該迭代順序可以是插入順序(默認(rèn))镀脂,也可以是訪問順序牺蹄。
6、緩存穿透薄翅、緩存擊穿沙兰、緩存雪崩解決方案?
緩存穿透:指查詢一個(gè)一定不存在的數(shù)據(jù)翘魄,如果從存儲(chǔ)層查不到數(shù)據(jù)則不寫入緩存鼎天,這將導(dǎo)致這個(gè)不存在的數(shù)據(jù)每次請(qǐng)求都要到DB去查詢,可能導(dǎo)致DB掛掉暑竟。
解決方案:
查詢返回的數(shù)據(jù)為空斋射,仍把這個(gè)空結(jié)果進(jìn)行緩存,但過期時(shí)間會(huì)比較短但荤;
布隆過濾器:將所有可能存在的數(shù)據(jù)哈希到一個(gè)足夠大的bitmap中罗岖,一個(gè)一定不存在的數(shù)據(jù)會(huì)被這個(gè)bitmap攔截掉,從而避免了對(duì)DB的查詢腹躁。
緩存擊穿:對(duì)于設(shè)置了過期時(shí)間的key桑包,緩存在某個(gè)時(shí)間點(diǎn)過期的時(shí)候,恰好這時(shí)間點(diǎn)對(duì)這個(gè)Key有大量的并發(fā)請(qǐng)求過來纺非,這些請(qǐng)求發(fā)現(xiàn)緩存過期一般都會(huì)從后端DB加載數(shù)據(jù)并回設(shè)到緩存哑了,這個(gè)時(shí)候大并發(fā)的請(qǐng)求可能會(huì)瞬間把DB壓垮赘方。
解決方案:
使用互斥鎖:當(dāng)緩存失效時(shí),不立即去Ioaddb弱左,先使用如Redis的setnx去設(shè)置一個(gè)互斥鎖蒜焊,當(dāng)操作成功返回時(shí)再進(jìn)行Ioaddb的操作并回設(shè)緩存,否則重試get緩存的方法科贬。
永遠(yuǎn)不過期:物理不過期泳梆,但邏輯過期(后臺(tái)異步線程去刷新)。緩存雪崩:設(shè)置緩存時(shí)采用了相同的過期時(shí)間榜掌,導(dǎo)致緩存在某一時(shí)刻同時(shí)失效优妙,請(qǐng)求全部轉(zhuǎn)發(fā)到DB,DB瞬時(shí)壓力過重雪崩憎账。與緩存擊穿的區(qū)別:雪崩是很多key套硼,擊穿是某一個(gè)key緩存。
解決方案:
將緩存失效時(shí)間分散開胞皱,比如可以在原有的失效時(shí)間基礎(chǔ)上增加一個(gè)隨機(jī)值邪意,比如1-5分鐘隨機(jī),這樣每一個(gè)緩存的過期時(shí)間的重復(fù)率就會(huì)降低反砌,就很難引發(fā)集體失效的事件雾鬼。
7、在選擇緩存時(shí)宴树,什么時(shí)候選擇redis策菜,什么時(shí)候選擇memcached
選擇redis的情況:
復(fù)雜數(shù)據(jù)結(jié)構(gòu),value的數(shù)據(jù)是哈希酒贬,列表又憨,集合,有序集合等這種情況下锭吨,會(huì)選擇redis蠢莺,因?yàn)閙emcache無法滿足這些數(shù)據(jù)結(jié)構(gòu),最典型的的使用場(chǎng)景是零如,用戶訂單列表躏将,用戶消息,帖子評(píng)論等埠况。
需要進(jìn)行數(shù)據(jù)的持久化功能耸携,但是注意,不要把redis當(dāng)成數(shù)據(jù)庫使用辕翰,如果redis掛了夺衍,內(nèi)存能夠快速恢復(fù)熱數(shù)據(jù),不會(huì)將壓力瞬間壓在數(shù)據(jù)庫上喜命,沒有cache預(yù)熱的過程沟沙。對(duì)于只讀和數(shù)據(jù)一致性要求不高的場(chǎng)景可以采用持久化存儲(chǔ)
高可用河劝,redis支持集群,可以實(shí)現(xiàn)主動(dòng)復(fù)制矛紫,讀寫分離赎瞎,而對(duì)于memcache如果想要實(shí)現(xiàn)高可用,需要進(jìn)行二次開發(fā)颊咬。
存儲(chǔ)的內(nèi)容比較大务甥,memcache存儲(chǔ)的value最大為1M。
選擇memcache的場(chǎng)景:
純KV喳篇,數(shù)據(jù)量非常大的業(yè)務(wù)敞临,使用memcache更合適,原因是:
memcache的內(nèi)存分配采用的是預(yù)分配內(nèi)存池的管理方式麸澜,能夠省去內(nèi)存分配的時(shí)間挺尿,redis是臨時(shí)申請(qǐng)空間,可能導(dǎo)致碎片化炊邦。
虛擬內(nèi)存使用编矾,memcache將所有的數(shù)據(jù)存儲(chǔ)在物理內(nèi)存里,redis有自己的vm機(jī)制馁害,理論上能夠存儲(chǔ)比物理內(nèi)存更多的數(shù)據(jù)窄俏,當(dāng)數(shù)據(jù)超量時(shí),引發(fā)swap蜗细,把冷數(shù)據(jù)刷新到磁盤上裆操,從這點(diǎn)上怒详,數(shù)據(jù)量大時(shí)炉媒,memcache更快
網(wǎng)絡(luò)模型,memcache使用非阻塞的10復(fù)用模型昆烁,redis也是使用非阻塞的I吊骤。復(fù)用模型,但是redis還提供了一些非KV存儲(chǔ)之外的排序静尼,聚合功能白粉,復(fù)雜的CPU計(jì)算,會(huì)阻塞整個(gè)I0調(diào)度鼠渺,從這點(diǎn)上由于redis提供的功能較多鸭巴,memcache更快些
線程模型,memcache使用多線程拦盹,主線程監(jiān)聽鹃祖,worker子線程接受請(qǐng)求,執(zhí)行讀寫普舆,這個(gè)過程可能存在鎖沖突恬口。redis使用的單線程校读,雖然無鎖沖突,但是難以利用多核的特性提升吞吐量祖能。
8歉秫、緩存與數(shù)據(jù)庫不一致怎么辦?
假設(shè)采用的主存分離养铸,讀寫分離的數(shù)據(jù)庫雁芙,
如果一個(gè)線程A先刪除緩存數(shù)據(jù),然后將數(shù)據(jù)寫入到主庫當(dāng)中钞螟,這個(gè)時(shí)候却特,主庫和從庫同步?jīng)]有完成,線程B從緩存當(dāng)中讀取數(shù)據(jù)失敗筛圆,從從庫當(dāng)中讀取到舊數(shù)據(jù)裂明,然后更新至緩存,這個(gè)時(shí)候太援,緩存當(dāng)中的就是舊的數(shù)據(jù)闽晦。
發(fā)生上述不一致的原因在于,主從庫數(shù)據(jù)不一致問題提岔,加入了緩存之后仙蛉,主從不一致的時(shí)間被拉長了阔墩。
處理思路:在從庫有數(shù)據(jù)更新之后案怯,將緩存當(dāng)中的數(shù)據(jù)也同時(shí)進(jìn)行更新,即當(dāng)從庫發(fā)生了數(shù)據(jù)更新之后逛艰,向緩存發(fā)出刪除赛惩,淘汰這段時(shí)間寫入的舊數(shù)據(jù)哀墓。
9、主從數(shù)據(jù)庫不一致如何解決喷兼?
場(chǎng)景描述篮绰,對(duì)于主從庫,讀寫分離季惯,如果主從庫更新同步有時(shí)差吠各,就會(huì)導(dǎo)致主從庫數(shù)據(jù)的不一致
忽略這個(gè)數(shù)據(jù)不一致,在數(shù)據(jù)一致性要求不高的業(yè)務(wù)下勉抓,未必需要時(shí)時(shí)一致性
強(qiáng)制讀主庫贾漏,使用一個(gè)高可用的主庫,數(shù)據(jù)庫讀寫都在主庫藕筋,添加一個(gè)緩存纵散,提升數(shù)據(jù)讀取的性能。
選擇性讀主庫,添加一個(gè)緩存困食,用來記錄必須讀主庫的數(shù)據(jù)边翁,將哪個(gè)庫,哪個(gè)表硕盹,哪個(gè)主鍵符匾,作為緩存的key,設(shè)置緩存失效的時(shí)間為主從庫同步的時(shí)間瘩例,如果緩存當(dāng)中有這個(gè)數(shù)據(jù)啊胶,直接讀取主庫,如果緩存當(dāng)中沒有這個(gè)主鍵垛贤,就到對(duì)應(yīng)的從庫中讀取焰坪。
10、Redis常見的性能問題和解決方案
聘惦、master最好不要做持久化工作某饰,如RDB內(nèi)存快照和AOF日志文件
如果數(shù)據(jù)比較重要,某個(gè)slave開啟AOF備份善绎,策略設(shè)置成每秒同步一次
為了主從復(fù)制的速度和連接的穩(wěn)定性黔漂,master和Slave最好在一個(gè)局域網(wǎng)內(nèi)
盡量避免在壓力大得主庫上增加從庫
主從復(fù)制不要米用網(wǎng)狀結(jié)構(gòu),盡量是線性結(jié)構(gòu)禀酱,Master<--Slave1<—Slave2....
11炬守、Redis的數(shù)據(jù)淘汰策略有哪些
voltile-lru從已經(jīng)設(shè)置過期時(shí)間的數(shù)據(jù)集中挑選最近最少使用的數(shù)據(jù)淘汰
voltile-ttl從已經(jīng)設(shè)置過期時(shí)間的數(shù)據(jù)庫集當(dāng)中挑選將要過期的數(shù)據(jù)
voltile-random從已經(jīng)設(shè)置過期時(shí)間的數(shù)據(jù)集任意選擇淘汰數(shù)據(jù)
allkeys-lru從數(shù)據(jù)集中挑選最近最少使用的數(shù)據(jù)淘汰
allkeys-random從數(shù)據(jù)集中任意選擇淘汰的數(shù)據(jù)
no-eviction禁止驅(qū)逐數(shù)據(jù)
12、Redis當(dāng)中有哪些數(shù)據(jù)結(jié)構(gòu)
字符串String剂跟、字典Hash减途、列表List、集合Set曹洽、有序集合SortedSet鳍置。如果是咼級(jí)用戶,那么還會(huì)有衣洁,如果你是Redis中高級(jí)用戶墓捻,還需要加上下面幾種數(shù)據(jù)結(jié)構(gòu)HyperLogLog、Geo坊夫、Pub/Sub。
13撤卢、假如Redis里面有1億個(gè)key环凿,其中有10w個(gè)key是以某個(gè)固定的已知的前綴開頭的,如果將它們?nèi)空页鰜恚?/h4>
使用keys指令可以掃出指定模式的key列表放吩。
對(duì)方接著追問:如果這個(gè)redis正在給線上的業(yè)務(wù)提供服務(wù)智听,那使用keys指令會(huì)有什么問題?
這個(gè)時(shí)候你要回答redis關(guān)鍵的一個(gè)特性:redis的單線程的。keys指令會(huì)導(dǎo)致線程阻塞一段時(shí)間到推,線上服務(wù)會(huì)停頓考赛,直到指令執(zhí)行完畢,服務(wù)才能恢復(fù)莉测。這個(gè)時(shí)候可以使用scan指令颜骤,scan指令可以無阻塞的提取出指定模式的key列表,但是會(huì)有一定的重復(fù)概率捣卤,在客戶端做一次去重就可以了忍抽,但是整體所花費(fèi)的時(shí)間會(huì)比直接用keys指令長。
14董朝、使用Redis做過異步隊(duì)列嗎鸠项,是如何實(shí)現(xiàn)的
使用list類型保存數(shù)據(jù)信息,rpush生產(chǎn)消息子姜,lpop消費(fèi)消息祟绊,當(dāng)lpop沒有消息時(shí),可以sleep一段時(shí)間哥捕,然后再檢查有沒有信息久免,如果不想sleep的話,可以使用blpop扭弧,在沒有信息的時(shí)候阎姥,會(huì)一直阻塞,直到信息的到來鸽捻。redis可以通過pub/sub主題訂閱模式實(shí)現(xiàn)一個(gè)生產(chǎn)者呼巴,多個(gè)消費(fèi)者,當(dāng)然也存在一定的缺點(diǎn)御蒲,當(dāng)消費(fèi)者下線時(shí)衣赶,生產(chǎn)的消息會(huì)丟失。
15厚满、Redis如何實(shí)現(xiàn)延時(shí)隊(duì)列
使用sortedset府瞄,使用時(shí)間戳做score,消息內(nèi)容作為key碘箍,調(diào)用zadd來生產(chǎn)消息遵馆,消費(fèi)者使用zrangbyscore獲取n秒之前的數(shù)據(jù)做輪詢處理。
16丰榴、什么是Redis货邓?簡(jiǎn)述它的優(yōu)缺點(diǎn)?
Redis本質(zhì)上是一個(gè)Key-Value類型的內(nèi)存數(shù)據(jù)庫四濒,很像memcached换况,整個(gè)數(shù)據(jù)庫統(tǒng)統(tǒng)加載在內(nèi)存當(dāng)中進(jìn)行操作职辨,定期通過異步操作把數(shù)據(jù)庫數(shù)據(jù)flush到硬盤上進(jìn)行保存。
因?yàn)槭羌儍?nèi)存操作戈二,Redis的性能非常出色舒裤,每秒可以處理超過10萬次讀寫操作,是已知性能最快的Key-ValueDB觉吭。
Redis的出色之處不僅僅是性能腾供,Redis最大的魅力是支持保存多種數(shù)據(jù)
結(jié)構(gòu),此外單個(gè)value的最大限制是1GB亏栈,不像memcached只能保存1MB的數(shù)據(jù)台腥,因此Redis可以用來實(shí)現(xiàn)很多有用的功能。
比方說用他的List來做FIFO雙向鏈表绒北,實(shí)現(xiàn)一個(gè)輕量級(jí)的高性能消息隊(duì)列服務(wù)黎侈,用他的Set可以做高性能的tag系統(tǒng)等等。
另外Redis也可以對(duì)存入的Key-Value設(shè)置expire時(shí)間闷游,因此也可以被當(dāng)作一個(gè)功能加強(qiáng)版的memcached來用峻汉。Redis的主要缺點(diǎn)是數(shù)據(jù)庫容量受到物理內(nèi)存的限制,不能用作海量數(shù)據(jù)的高性能讀寫脐往,因此Redis適合的場(chǎng)景主要局限在較小數(shù)據(jù)量的高性能操作和運(yùn)算上休吠。
17、Redis相比memcached有哪些優(yōu)勢(shì)业簿?
memcached所有的值均是簡(jiǎn)單的字符串瘤礁,redis作為其替代者,支持更為豐富數(shù)據(jù)類型
Redis的速度比memcached快很多
redis可以持久化其數(shù)據(jù)
18梅尤、Redis支持哪幾種數(shù)據(jù)類型柜思?
String、List巷燥、Set赡盘、SortedSet、hashes
19缰揪、Redis主要消耗什么物理資源陨享?
內(nèi)存。
20钝腺、Redis的全稱是什么抛姑?
Remote Dictionary Server
21、Redis有哪幾種數(shù)據(jù)淘汰策略拍屑?
noeviction:返回錯(cuò)誤當(dāng)內(nèi)存限制達(dá)到并且客戶端嘗試執(zhí)行會(huì)讓更多內(nèi)存被使用的命令(大部分的寫入指令途戒,但DEL和幾個(gè)例外)
allkeys-lru:嘗試回收最少使用的鍵(LRU),使得新添加的數(shù)據(jù)有空間存放僵驰。
volatile-lru:嘗試回收最少使用的鍵(LRU),但僅限于在過期集合的鍵,使得新添加的數(shù)據(jù)有空間存放蒜茴。
allkeys-random:回收隨機(jī)的鍵使得新添加的數(shù)據(jù)有空間存放星爪。
volatile-random:回收隨機(jī)的鍵使得新添加的數(shù)據(jù)有空間存放,但僅限于在過期集合的鍵粉私。
volatile-ttl:回收在過期集合的鍵顽腾,并且優(yōu)先回收存活時(shí)間(TTL)較短的鍵,使得新添加的數(shù)據(jù)有空間存放诺核。
22抄肖、Redis官方為什么不提供Windows版本?
因?yàn)槟壳癓inux版本已經(jīng)相當(dāng)穩(wěn)定窖杀,而且用戶量很大漓摩,無需開發(fā)windows版本,反而會(huì)帶來兼容性等問題入客。
23管毙、一個(gè)字符串類型的值能存儲(chǔ)最大容量是多少?
512M
24桌硫、為什么Redis需要把所有數(shù)據(jù)放到內(nèi)存中夭咬?
Redis為了達(dá)到最快的讀寫速度將數(shù)據(jù)都讀到內(nèi)存中,并通過異步的方式將數(shù)據(jù)寫入磁盤铆隘。
所以redis具有快速和數(shù)據(jù)持久化的特征卓舵。如果不將數(shù)據(jù)放在內(nèi)存中,磁盤I/O速度為嚴(yán)重影響redis的性能膀钠。
在內(nèi)存越來越便宜的今天掏湾,redis將會(huì)越來越受歡迎。如果設(shè)置了最大使用的內(nèi)存托修,則數(shù)據(jù)已有記錄數(shù)達(dá)到內(nèi)存限值后不能繼續(xù)插入新值忘巧。
25、Redis集群方案應(yīng)該怎么做睦刃?都有哪些方案砚嘴?
codis。
目前用的最多的集群方案涩拙,基本和twemproxy一致的效果际长,但它支持在節(jié)點(diǎn)數(shù)量改變情況下,舊節(jié)點(diǎn)數(shù)據(jù)可恢復(fù)到新hash節(jié)點(diǎn)兴泥。rediscluster3.0自帶的集群工育,特點(diǎn)在于他的分布式算法不是一致性hash,而是hash槽的概念搓彻,以及自身支持節(jié)點(diǎn)設(shè)置從節(jié)點(diǎn)如绸。具體看官方文檔介紹嘱朽。
在業(yè)務(wù)代碼層實(shí)現(xiàn),起幾個(gè)毫無關(guān)聯(lián)的redis實(shí)例怔接,在代碼層搪泳,對(duì)key進(jìn)行hash計(jì)算,然后去對(duì)應(yīng)的redis實(shí)例操作數(shù)據(jù)扼脐。這種方式對(duì)hash層代碼要求比較高岸军,考慮部分包括,節(jié)點(diǎn)失效后的替代算法方案瓦侮,數(shù)據(jù)震蕩后的自動(dòng)腳本恢復(fù)艰赞,實(shí)例的監(jiān)控,等等肚吏。
26方妖、Redis集群方案什么情況下會(huì)導(dǎo)致整個(gè)集群不可用?
有A须喂,B吁断,C三個(gè)節(jié)點(diǎn)的集群,在沒有復(fù)制模型的情況下坞生,如果節(jié)點(diǎn)B失敗了仔役,那么整個(gè)集群就會(huì)以為缺少5501-11000這個(gè)范圍的槽而不可用。
27是己、MySQL里有2000w數(shù)據(jù)又兵,redis中只存20w的數(shù)據(jù),如何保證redis中的數(shù)據(jù)都是熱點(diǎn)數(shù)據(jù)卒废?
redis內(nèi)存數(shù)據(jù)集大小上升到一定大小的時(shí)候沛厨,就會(huì)施行數(shù)據(jù)淘汰策略。
28摔认、Redis有哪些適合的場(chǎng)景逆皮?
- 會(huì)話緩存(SessionCache)
最常用的一種使用Redis的情景是會(huì)話緩存(sessioncache)。用Redis緩存會(huì)話比其他存儲(chǔ)(如Memcached)的優(yōu)勢(shì)在于:Redis提供持久化参袱。當(dāng)維護(hù)一個(gè)不是嚴(yán)格要求一致性的緩存時(shí)电谣,如果用戶的購物車信息全部丟失,大部分人都會(huì)不高興的抹蚀,現(xiàn)在剿牺,他們還會(huì)這樣嗎?
幸運(yùn)的是环壤,隨著Redis這些年的改進(jìn)晒来,很容易找到怎么恰當(dāng)?shù)氖褂肦edis來緩存會(huì)話的文檔。甚至廣為人知的商業(yè)平臺(tái)Magento也提供Redis的插件郑现。
- 全頁緩存(FPC)
除基本的會(huì)話token之外湃崩,Redis還提供很簡(jiǎn)便的FPC平臺(tái)荧降。回到一致性問題竹习,即使重啟了Redis實(shí)例誊抛,因?yàn)橛写疟P的持久化列牺,用戶也不會(huì)看到頁面加載速度的下降整陌,這是一個(gè)極大改進(jìn),類似PHP本地FPC瞎领。
再次以Magento為例泌辫,Magento提供一個(gè)插件來使用Redis作為全頁緩存后端。
此外九默,對(duì)WordPress的用戶來說震放,Pantheon有一個(gè)非常好的插件wp-redis,這個(gè)插件能幫助你以最快速度加載你曾瀏覽過的頁面驼修。
- 隊(duì)列
Reids在內(nèi)存存儲(chǔ)引擎領(lǐng)域的一大優(yōu)點(diǎn)是提供list和set操作殿遂,這使得Redis能作為一個(gè)很好的消息隊(duì)列平臺(tái)來使用。Redis作為隊(duì)列使用的操作乙各,就類似于本地程序語言(如Python)對(duì)list的push/pop操作墨礁。
如果你快速的在Google中搜索"Redisqueues",你馬上就能找到大量的開源項(xiàng)目耳峦,這些項(xiàng)目的目的就是利用Redis創(chuàng)建非常好的后端工具,以滿足各種隊(duì)列需求蹲坷。例如驶乾,Celery有一個(gè)后臺(tái)就是使用Redis作為broker,你可以從這里去查看循签。
- 排行榜/計(jì)數(shù)器
Redis在內(nèi)存中對(duì)數(shù)字進(jìn)行遞增或遞減的操作實(shí)現(xiàn)的非常好级乐。集合(Set)和有序集合(SortedSet)也使得我們?cè)趫?zhí)行這些操作的時(shí)候變的非常簡(jiǎn)單,Redis只是正好提供了這兩種數(shù)據(jù)結(jié)構(gòu)县匠。所以风科,我們要從排序集合中獲取到排名最靠前的10個(gè)用戶-我們稱之為“user_scores”,我們只需要像下面一樣執(zhí)行即可:
當(dāng)然聚唐,這是假定你是根據(jù)你用戶的分?jǐn)?shù)做遞增的排序丐重。如果你想返回用戶及用戶的分?jǐn)?shù),你需要這樣執(zhí)行:
ZRANGEuser_scores010WITHSCORES
AgoraGames就是一個(gè)很好的例子杆查,用Ruby實(shí)現(xiàn)的扮惦,它的排行榜就是使用Redis來存儲(chǔ)數(shù)據(jù)的,你可以在這里看到亲桦。
- 發(fā)布/訂閱
最后(但肯定不是最不重要的)是Redis的發(fā)布/訂閱功能崖蜜。發(fā)布/訂閱的使用場(chǎng)景確實(shí)非常多浊仆。我已看見人們?cè)谏缃痪W(wǎng)絡(luò)連接中使用,還可作為基于發(fā)布/訂閱的腳本觸發(fā)器豫领,甚至用Redis的發(fā)布/訂閱功能來建立聊天系統(tǒng)抡柿!
29、Redis支持的Java客戶端都有哪些等恐?官方推薦用哪個(gè)洲劣?
Redisson、Jedis课蔬、lettuce等等囱稽,官方推薦使用Redisson。
30二跋、Redis和Redisson有什么關(guān)系战惊?
Redisson是一個(gè)高級(jí)的分布式協(xié)調(diào)Redis客服端,能幫助用戶在分布式環(huán)境中輕松實(shí)現(xiàn)一些Java的對(duì)象(Bloomfilter扎即,BitSet吞获,Set,SetMultimap谚鄙,ScoredSortedSet各拷,SortedSet,Map襟锐,ConcurrentMap撤逢,List,ListMultimap粮坞,Queue蚊荣,BlockingQueue,Deque莫杈,BlockingDeque互例,Semaphore,Lock筝闹,ReadWriteLock媳叨,AtomicLong,CountDownLatch关顷,Publish/Subscribe糊秆,HyperLogLog)。
31议双、Jedis與Redisson對(duì)比有什么優(yōu)缺點(diǎn)痘番?
Jedis是Redis的Java實(shí)現(xiàn)的客戶端,其API提供了比較全面的Redis命令的支持;
Redisson實(shí)現(xiàn)了分布式和可擴(kuò)展的Java數(shù)據(jù)結(jié)構(gòu)汞舱,和Jedis相比伍纫,功能較為簡(jiǎn)單,不支持字符串操作昂芜,不支持排序莹规、事務(wù)、管道泌神、分區(qū)等Redis特性良漱。Redisson的宗旨是促進(jìn)使用者對(duì)Redis的關(guān)注分離,從而讓使用者能夠?qū)⒕Ω械胤旁谔幚順I(yè)務(wù)邏輯上腻扇。
32债热、Redis如何設(shè)置密碼及驗(yàn)證密碼?
設(shè)置密碼:config set require pass 123456 授權(quán)密碼:auth123456
33幼苛、說說Redis哈希槽的概念?
Redis集群沒有使用一致性hash焕刮,而是引入了哈希槽的概念舶沿,Redis集群有16384個(gè)哈希槽,每個(gè)key通過CRC16校驗(yàn)后對(duì)16384取模來決定放置哪個(gè)槽配并,集群的每個(gè)節(jié)點(diǎn)負(fù)責(zé)一部分hash槽括荡。
34、Redis集群的主從復(fù)制模型是怎樣的溉旋?
為了使在部分節(jié)點(diǎn)失敗或者大部分節(jié)點(diǎn)無法通信的情況下集群仍然可用畸冲,所以集群使用了主從復(fù)制模型,每個(gè)節(jié)點(diǎn)都會(huì)有N-1個(gè)復(fù)制品.
35观腊、Redis集群會(huì)有寫操作丟失嗎邑闲?為什么?
Redis并不能保證數(shù)據(jù)的強(qiáng)一致性梧油,這意味這在實(shí)際中集群在特定的條件下可能會(huì)丟失寫操作苫耸。
36、Redis集群之間是如何復(fù)制的儡陨?
異步復(fù)制
37褪子、Redis集群最大節(jié)點(diǎn)個(gè)數(shù)是多少?
16384個(gè)骗村。
38嫌褪、Redis集群如何選擇數(shù)據(jù)庫?
Redis集群目前無法做數(shù)據(jù)庫選擇胚股,默認(rèn)在0數(shù)據(jù)庫笼痛。
39、怎么測(cè)試Redis的連通性信轿?
ping
40晃痴、Redis中的管道有什么用残吩?
一次請(qǐng)求/響應(yīng)服務(wù)器能實(shí)現(xiàn)處理新的請(qǐng)求即使舊的請(qǐng)求還未被響應(yīng)。這樣就可以將多個(gè)命令發(fā)送到服務(wù)器倘核,而不用等待回復(fù)泣侮,最后在一個(gè)步驟中讀取該答復(fù)。
這就是管道(pipelining)紧唱,是一種幾十年來廣泛使用的技術(shù)活尊。例如許多POP3協(xié)議已經(jīng)實(shí)現(xiàn)支持這個(gè)功能,大大加快了從服務(wù)器下載新郵件的過程漏益。
41蛹锰、怎么理解Redis事務(wù)?
事務(wù)是一個(gè)單獨(dú)的隔離操作:事務(wù)中的所有命令都會(huì)序列化绰疤、按順序地執(zhí)行铜犬。事務(wù)在執(zhí)行的過程中,不會(huì)被其他客戶端發(fā)送來的命令請(qǐng)求所打斷轻庆。事務(wù)是一個(gè)原子操作:事務(wù)中的命令要么全部被執(zhí)行癣猾,要么全部都不執(zhí)行。
42余爆、Redis事務(wù)相關(guān)的命令有哪幾個(gè)纷宇?
MULTI、EXEC蛾方、DISCARD像捶、WATCH
43、Rediskey的過期時(shí)間和永久有效分別怎么設(shè)置桩砰?
EXPIRE和PERSIST命令拓春。
44、Redis如何做內(nèi)存優(yōu)化五芝?
盡可能使用散列表(hashes)痘儡,散列表(是說散列表里面存儲(chǔ)的數(shù)少)使用的內(nèi)存非常小,所以你應(yīng)該盡可能的將你的數(shù)據(jù)模型抽象到一個(gè)散列表里面枢步。比如你的web系統(tǒng)中有一個(gè)用戶對(duì)象沉删,不要為這個(gè)用戶的名稱,姓氏醉途,郵箱矾瑰,密碼設(shè)置單獨(dú)的key,而是應(yīng)該把這個(gè)用戶的所有信息存儲(chǔ)到一張散列表里面隘擎。
45殴穴、Redis回收進(jìn)程如何工作的?
一個(gè)客戶端運(yùn)行了新的命令,添加了新的數(shù)據(jù)采幌。
Redi檢查內(nèi)存使用情況劲够,如果大于maxmemory的限制,則根據(jù)設(shè)定好的策略進(jìn)行回收休傍。一個(gè)新的命令被執(zhí)行征绎,等等。
所以我們不斷地穿越內(nèi)存限制的邊界磨取,通過不斷達(dá)到邊界然后不斷地回收回到邊界以下人柿。
如果一個(gè)命令的結(jié)果導(dǎo)致大量?jī)?nèi)存被使用(例如很大的集合的交集保存到一個(gè)新的鍵),不用多久內(nèi)存限制就會(huì)被這個(gè)內(nèi)存使用量超越忙厌。