redis面试问题(二)
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數據庫筆談》https://docs.google.com/View?id=dc23x53c_64db5px4f6
Causal consistency(因果一致性)
7. Redis用的什么協議
Redis從1.2版本開始,設計了一套統一的協議格式,作者講到自己設計的協議在下面幾個方面進行了權衡:
容易讓人閱讀
如果我們需要自己實現一個Redis客戶端程序,有必要了解一下Redis的協議格式。在網絡層面,客戶端通過TCP連接到Redis服務器(默認端口6379,可以通過配置文件修改),客戶端與服務器之間發送的命令以\r\n(CR LF)結尾。
https://blog.csdn.net/hu2010shuai/article/details/52946116
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中同時存在,保存下來即可。
http://www.360doc.com/content/16/0331/22/16915_546938410.shtml
11.聊聊 Redis 使用場景
見上一篇
以下三個集群的問題完全不懂
12.Redis 集群方案與實現
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讀寫分離+哨兵機制區別
https://blog.csdn.net/keketrtr/article/details/78802571
15.Redis 為什么是單線程的
官方FAQ表示,因為Redis是基于內存的操作,CPU不是Redis的瓶頸,Redis的瓶頸最有可能是機器內存的大小或者網絡帶寬。既然單線程容易實現,而且CPU不會成為瓶頸,那就順理成章地采用單線程的方案了(畢竟采用多線程會有很多麻煩!)
Redis總體快速的原因:
采用隊列模式將并發訪問變為串行訪問(?)
單線程指的是網絡請求模塊使用了一個線程(所以不需考慮并發安全性),其他模塊仍用了多個線程。
總體來說快速的原因如下:
1)絕大部分請求是純粹的內存操作(非??焖?#xff09;
2)采用單線程,避免了不必要的上下文切換和競爭條件
3)非阻塞IO
內部實現采用epoll,采用了epoll+自己實現的簡單的事件框架。epoll中的讀、寫、關閉、連接都轉化成了事件,然后利用epoll的多路復用特性,絕不在io上浪費一點時間
這3個條件不是相互獨立的,特別是第一條,如果請求都是耗時的,采用單線程吞吐量及性能可想而知了。應該說redis為特殊的場景選擇了合適的技術方案。
16.緩存崩潰
見上一篇緩存雪崩
17.緩存降級
https://www.cnblogs.com/leeSmall/p/8594542.html
18.使用緩存的合理性問題
熱點數據
對于冷數據而言,讀取頻率低,大部分數據可能還沒有再次訪問到就已經被擠出內存,不僅占用內存,而且價值不大。
對于熱點數據,讀取頻率高。如果不做緩存,給數據庫造成很大的壓力,可能被擊穿。
修改頻率
數據更新前至少讀取兩次,緩存才有意義。這個是最基本的策略,如果緩存還沒有起作用就失效了,那就沒有太大價值了。(讀取頻率>修改頻率)
如果這個讀取接口對數據庫的壓力很大,但是又是熱點數據,這個時候就需要考慮通過緩存手段,減少數據庫的壓力,比如我們的某助手產品的,點贊數,收藏數,分享數等是非常典型的熱點數據,但是又不斷變化,此時就需要將數據同步保存到Redis緩存,減少數據庫壓力
緩存更新機制
一般情況下,我們采取緩存雙淘汰機制,在更新數據庫的時候淘汰緩存。此外,設定超時時間,例如30分鐘。極限場景下,即使有臟數據入cache,這個臟數據也最多存在三十分鐘。
在高并發的情況下,設計上最好避免查詢Mysql,所以在更新數據庫的時候更新緩存。
緩存可用性
緩存是提高數據讀取性能的,緩存數據丟失和緩存不可用不會影響應用程序的處理。因此,一般的操作手段是,如果Redis出現異常,我們手動捕獲這個異常,記錄日志,并且去數據庫查詢數據返回給用戶。
服務降級
服務降級的目的,是為了防止Redis服務故障,導致數據庫跟著一起發生雪崩問題。因此,對于不重要的緩存數據,可以采取服務降級策略,例如一個比較常見的做法就是,Redis出現問題,不去數據庫查詢,而是直接返回默認值給用戶。
轉載于:https://www.cnblogs.com/dudu19939/p/9477407.html
總結
以上是生活随笔為你收集整理的redis面试问题(二)的全部內容,希望文章能夠幫你解決所遇到的問題。