redis面试问题(二)
1.redis和其他緩存相比有哪些優(yōu)點(diǎn)呢
見上一篇
2. 你剛剛提到了持久化,能重點(diǎn)介紹一下么
見上一篇
3.Redis中對于IO的控制做過什么優(yōu)化?
pipeline?
4 有沒有嘗試進(jìn)行多機(jī)redis 的部署?如何保證數(shù)據(jù)一致的?
主從復(fù)制,讀寫分離
1、redis的復(fù)制功能是支持多個數(shù)據(jù)庫之間的數(shù)據(jù)同步。一類是主數(shù)據(jù)庫(master)一類是從數(shù)據(jù)庫(slave),主數(shù)據(jù)庫可以進(jìn)行讀寫操作,當(dāng)發(fā)生寫操作的時候自動將數(shù)據(jù)同步到從數(shù)據(jù)庫,而從數(shù)據(jù)庫一般是只讀的,并接收主數(shù)據(jù)庫同步過來的數(shù)據(jù),一個主數(shù)據(jù)庫可以有多個從數(shù)據(jù)庫,而一個從數(shù)據(jù)庫只能有一個主數(shù)據(jù)庫。
2、通過redis的復(fù)制功能可以很好的實(shí)現(xiàn)數(shù)據(jù)庫的讀寫分離,提高服務(wù)器的負(fù)載能力。主數(shù)據(jù)庫主要進(jìn)行寫操作,而從數(shù)據(jù)庫負(fù)責(zé)讀操作。
1:當(dāng)一個從數(shù)據(jù)庫啟動時,會向主數(shù)據(jù)庫發(fā)送sync命令,
2:主數(shù)據(jù)庫接收到sync命令后會開始在后臺保存快照(執(zhí)行rdb操作),并將保存期間接收到的命令緩存起來
3:當(dāng)快照完成后,redis會將快照文件和所有緩存的命令發(fā)送給從數(shù)據(jù)庫。
4:從數(shù)據(jù)庫收到后,會載入快照文件并執(zhí)行收到的緩存的命令。
5. 我們把數(shù)存到redis的一個節(jié)點(diǎn),在另一個節(jié)點(diǎn)卻能查詢到,這是怎么實(shí)現(xiàn)的呢
主從復(fù)制?
6. 說一下強(qiáng)一致性和最終一致性
一致性又可以分為強(qiáng)一致性與弱一致性。
強(qiáng)一致性可以理解為在任意時刻,所有節(jié)點(diǎn)中的數(shù)據(jù)是一樣的。同一時間點(diǎn),你在節(jié)點(diǎn)A中獲取到key1的值與在節(jié)點(diǎn)B中獲取到key1的值應(yīng)該都是一樣的。
弱一致性包含很多種不同的實(shí)現(xiàn),目前分布式系統(tǒng)中廣泛實(shí)現(xiàn)的是最終一致性。
所謂最終一致性,就是不保證在任意時刻任意節(jié)點(diǎn)上的同一份數(shù)據(jù)都是相同的,但是隨著時間的遷移,不同節(jié)點(diǎn)上的同一份數(shù)據(jù)總是在向趨同的方向變化。也可以簡單的理解為在一段時間后,節(jié)點(diǎn)間的數(shù)據(jù)會最終達(dá)到一致狀態(tài)。
對于最終一致性最好的例子就是DNS系統(tǒng),由于DNS多級緩存的實(shí)現(xiàn),所以修改DNS記錄后不會在全球所有DNS服務(wù)節(jié)點(diǎn)生效,需要等待DNS服務(wù)器緩存過期后向源服務(wù)器更新新的記錄才能實(shí)現(xiàn)。
類似的,還有一些其它的弱一致性實(shí)現(xiàn),下面摘自《NoSQL數(shù)據(jù)庫筆談》https://docs.google.com/View?id=dc23x53c_64db5px4f6
Causal consistency(因果一致性)
7. Redis用的什么協(xié)議
Redis從1.2版本開始,設(shè)計(jì)了一套統(tǒng)一的協(xié)議格式,作者講到自己設(shè)計(jì)的協(xié)議在下面幾個方面進(jìn)行了權(quán)衡:
容易讓人閱讀
如果我們需要自己實(shí)現(xiàn)一個Redis客戶端程序,有必要了解一下Redis的協(xié)議格式。在網(wǎng)絡(luò)層面,客戶端通過TCP連接到Redis服務(wù)器(默認(rèn)端口6379,可以通過配置文件修改),客戶端與服務(wù)器之間發(fā)送的命令以\r\n(CR LF)結(jié)尾。
https://blog.csdn.net/hu2010shuai/article/details/52946116
8.對于大量的請求怎么樣處理
redis是一個單線程程序,也就說同一時刻它只能處理一個客戶端請求;
redis是通過IO多路復(fù)用(select,epoll, kqueue,依據(jù)不同的平臺,采取不同的實(shí)現(xiàn))來處理多個客戶端請求的,偽代碼:
9.怎么樣設(shè)計(jì)調(diào)度算法
10.兩個文件,上億個URL怎么樣找出重復(fù)的。
題目描述:給A,B兩個文件,各存放50億條URL,每條URL占用64個字節(jié),內(nèi)存限制為4G,找出A,B中相同的URL。
分析:我們先來看如果要把這些URL全部加載到內(nèi)存中,需要多大的空間。
1MB = 2^20 = 10^6 = 100W
1GB = 2^30 = 10^9 = 10億
50億 = 5G * 64 Byte = 320G
明顯是不可能全部加載到內(nèi)存中的。我們可采用以下方法解決:
方法1:
采用Bloom filter,假設(shè)布隆過濾器的錯誤率為0.01,則位數(shù)組大小m約為輸入元素個數(shù)n的13倍,此時需要的哈希函數(shù)k約為8個。
元素個數(shù):n = 5G
位數(shù)組大小:m = 5G * 13 = 65G = 650億 即需要650億個bit位才能達(dá)到錯誤率0.01
而我們擁有的內(nèi)存可容納bit位個數(shù):4G * 8bit = 32G bit = 320億,按此實(shí)現(xiàn)錯誤率大于0.01。
方法2:
分別掃描A,B兩個文件,根據(jù)hash(url)%k(k為正整數(shù),比如k = 1000,那么每個小文件只占用300M,內(nèi)存完全可以放得下)將url劃分到不同的k個文件中,比如a0,a1,....a999;b0,b1,...b999;這樣處理后相同的url肯定在對應(yīng)的小文件中(a0 vs b0,a1 vs b1,...a999 vs b999)因?yàn)橄嗤膗rl%1000的值肯定相同,不對應(yīng)的小文件不可能有相同的url;然后我們只要求出1000對小文件中相同的url即可。比如對于a0 vs b0,我們可以遍歷a0,將其中的url存放到hash_map中,然后遍歷b0,如果b0中的某個url在hash_map中,則說明此url在a和b中同時存在,保存下來即可。
http://www.360doc.com/content/16/0331/22/16915_546938410.shtml
11.聊聊 Redis 使用場景
見上一篇
以下三個集群的問題完全不懂
12.Redis 集群方案與實(shí)現(xiàn)
https://www.cnblogs.com/kerwinC/p/6611634.html
https://www.cnblogs.com/me115/p/9043420.html#h21
https://blog.csdn.net/u010963948/article/details/78963572
13.問我Redis怎么做集群,答了主從哨兵和cluster。
14.redis3.0原生集群和redis讀寫分離+哨兵機(jī)制區(qū)別
https://blog.csdn.net/keketrtr/article/details/78802571
15.Redis 為什么是單線程的
官方FAQ表示,因?yàn)镽edis是基于內(nèi)存的操作,CPU不是Redis的瓶頸,Redis的瓶頸最有可能是機(jī)器內(nèi)存的大小或者網(wǎng)絡(luò)帶寬。既然單線程容易實(shí)現(xiàn),而且CPU不會成為瓶頸,那就順理成章地采用單線程的方案了(畢竟采用多線程會有很多麻煩!)
Redis總體快速的原因:
采用隊(duì)列模式將并發(fā)訪問變?yōu)榇性L問(?)
單線程指的是網(wǎng)絡(luò)請求模塊使用了一個線程(所以不需考慮并發(fā)安全性),其他模塊仍用了多個線程。
總體來說快速的原因如下:
1)絕大部分請求是純粹的內(nèi)存操作(非常快速)
2)采用單線程,避免了不必要的上下文切換和競爭條件
3)非阻塞IO
內(nèi)部實(shí)現(xiàn)采用epoll,采用了epoll+自己實(shí)現(xiàn)的簡單的事件框架。epoll中的讀、寫、關(guān)閉、連接都轉(zhuǎn)化成了事件,然后利用epoll的多路復(fù)用特性,絕不在io上浪費(fèi)一點(diǎn)時間
這3個條件不是相互獨(dú)立的,特別是第一條,如果請求都是耗時的,采用單線程吞吐量及性能可想而知了。應(yīng)該說redis為特殊的場景選擇了合適的技術(shù)方案。
16.緩存崩潰
見上一篇緩存雪崩
17.緩存降級
https://www.cnblogs.com/leeSmall/p/8594542.html
18.使用緩存的合理性問題
熱點(diǎn)數(shù)據(jù)
對于冷數(shù)據(jù)而言,讀取頻率低,大部分?jǐn)?shù)據(jù)可能還沒有再次訪問到就已經(jīng)被擠出內(nèi)存,不僅占用內(nèi)存,而且價值不大。
對于熱點(diǎn)數(shù)據(jù),讀取頻率高。如果不做緩存,給數(shù)據(jù)庫造成很大的壓力,可能被擊穿。
修改頻率
數(shù)據(jù)更新前至少讀取兩次,緩存才有意義。這個是最基本的策略,如果緩存還沒有起作用就失效了,那就沒有太大價值了。(讀取頻率>修改頻率)
如果這個讀取接口對數(shù)據(jù)庫的壓力很大,但是又是熱點(diǎn)數(shù)據(jù),這個時候就需要考慮通過緩存手段,減少數(shù)據(jù)庫的壓力,比如我們的某助手產(chǎn)品的,點(diǎn)贊數(shù),收藏數(shù),分享數(shù)等是非常典型的熱點(diǎn)數(shù)據(jù),但是又不斷變化,此時就需要將數(shù)據(jù)同步保存到Redis緩存,減少數(shù)據(jù)庫壓力
緩存更新機(jī)制
一般情況下,我們采取緩存雙淘汰機(jī)制,在更新數(shù)據(jù)庫的時候淘汰緩存。此外,設(shè)定超時時間,例如30分鐘。極限場景下,即使有臟數(shù)據(jù)入cache,這個臟數(shù)據(jù)也最多存在三十分鐘。
在高并發(fā)的情況下,設(shè)計(jì)上最好避免查詢Mysql,所以在更新數(shù)據(jù)庫的時候更新緩存。
緩存可用性
緩存是提高數(shù)據(jù)讀取性能的,緩存數(shù)據(jù)丟失和緩存不可用不會影響應(yīng)用程序的處理。因此,一般的操作手段是,如果Redis出現(xiàn)異常,我們手動捕獲這個異常,記錄日志,并且去數(shù)據(jù)庫查詢數(shù)據(jù)返回給用戶。
服務(wù)降級
服務(wù)降級的目的,是為了防止Redis服務(wù)故障,導(dǎo)致數(shù)據(jù)庫跟著一起發(fā)生雪崩問題。因此,對于不重要的緩存數(shù)據(jù),可以采取服務(wù)降級策略,例如一個比較常見的做法就是,Redis出現(xiàn)問題,不去數(shù)據(jù)庫查詢,而是直接返回默認(rèn)值給用戶。
轉(zhuǎn)載于:https://www.cnblogs.com/dudu19939/p/9477407.html
總結(jié)
以上是生活随笔為你收集整理的redis面试问题(二)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。