1.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ǔ)到一張散列表里面。
2.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ù)器下載新郵件的過程。
3.Redis和Redisson有什么關(guān)系?
Redisson是一個(gè)高級(jí)的分布式協(xié)調(diào)Redis客服端,能幫助用戶在分布式環(huán)境中輕松實(shí)現(xiàn)一些 Java的對(duì)象 (Bloom filter, BitSet, Set, SetMultimap, ScoredSortedSet, SortedSet, Map, ConcurrentMap, List, ListMultimap, Queue, BlockingQueue, Deque, BlockingDeque, Semaphore, Lock, ReadWriteLock, AtomicLong, CountDownLatch, Publish / Subscribe, HyperLogLog)。
4.Redis有哪些適合的場(chǎng)景?
(1)會(huì)話緩存(Session Cache)
最常用的一種使用Redis的情景是會(huì)話緩存(session cache)。用Redis緩存會(huì)話比其他存儲(chǔ) (如Memcached)的優(yōu)勢(shì)在于:Redis提供持久化。當(dāng)維護(hù)一個(gè)不是嚴(yán)格要求一致性的緩存 時(shí),如果用戶的購(gòu)物車信息全部丟失,大部分人都會(huì)不高興的,現(xiàn)在,他們還會(huì)這樣嗎?
幸運(yùn)的是,隨著 Redis 這些年的改進(jìn),很容易找到怎么恰當(dāng)?shù)氖褂肦edis來緩存會(huì)話的文檔。甚至廣為人知的商業(yè)平臺(tái)Magento也提供Redis的插件。
(2)全頁(yè)緩存(FPC)
除基本的會(huì)話token之外,Redis還提供很簡(jiǎn)便的FPC平臺(tái)?;氐揭恢滦詥栴},即使重啟了 Redis實(shí)例,因?yàn)橛写疟P的持久化,用戶也不會(huì)看到頁(yè)面加載速度的下降,這是一個(gè)極大改 進(jìn),類似PHP本地FPC。
再次以Magento為例,Magento提供一個(gè)插件來使用Redis作為全頁(yè)緩存后端。
此外,對(duì)WordPress的用戶來說,Pantheon有一個(gè)非常好的插件 wp-redis,這個(gè)插件能幫 助你以最快速度加載你曾瀏覽過的頁(yè)面。
(3)隊(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中搜索“Redis queues”,你馬上就能找到大量的開源項(xiàng)目,這些項(xiàng)目 的目的就是利用Redis創(chuàng)建非常好的后端工具,以滿足各種隊(duì)列需求。例如,Celery有一個(gè)后 臺(tái)就是使用Redis作為broker,你可以從這里去查看。
(4)排行榜/計(jì)數(shù)器
Redis在內(nèi)存中對(duì)數(shù)字進(jìn)行遞增或遞減的操作實(shí)現(xiàn)的非常好。集合(Set)和有序集合(Sorted Set)也使得我們?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í)行:
ZRANGE user_scores 0 10 WITHSCORES
Agora Games就是一個(gè)很好的例子,用Ruby實(shí)現(xiàn)的,它的排行榜就是使用Redis來存儲(chǔ)數(shù)據(jù) 的,你可以在這里看到。
(5)發(fā)布/訂閱
最后(但肯定不是最不重要的)是Redis的發(fā)布/訂閱功能。發(fā)布/訂閱的使用場(chǎng)景確實(shí)非常 多。我已看見人們?cè)谏缃痪W(wǎng)絡(luò)連接中使用,還可作為基于發(fā)布/訂閱的腳本觸發(fā)器,甚至用 Redis的發(fā)布/訂閱功能來建立聊天系統(tǒng)!
5.MySQL 里有 2000w 數(shù)據(jù),redis 中只存 20w 的數(shù)據(jù),如何保證 redis 中的數(shù)據(jù)都 是熱點(diǎn)數(shù)據(jù)?
redis 內(nèi)存數(shù)據(jù)集大小上升到一定大小的時(shí)候,就會(huì)施行數(shù)據(jù)淘汰策略。
其實(shí)面試除了考察 Redis,不少公司都很重視高并發(fā)高可用的技術(shù),特別是一線互聯(lián)網(wǎng)公司, 分布式、
JVM、spring 源碼分析、微服務(wù)等知識(shí)點(diǎn)已是面試的必考題。
6.Redis 集群方案什么情況下會(huì)導(dǎo)致整個(gè)集群不可用?
有 A,B,C 三個(gè)節(jié)點(diǎn)的集群,在沒有復(fù)制模型的情況下,如果節(jié)點(diǎn) B 失敗了,那么整個(gè)集群就會(huì) 以為缺少5501-11000 這個(gè)范圍的槽而不可用。
7.Redis 集群方案應(yīng)該怎么做?都有哪些方案?
codis
目前用的最多的集群方案,基本和 twemproxy 一致的效果,但它支持在節(jié)點(diǎn)數(shù)量改變情況下,舊節(jié)點(diǎn)數(shù)據(jù)可恢復(fù)到新 hash 節(jié)點(diǎn)。
redis cluster
3.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)控,等等。
8.Redis String的內(nèi)部編碼有哪些?
int、embstr、raw
10000以下的整數(shù)會(huì)使用緩存里的int常量。
長(zhǎng)度小于等于44字節(jié):embstr編碼
長(zhǎng)度大于44字節(jié):raw編碼
9.用Redis做延時(shí)隊(duì)列,具體應(yīng)該怎么實(shí)現(xiàn)?
可以使用Zset實(shí)現(xiàn)。member是任務(wù)描述,score是執(zhí)行時(shí)間,然后用定時(shí)器定時(shí)去掃描,一 旦有執(zhí)行時(shí)間小于或等于當(dāng)前時(shí)間的任務(wù),就立即執(zhí)行。
10.Redis在集群種查找key的時(shí)候,是怎么定位到具體節(jié)點(diǎn)的?
使用crc16算法對(duì)key進(jìn)行hash 將hash值對(duì)16384取模,得到具體的槽位根據(jù)節(jié)點(diǎn)和槽位的映射信息(與集群建立連接后,客戶端可以取得槽位映射信息),找到具體的節(jié)點(diǎn)地址 去具體的節(jié)點(diǎn)找key如果key不在這個(gè)節(jié)點(diǎn)上,則redis集群會(huì)返回moved指令,加上新的節(jié)點(diǎn)地址給客戶端,同時(shí),客戶端會(huì)刷新本地的節(jié)點(diǎn)槽位映射關(guān)系如果槽位正在遷移中,那么redis集群會(huì)返回asking指令給客戶端,這是臨時(shí)糾正,客戶端不會(huì)刷新本地的節(jié)點(diǎn)槽位映射關(guān)系
11.Redis的持久化了解過嗎?
Redis持久化有RDB和AOF這2種方式。
RDB:將數(shù)據(jù)庫(kù)快照以二進(jìn)制的方式保存到磁盤中。
AOF:以協(xié)議文本方式,將所有對(duì)數(shù)據(jù)庫(kù)進(jìn)行過寫入的命令和參數(shù)記錄到AOF文件,從而記錄 數(shù)據(jù)庫(kù)狀態(tài)。
12.Redis在什么情況下會(huì)觸發(fā)key的回收?
2種情況:1、定時(shí)(抽樣)清理;2、執(zhí)行命令時(shí),判斷內(nèi)存是否超過maxmemory。
13.Redis key的淘汰策略有哪些?
8種:noeviction,volatile-lru,volatile-lfu,volatile-ttl,volatile-random,allkeylru,allkeys-lfu,allkeys-random
14.Redis事務(wù)機(jī)制了解過嗎?
Redis事務(wù)的概念:
Redis 事務(wù)的本質(zhì)是一組命令的集合。事務(wù)支持一次執(zhí)行多個(gè)命令,一個(gè)事務(wù)中所有命令都會(huì) 被序列化。在事務(wù)執(zhí)行過程,會(huì)按照順序串行化執(zhí)行隊(duì)列中的命令,其他客戶端提交的命令請(qǐng) 求不會(huì)插入到事務(wù)執(zhí)行命令序列中。
Redis事務(wù)就是一次性、順序性、排他性的執(zhí)行一個(gè)隊(duì)列中的一系列命令。
Redis事務(wù)沒有隔離級(jí)別的概念:
批量操作在發(fā)送 EXEC 命令前被放入隊(duì)列緩存,并不會(huì)被實(shí)際執(zhí)行,也就不存在事務(wù)內(nèi)的查詢 要看到事務(wù)里的更新,事務(wù)外查詢不能看到。
Redis不保證原子性:
Redis中,單條命令是原子性執(zhí)行的,但事務(wù)不保證原子性,且沒有回滾。事務(wù)中任意命令執(zhí) 行失敗,其余的命令仍會(huì)被執(zhí)行。
Redis事務(wù)的三個(gè)階段:
開始事務(wù)
命令入隊(duì)
執(zhí)行事務(wù)
Redis事務(wù)相關(guān)命令:
watch key1 key2 … : 監(jiān)視一或多個(gè)key,如果在事務(wù)執(zhí)行之前,被監(jiān)視的key被其他命令改動(dòng), 則事務(wù)被打斷 ( 類似樂觀鎖 )
multi : 標(biāo)記一個(gè)事務(wù)塊的開始( queued )
exec : 執(zhí)行所有事務(wù)塊的命令 ( 一旦執(zhí)行exec后,之前加的監(jiān)控鎖都會(huì)被取消掉 )
discard : 取消事務(wù),放棄事務(wù)塊中的所有命令
unwatch : 取消watch對(duì)所有key的監(jiān)控
15.使用Redis統(tǒng)計(jì)網(wǎng)站的UV,應(yīng)該怎么做?
UV與PV不同,UV需要去重。一般有2種方案:
1、用BitMap。存的是用戶的uid,計(jì)算UV的時(shí)候,做下bitcount就行了。
2、用布隆過濾器。將每次訪問的用戶uid都放到布隆過濾器中。優(yōu)點(diǎn)是省內(nèi)存,缺點(diǎn)是無法得 到精確的UV。但是對(duì)于不需要精確知道具體UV,只需要大概的數(shù)量級(jí)的場(chǎng)景,是個(gè)不錯(cuò)的選 擇。
16.Redis中的大key怎么處理?
大key指的是value特別大的key。比如很長(zhǎng)的字符串,或者很大的set等等。大key會(huì)造成2個(gè)問題:
1、數(shù)據(jù)傾斜,比如某些節(jié)點(diǎn)內(nèi)存占用過高。
2、當(dāng)刪除大key或者大 key自動(dòng)過期的時(shí)候,會(huì)造成QPS突降,因?yàn)镽edis是單線程的緣故。
處理方案:可以將一個(gè)大key進(jìn)行分片處理,比如:將一個(gè)大set分成多個(gè)小的set。
17.Redis中的熱key怎么處理?
1、對(duì)熱key進(jìn)行分散處理。比如:在key上加上不同的前后綴,緩存多個(gè)key,使得各個(gè)key分 散到不同的節(jié)點(diǎn)上。
2、采用多級(jí)緩存。
18.緩存失效?緩存穿透?緩存雪崩?緩存并發(fā)?
緩存失效 緩存失效指的是大量的緩存在同一時(shí)間失效,到時(shí)DB的瞬間壓力飆升。造成這種現(xiàn)象的 原因是,key的過期時(shí)間都設(shè)置成一樣了。解決方案是,key的過期時(shí)間引入隨機(jī)因素, 比如5分鐘+隨機(jī)秒這種方式。
緩存穿透 緩存穿透是指查詢一條數(shù)據(jù)庫(kù)和緩存都沒有的一條數(shù)據(jù),就會(huì)一直查詢數(shù)據(jù)庫(kù),對(duì)數(shù)據(jù) 庫(kù)的訪問壓力就會(huì)增大,緩存穿透的解決方案,有以下2種:緩存空對(duì)象:代碼維護(hù)較簡(jiǎn)單,但是效果不好。布隆過濾器:代碼維護(hù)復(fù)雜,效果很好。
緩存雪崩 緩存雪崩 是指在某一個(gè)時(shí)間段,緩存集中過期失效。此刻無數(shù)的請(qǐng)求直接繞開緩存,直 接請(qǐng)求數(shù)據(jù)庫(kù)。造成緩存雪崩的原因,有以下2種:reids宕機(jī)。大部分?jǐn)?shù)據(jù)失效。
對(duì)于緩存雪崩的解決方案有以下2種:
搭建高可用的集群,防止單機(jī)的redis宕機(jī)。
設(shè)置不同的過期時(shí)間,防止同意之間內(nèi)大量的key失效。
緩存并發(fā) 有時(shí)候如果網(wǎng)站并發(fā)訪問高,一個(gè)緩存如果失效,可能出現(xiàn)多個(gè)進(jìn)程同時(shí)查詢DB,同時(shí) 設(shè)置緩存的情況,如果并發(fā)確實(shí)很大,這也可能造成DB壓力過大,還有緩存頻繁更新的 問題。一般處理方案是在查DB的時(shí)候進(jìn)行加鎖,如果KEY不存在,就加鎖,然后查DB入緩存, 然后解鎖;其他進(jìn)程如果發(fā)現(xiàn)有鎖就等待,然后等解鎖后再查緩存或者進(jìn)入DB查詢。
19.Redis集群如何選擇數(shù)據(jù)庫(kù)?
Redis集群目前無法做數(shù)據(jù)庫(kù)選擇,默認(rèn)在0數(shù)據(jù)庫(kù)。
20.Redis如何設(shè)置密碼及驗(yàn)證密碼?
設(shè)置密碼:config set requirepass 123456
授權(quán)密碼:auth 123456
21.為什么 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ù)插入新值。
22.Redis 官方為什么不提供 Windows 版本?
因?yàn)槟壳?Linux 版本已經(jīng)相當(dāng)穩(wěn)定,而且用戶量很大,無需開發(fā) windows 版本,反而會(huì)帶來 兼容性等問題。
23.Redis是單線程還是多線程?
Redis6.0采用多線程IO,不過命令的執(zhí)行還是單線程的。
Redis6.0之前,IO線程和執(zhí)行線程都是單線程的。
24.Redis為什么那么快?
1、內(nèi)存操作;
2、單線程,省去線程切換、鎖競(jìng)爭(zhēng)的開銷;
3、非阻塞IO模型,epoll。
25.一個(gè)字符串類型的值能存儲(chǔ)最大容量是多少?
512M
26.Redis的全稱是什么?
Remote Dictionary Server。
27.Redis主要消耗什么物理資源?
內(nèi)存。
28.Redis有哪些數(shù)據(jù)結(jié)構(gòu)?
Redis 有 5 種基礎(chǔ)數(shù)據(jù)結(jié)構(gòu),它們分別是:string(字符串)、list(列表)、hash(字典)、set(集 合) 和 zset(有序集合)。
這 5 種是 Redis 相關(guān)知識(shí)中最基礎(chǔ)、最重要的部分。
29.Redis相比memcached有哪些優(yōu)勢(shì)?
(1) memcached所有的值均是簡(jiǎn)單的字符串,redis作為其替代者,支持更為豐富的數(shù)據(jù)類型
(2) redis的速度比memcached快很多
(3) redis可以持久化其數(shù)據(jù)
30.什么是Redis?簡(jiǎn)述它的優(yōu)缺點(diǎn)?
Redis本質(zhì)上是一個(gè)Key-Value類型的內(nèi)存數(shù)據(jù)庫(kù),很像memcached,整個(gè)數(shù)據(jù)庫(kù)統(tǒng)統(tǒng)加載 在內(nèi)存當(dāng)中進(jìn)行操作,定期通過異步操作把數(shù)據(jù)庫(kù)數(shù)據(jù)flush到硬盤上進(jìn)行保存。
因?yàn)槭羌儍?nèi)存操作,Redis的性能非常出色,每秒可以處理超過 10萬次讀寫操作,是已知性能 最快的Key-Value DB。
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ù)庫(kù)容量受到物理內(nèi)存的限制,不能用作海量數(shù)據(jù) 的高性能讀寫,因此Redis適合的場(chǎng)景主要局限在較小數(shù)據(jù)量的高性能操作和運(yùn)算上。
推薦學(xué)習(xí):《redis視頻教程》