redis面試問題(二)
10-07
redis面試問題(二)
(CR LF)結尾。
推薦閱讀:
來自專欄學習編程45 人贊了文章
作者:構造函數
鏈接:https://www.nowcoder.com/discuss/92611來源:牛客網上一篇:https://www.nowcoder.com/discuss/926101.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_64db5px4f6Causal consistency(因果一致性)7. Redis用的什麼協議Redis從1.2版本開始,設計了一套統一的協議格式,作者講到自己設計的協議在下面幾個方面進行了權衡: 1. 實現簡單 2. 快速通過計算機解析 3. 容易讓人閱讀如果我們需要自己實現一個Redis客戶端程序,有必要了解一下Redis的協議格式。在網路層面,客戶端通過TCP連接到Redis伺服器(默認埠6379,可以通過配置文件修改),客戶端與伺服器之間發送的命令以(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 = 100W1GB = 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.shtml11.聊聊 Redis 使用場景
見上一篇==================以下三個集群的問題完全不懂12.Redis 集群方案與實現https://www.cnblogs.com/kerwinC/p/6611634.htmlhttps://www.cnblogs.com/me115/p/9043420.html#h21https://blog.csdn.net/u010963948/article/details/7896357213.問我Redis怎麼做集群,答了主從哨兵和cluster。14.redis3.0原生集群和redis讀寫分離+哨兵機制區別
https://blog.csdn.net/keketrtr/article/details/7880257115.Redis 為什麼是單線程的官方FAQ表示,因為Redis是基於內存的操作,CPU不是Redis的瓶頸,Redis的瓶頸最有可能是機器內存的大小或者網路帶寬。既然單線程容易實現,而且CPU不會成為瓶頸,那就順理成章地採用單線程的方案了(畢竟採用多線程會有很多麻煩!)Redis總體快速的原因:採用隊列模式將並發訪問變為串列訪問(?)單線程指的是網路請求模塊使用了一個線程(所以不需考慮並發安全性),其他模塊仍用了多個線程。總體來說快速的原因如下:1)絕大部分請求是純粹的內存操作(非常快速)2)採用單線程,避免了不必要的上下文切換和競爭條件3)非阻塞IO
內部實現採用epoll,採用了epoll+自己實現的簡單的事件框架。epoll中的讀、寫、關閉、連接都轉化成了事件,然後利用epoll的多路復用特性,絕不在io上浪費一點時間這3個條件不是相互獨立的,特別是第一條,如果請求都是耗時的,採用單線程吞吐量及性能可想而知了。應該說redis為特殊的場景選擇了合適的技術方案。16.緩存崩潰見上一篇緩存雪崩17.緩存降級https://www.cnblogs.com/leeSmall/p/8594542.html18.使用緩存的合理性問題熱點數據對於冷數據而言,讀取頻率低,大部分數據可能還沒有再次訪問到就已經被擠出內存,不僅佔用內存,而且價值不大。對於熱點數據,讀取頻率高。如果不做緩存,給資料庫造成很大的壓力,可能被擊穿。
修改頻率數據更新前至少讀取兩次,緩存才有意義。這個是最基本的策略,如果緩存還沒有起作用就失效了,那就沒有太大價值了。(讀取頻率>修改頻率)如果這個讀取介面對資料庫的壓力很大,但是又是熱點數據,這個時候就需要考慮通過緩存手段,減少資料庫的壓力,比如我們的某助手產品的,點贊數,收藏數,分享數等是非常典型的熱點數據,但是又不斷變化,此時就需要將數據同步保存到Redis緩存,減少資料庫壓力緩存更新機制一般情況下,我們採取緩存雙淘汰機制,在更新資料庫的時候淘汰緩存。此外,設定超時時間,例如30分鐘。極限場景下,即使有臟數據入cache,這個臟數據也最多存在三十分鐘。在高並發的情況下,設計上最好避免查詢Mysql,所以在更新資料庫的時候更新緩存。緩存可用性緩存是提高數據讀取性能的,緩存數據丟失和緩存不可用不會影響應用程序的處理。因此,一般的操作手段是,如果Redis出現異常,我們手動捕獲這個異常,記錄日誌,並且去資料庫查詢數據返回給用戶。服務降級服務降級的目的,是為了防止Redis服務故障,導致資料庫跟著一起發生雪崩問題。因此,對於不重要的緩存數據,可以採取服務降級策略,例如一個比較常見的做法就是,Redis出現問題,不去資料庫查詢,而是直接返回默認值給用戶。與作者交流:https://www.nowcoder.com/discuss/92611
更多筆經面經:https://www.nowcoder.com/discuss?type=2&order=0
推薦閱讀: