redis面試問題(二)

redis面試問題(二)

來自專欄學習編程45 人贊了文章

作者:構造函數

鏈接:nowcoder.com/discuss/92

來源:牛客網

上一篇:nowcoder.com/discuss/92

1.redis和其他緩存相比有哪些優點呢

見上一篇

2. 你剛剛提到了持久化,能重點介紹一下么

見上一篇

3.Redis中對於IO的控制做過什麼優化?

pipeline?

4 有沒有嘗試進行多機redis 的部署?如何保證數據一致的?

主從複製,讀寫分離

1、redis的複製功能是支持多個資料庫之間的數據同步。一類是主資料庫(master)一類是從資料庫(slave),主資料庫可以進行讀寫操作,當發生寫操作的時候自動將數據同步到從資料庫,而從資料庫一般是只讀的,並接收主資料庫同步過來的數據,一個主資料庫可以有多個從資料庫,而一個從資料庫只能有一個主資料庫。

2、通過redis的複製功能可以很好的實現資料庫的讀寫分離,提高伺服器的負載能力。主資料庫主要進行寫操作,而從資料庫負責讀操作。

1:當一個從資料庫啟動時,會向主資料庫發送sync命令,

2:主資料庫接收到sync命令後會開始在後台保存快照(執行rdb操作),並將保存期間接收到的命令緩存起來

3:當快照完成後,redis會將快照文件和所有緩存的命令發送給從資料庫。

4:從資料庫收到後,會載入快照文件並執行收到的緩存的命令。

5. 我們把數存到redis的一個節點,在另一個節點卻能查詢到,這是怎麼實現的呢

主從複製?

6. 說一下強一致性和最終一致性

一致性又可以分為強一致性與弱一致性。

強一致性可以理解為在任意時刻,所有節點中的數據是一樣的。同一時間點,你在節點A中獲取到key1的值與在節點B中獲取到key1的值應該都是一樣的。

弱一致性包含很多種不同的實現,目前分散式系統中廣泛實現的是最終一致性。

所謂最終一致性,就是不保證在任意時刻任意節點上的同一份數據都是相同的,但是隨著時間的遷移,不同節點上的同一份數據總是在向趨同的方向變化。也可以簡單的理解為在一段時間後,節點間的數據會最終達到一致狀態。

對於最終一致性最好的例子就是DNS系統,由於DNS多級緩存的實現,所以修改DNS記錄後不會在全球所有DNS服務節點生效,需要等待DNS伺服器緩存過期後向源伺服器更新新的記錄才能實現。

類似的,還有一些其它的弱一致性實現,下面摘自《NoSQL資料庫筆談》docs.google.com/View?

Causal consistency(因果一致性)

7. Redis用的什麼協議

Redis從1.2版本開始,設計了一套統一的協議格式,作者講到自己設計的協議在下面幾個方面進行了權衡:

1. 實現簡單

2. 快速通過計算機解析

3. 容易讓人閱讀

如果我們需要自己實現一個Redis客戶端程序,有必要了解一下Redis的協議格式。在網路層面,客戶端通過TCP連接到Redis伺服器(默認埠6379,可以通過配置文件修改),客戶端與伺服器之間發送的命令以
(CR LF)結尾。

blog.csdn.net/hu2010shu

8.對於大量的請求怎麼樣處理

redis是一個單線程程序,也就說同一時刻它只能處理一個客戶端請求;

redis是通過IO多路復用(select,epoll, kqueue,依據不同的平台,採取不同的實現)來處理多個客戶端請求的,偽代碼:

9.怎麼樣設計調度演算法

10.兩個文件,上億個URL怎麼樣找出重複的。

題目描述:給A,B兩個文件,各存放50億條URL,每條URL佔用64個位元組,內存限制為4G,找出A,B中相同的URL。

分析:我們先來看如果要把這些URL全部載入到內存中,需要多大的空間。

1MB = 2^20 = 10^6 = 100W

1GB = 2^30 = 10^9 = 10億

50億 = 5G * 64 Byte = 320G

明顯是不可能全部載入到內存中的。我們可採用以下方法解決:

方法1:

採用Bloom filter,假設布隆過濾器的錯誤率為0.01,則位數組大小m約為輸入元素個數n的13倍,此時需要的哈希函數k約為8個。

元素個數:n = 5G

位數組大小:m = 5G * 13 = 65G = 650億 即需要650億個bit位才能達到錯誤率0.01

而我們擁有的內存可容納bit位個數:4G * 8bit = 32G bit = 320億,按此實現錯誤率大於0.01。

方法2:

分別掃描A,B兩個文件,根據hash(url)%k(k為正整數,比如k = 1000,那麼每個小文件只佔用300M,內存完全可以放得下)將url劃分到不同的k個文件中,比如a0,a1,....a999;b0,b1,...b999;這樣處理後相同的url肯定在對應的小文件中(a0 vs b0,a1 vs b1,...a999 vs b999)因為相同的url%1000的值肯定相同,不對應的小文件不可能有相同的url;然後我們只要求出1000對小文件中相同的url即可。比如對於a0 vs b0,我們可以遍歷a0,將其中的url存放到hash_map中,然後遍歷b0,如果b0中的某個url在hash_map中,則說明此url在a和b中同時存在,保存下來即可。

360doc.com/content/16/0

11.聊聊 Redis 使用場景

見上一篇

==================

以下三個集群的問題完全不懂

12.Redis 集群方案與實現

cnblogs.com/kerwinC/p/6

cnblogs.com/me115/p/904

blog.csdn.net/u01096394

13.問我Redis怎麼做集群,答了主從哨兵和cluster。

14.redis3.0原生集群和redis讀寫分離+哨兵機制區別

blog.csdn.net/keketrtr/

15.Redis 為什麼是單線程的

官方FAQ表示,因為Redis是基於內存的操作,CPU不是Redis的瓶頸,Redis的瓶頸最有可能是機器內存的大小或者網路帶寬。既然單線程容易實現,而且CPU不會成為瓶頸,那就順理成章地採用單線程的方案了(畢竟採用多線程會有很多麻煩!)

Redis總體快速的原因:

採用隊列模式將並發訪問變為串列訪問(?)

單線程指的是網路請求模塊使用了一個線程(所以不需考慮並發安全性),其他模塊仍用了多個線程。

總體來說快速的原因如下:

1)絕大部分請求是純粹的內存操作(非常快速)

2)採用單線程,避免了不必要的上下文切換和競爭條件

3)非阻塞IO

內部實現採用epoll,採用了epoll+自己實現的簡單的事件框架。epoll中的讀、寫、關閉、連接都轉化成了事件,然後利用epoll的多路復用特性,絕不在io上浪費一點時間

這3個條件不是相互獨立的,特別是第一條,如果請求都是耗時的,採用單線程吞吐量及性能可想而知了。應該說redis為特殊的場景選擇了合適的技術方案。

16.緩存崩潰

見上一篇緩存雪崩

17.緩存降級

cnblogs.com/leeSmall/p/

18.使用緩存的合理性問題

熱點數據

對於冷數據而言,讀取頻率低,大部分數據可能還沒有再次訪問到就已經被擠出內存,不僅佔用內存,而且價值不大。

對於熱點數據,讀取頻率高。如果不做緩存,給資料庫造成很大的壓力,可能被擊穿。

修改頻率

數據更新前至少讀取兩次,緩存才有意義。這個是最基本的策略,如果緩存還沒有起作用就失效了,那就沒有太大價值了。(讀取頻率>修改頻率)

如果這個讀取介面對資料庫的壓力很大,但是又是熱點數據,這個時候就需要考慮通過緩存手段,減少資料庫的壓力,比如我們的某助手產品的,點贊數,收藏數,分享數等是非常典型的熱點數據,但是又不斷變化,此時就需要將數據同步保存到Redis緩存,減少資料庫壓力

緩存更新機制

一般情況下,我們採取緩存雙淘汰機制,在更新資料庫的時候淘汰緩存。此外,設定超時時間,例如30分鐘。極限場景下,即使有臟數據入cache,這個臟數據也最多存在三十分鐘。

在高並發的情況下,設計上最好避免查詢Mysql,所以在更新資料庫的時候更新緩存。

緩存可用性

緩存是提高數據讀取性能的,緩存數據丟失和緩存不可用不會影響應用程序的處理。因此,一般的操作手段是,如果Redis出現異常,我們手動捕獲這個異常,記錄日誌,並且去資料庫查詢數據返回給用戶。

服務降級

服務降級的目的,是為了防止Redis服務故障,導致資料庫跟著一起發生雪崩問題。因此,對於不重要的緩存數據,可以採取服務降級策略,例如一個比較常見的做法就是,Redis出現問題,不去資料庫查詢,而是直接返回默認值給用戶。

與作者交流:nowcoder.com/discuss/92

更多筆經面經:nowcoder.com/discuss?


推薦閱讀:

TAG:Redis | 計算機科學 | 面試 |