你知道的越多,你不知道的越多java
點贊再看,養成習慣node
Redis在互聯網技術存儲方面使用如此普遍,幾乎全部的後端技術面試官都要在Redis的使用和原理方面對小夥伴們進行360°的刁難。做爲一個在互聯網公司面一次拿一次offer的麪霸(請容許我使用一下誇張的修辭手法),戰勝了無數競爭對手,每次都只能看到無數落寞的身影失望的離開,略感愧疚,在一個寂寞難耐的夜晚,我痛定思痛,決定開始寫《吊打面試官》系列,但願能幫助各位讀者之後面試勢如破竹,對面試官進行360°的反擊,吊打問你的面試官,讓一同面試的同僚瞠目結舌,瘋狂收割大廠Offer!git
寫這期其實比較糾結,我以前的寫的比較通俗易懂,一是我都知道這些點,二是以前我在所在的電商公司對雪崩,擊穿啥的還算有場景去接觸。可是線上的Redis集羣我實際操做經驗不多,總不能在公司線上環境實踐那些操做吧,因此最後看了下官網,還有一些資料(文章後面我都會貼出來),強行懟了這麼篇出來。github
最近雙十一小忙,週末雙十一值班目測沒時間寫,那我是暖男呀,我不能鴿啊,就有了這一篇,下一篇遲到大家不要噴我哈,並且下一篇仍是Redis的終章仍是得構思下,不熟悉的知識點我怕漏洞多,特地讓之前的大牛同事看了下,因此有啥不對的地方你們及時留言Diss我,寫這篇是真的難,諾下面就是我本人某天凌晨兩點的拍的視頻,多動症的仔。面試
(手機上動圖可能太大加載失敗,點進去這裏能夠看看這個圖)redis
以前說過系列第二篇到300讚我就發第三篇算法
咋樣沒騙大家吧,就很枯竭,不BB了,開搞。sql
不點個贊對不起我,此次不要白嫖我!數據庫
上幾期《吊打面試官》還沒看的小夥伴能夠回顧一下(明明就寫了兩期說的好像不少同樣)!後端
你們都知道一個技術的引入方便了開發,解決了各類問題,可是也會帶來對應的問題,技術是把雙刃劍嘛,集羣的引入也會帶來不少問題,如:集羣的高可用怎麼保證,數據怎麼同步等等,咱們話很少說,有請下一位受害者爲咱們展現。
三個大腹便便,穿着格子襯衣的中年男子,拿着三個盡是劃痕的mac向你走來,看着快禿頂的頭髮,心想着確定是尼瑪頂級架構師吧!並且仍是三個,可是還好我看過敖丙寫的《吊打面試官》系列,腹有詩書氣自華,根本虛都不虛好伐。
哦,帥氣迷人的面試官您好,咱們能夠先看一下關係型數據庫跟Redis本質上的區別。
Redis採用的是基於內存的採用的是單進程單線程模型的 KV 數據庫,由C語言編寫,官方提供的數據是能夠達到100000+的QPS(每秒內查詢次數)。
徹底基於內存,絕大部分請求是純粹的內存操做,很是快速。它的,數據存在內存中,相似於HashMap,HashMap的優點就是查找和操做的時間複雜度都是O(1);
數據結構簡單,對數據操做也簡單,Redis中的數據結構是專門進行設計的;
採用單線程,避免了沒必要要的上下文切換和競爭條件,也不存在多進程或者多線程致使的切換而消耗 CPU,不用去考慮各類鎖的問題,不存在加鎖釋放鎖操做,沒有由於可能出現死鎖而致使的性能消耗;
使用多路I/O複用模型,非阻塞IO;
使用底層模型不一樣,它們之間底層實現方式以及與客戶端之間通訊的應用協議不同,Redis直接本身構建了VM 機制 ,由於通常的系統調用系統函數的話,會浪費必定的時間去移動和請求;
我能夠打個比方麼:我記得有過一個小夥伴微信問過我上下文切換是啥,爲啥可能會線程不安全,我是這麼說的,就比如你看一本英文書,你看到第十頁發現有個單詞不會讀,你加了個書籤,而後去查字典,過了一會你又回來繼續從書籤那裏讀,ok到目前爲止沒啥問題。
若是是你一我的讀確定沒啥問題,可是你去查的時候,別的小夥伴好奇你在看啥他就翻了一下你的書,而後溜了,哦豁,你再看的時候就發現書不是你看的那一頁了。不知道到這裏爲止我有沒有解釋清楚,以及爲啥會線程不安全,就是由於你一我的怎麼看都沒事,可是人多了換來換去的操做一本書數據就亂了。可能個人解釋很粗糙,可是道理應該是同樣的。
是的他是單線程的,可是,咱們能夠經過在單機開多個Redis實例嘛。
咱們用到了集羣的部署方式也就是Redis cluster,而且是主從同步讀寫分離,相似Mysql的主從同步,Redis cluster 支撐 N 個 Redis master node,每一個master node均可以掛載多個 slave node。
這樣整個 Redis 就能夠橫向擴容了。若是你要支撐更大數據量的緩存,那就橫向擴容更多的 master 節點,每一個 master 節點就能存放更多的數據了。
是的,持久化的話是Redis高可用中比較重要的一個環節,由於Redis數據在內存的特性,持久化必須得有,我瞭解到的持久化是有兩種方式的。
兩種方式均可以把Redis內存中的數據持久化到磁盤上,而後再將這些數據備份到別的地方去,RDB更適合作冷備,AOF更適合作熱備,好比我杭州的某電商公司有這兩個數據,我備份一份到我杭州的節點,再備份一個到上海的,就算髮生沒法避免的天然災害,也不會兩個地方都一塊兒掛吧,這災備也就是異地容災,地球毀滅他沒辦法。
tip:兩種機制所有開啓的時候,Redis在重啓的時候會默認使用AOF去從新構建數據,由於AOF的數據是比RDB更完整的。
我先說RDB吧
他會生成多個數據文件,每一個數據文件分別都表明了某一時刻Redis裏面的數據,這種方式,有沒有以爲很適合作冷備,完整的數據運維設置定時任務,定時同步到遠端的服務器,好比阿里的雲服務,這樣一旦線上掛了,你想恢復多少分鐘以前的數據,就去遠端拷貝一份以前的數據就行了。
RDB對Redis的性能影響很是小,是由於在同步數據的時候他只是fork了一個子進程去作持久化的,並且他在數據恢復的時候速度比AOF來的快。
RDB都是快照文件,都是默認五分鐘甚至更久的時間纔會生成一次,這意味着你此次同步到下次同步這中間五分鐘的數據都極可能所有丟失掉。AOF則最多丟一秒的數據,數據完整性上高下立判。
還有就是RDB在生成數據快照的時候,若是文件很大,客戶端可能會暫停幾毫秒甚至幾秒,你公司在作秒殺的時候他恰好在這個時候fork了一個子進程去生成一個大快照,哦豁,出大問題。
咱們再來講說AOF
上面提到了,RDB五分鐘一次生成快照,可是AOF是一秒一次去經過一個後臺的線程fsync
操做,那最多丟這一秒的數據。
AOF在對日誌文件進行操做的時候是以append-only
的方式去寫的,他只是追加的方式寫數據,天然就少了不少磁盤尋址的開銷了,寫入性能驚人,文件也不容易破損。
AOF的日誌是經過一個叫很是可讀的方式記錄的,這樣的特性就適合作災難性數據誤刪除的緊急恢復了,好比公司的實習生經過flushall清空了全部的數據,只要這個時候後臺重寫還沒發生,你立刻拷貝一份AOF日誌文件,把最後一條flushall命令刪了就完事了。
tip:我說的命令大家別真去線上系統操做啊,想試去本身買的服務器上裝個Redis試,別到時候來講,敖丙真是個渣男,害我把服務器搞崩了,Redis官網上的命令都去看看,不要亂試!!!
同樣的數據,AOF文件比RDB還要大。
AOF開啓後,Redis支持寫的QPS會比RDB支持寫的要低,他不是每秒都要去異步刷新一第二天志嘛fsync,固然即便這樣性能仍是很高,我記得ElasticSearch也是這樣的,異步刷新緩存區的數據去持久化,爲啥這麼作呢,不直接來一條懟一條呢,那我會告訴你這樣性能可能低到沒辦法用的,你們能夠思考下爲啥喲。
小孩子才作選擇,我全都要,你單獨用RDB你會丟失不少數據,你單獨用AOF,你數據恢復沒RDB來的快,真出何時第一時間用RDB恢復,而後AOF作數據補全,真香!冷備熱備一塊兒上,纔是互聯網時代一個高健壯性系統的王道。
!!!暈 本身給本身埋個坑(實際上是明早就準備好了,故意拋出這個詞等他問,就怕他不問)。
僞裝思考一會(不要過久,省得覺得你真的不會),哦我想起來了,還有哨兵集羣sentinel。
哨兵必須用三個實例去保證本身的健壯性的,哨兵+主從並不能保證數據不丟失,可是能夠保證集羣的高可用。
爲啥必需要三個實例呢?咱們先看看兩個哨兵會咋樣。
master宕機了 s1和s2兩個哨兵只要有一個認爲你宕機了就切換了,而且會選舉出一個哨兵去執行故障,可是這個時候也須要大多數哨兵都是運行的。
那這樣有啥問題呢?M1宕機了,S1沒掛那實際上是OK的,可是整個機器都掛了呢?哨兵就只剩下S2個裸屌了,沒有哨兵去容許故障轉移了,雖然另一個機器上還有R1,可是故障轉移就是不執行。
經典的哨兵集羣是這樣的:
M1所在的機器掛了,哨兵還有兩個,兩我的一看他不是掛了嘛,那咱們就選舉一個出來執行故障轉移不就行了。
暖男我,小的總結下哨兵組件的主要功能:
集羣監控:負責監控 Redis master 和 slave 進程是否正常工做。
消息通知:若是某個 Redis 實例有故障,那麼哨兵負責發送消息做爲報警通知給管理員。
故障轉移:若是 master node 掛掉了,會自動轉移到 slave node 上。
配置中心:若是故障轉移發生了,通知 client 客戶端新的 master 地址。
面試官您的記性可真是一級棒呢,我都要忘了你還記得,我特麼謝謝你,提到這個,就跟我前面提到的數據持久化的RDB和AOF有着比密切的關係了。
我先說下爲啥要用主從這樣的架構模式,前面提到了單機QPS是有上限的,並且Redis的特性就是必須支撐讀高併發的,那你一臺機器又讀又寫,這誰頂得住啊,不當人啊!可是你讓這個master機器去寫,數據同步給別的slave機器,他們都拿去讀,分發掉大量的請求那是否是好不少,並且擴容的時候還能夠輕鬆實現水平擴容。
迴歸正題,他們數據怎麼同步的呢?
你啓動一臺slave 的時候,他會發送一個psync命令給master ,若是是這個slave第一次鏈接到master,他會觸發一個全量複製。master就會啓動一個線程,生成RDB快照,還會把新的寫請求都緩存在內存中,RDB文件生成後,master會將這個RDB發送給slave的,slave拿到以後作的第一件事情就是寫進本地的磁盤,而後加載進內存,而後master會把內存裏面緩存的那些新命名都發給slave。
傳輸過程當中有什麼網絡問題啥的,會自動重連的,而且鏈接以後會把缺乏的數據補上的。
你們須要記得的就是,RDB快照的數據生成的時候,緩存區也必須同時開始接受新請求,否則你舊的數據過去了,你在同步期間的增量數據咋辦?是吧?
這個問題是我在螞蟻金服三面的時候親身被問過的問題,不知道你們有沒有被懟到過這個問題。
Redis的過時策略,是有按期刪除+惰性刪除兩種。
按期好理解,默認100s就隨機抽一些設置了過時時間的key,去檢查是否過時,過時了就刪了。
假如Redis裏面全部的key都有過時時間,都掃描一遍?那太恐怖了,並且咱們線上基本上也都是會設置必定的過時時間的。全掃描跟你去查數據庫不帶where條件不走索引全表掃描同樣,100s一次,Redis累都累死了。
好問題,惰性刪除,見名知意,惰性嘛,我不主動刪,我懶,我等你來查詢了我看看你過時沒,過時就刪了還不給你返回,沒過時該怎麼樣就怎麼樣。
內存淘汰機制!
官網上給到的內存淘汰機制是如下幾個:
noeviction:返回錯誤當內存限制達到而且客戶端嘗試執行會讓更多內存被使用的命令(大部分的寫入指令,但DEL和幾個例外)
allkeys-lru: 嘗試回收最少使用的鍵(LRU),使得新添加的數據有空間存放。
volatile-lru: 嘗試回收最少使用的鍵(LRU),但僅限於在過時集合的鍵,使得新添加的數據有空間存放。
allkeys-random: 回收隨機的鍵使得新添加的數據有空間存放。
volatile-random: 回收隨機的鍵使得新添加的數據有空間存放,但僅限於在過時集合的鍵。
volatile-ttl: 回收在過時集合的鍵,而且優先回收存活時間(TTL)較短的鍵,使得新添加的數據有空間存放。
若是沒有鍵知足回收的前提條件的話,策略volatile-lru, volatile-random以及volatile-ttl就和noeviction 差很少了。
至於LRU我也簡單提一下,手寫實在是太長了,你們能夠去Redis官網看看,我把近視LUR效果給你們看看
tip:Redis爲何不使用真實的LRU實現是由於這須要太多的內存。不過近似的LRU算法對於應用而言應該是等價的。使用真實的LRU算法與近似的算法能夠經過下面的圖像對比。
你能夠看到三種點在圖片中, 造成了三種帶.
你能夠看到,在都是五個採樣的時候Redis 3.0比Redis 2.8要好,Redis2.8中在最後一次訪問之間的大多數的對象依然保留着。使用10個採樣大小的Redis 3.0的近似值已經很是接近理論的性能。
注意LRU只是個預測鍵將如何被訪問的模型。另外,若是你的數據訪問模式很是接近冪定律,大部分的訪問將集中在一個鍵的集合中,LRU的近似算法將處理得很好。
其實在你們熟悉的LinkedHashMap中也實現了Lru算法的,實現以下:
當容量超過100時,開始執行LRU策略:將最近最少未使用的 TimeoutInfoHolder 對象 evict 掉。
真實面試中會讓你寫LUR算法,你可別搞原始的那個,那真TM多,寫不完的,你要麼懟上面這個,要麼懟下面這個,找一個數據結構實現下Java版本的LRU仍是比較容易的,知道啥原理就行了。
好的謝謝面試官,面試官真好,我還想再面幾回,噗此。
能回答得這麼全面這麼細節仍是忍不住點贊
(暗示點贊,每次都看了不點贊,大家想白嫖我麼?大家好壞喲,不過我好喜歡)
好了,咱們玩歸玩,鬧歸鬧,別拿面試開玩笑,我這麼寫是爲了節目效果,你們面試請認真對待。
這一期是這期沒前面好理解了對吧,我就在本身的服務器上啓動了,而後再去官網看看命令一頓瞎操做的,查閱了部分資料,這裏給你們推薦幾本經典的Redis入門的書籍和我參考的資料。
《Redis入門指南(第2版)》
《Redis實戰》
《Redis設計與實現》
《大型網站技術架構——李智慧》
《Redis 設計與實現——黃健宏》
《Redis 深度歷險——錢文品》
《億級流量網站架構核心技術——張開濤》
《中華石杉——石杉》
不出意外的話這是Redis的倒數第二期,最後一期不知道寫啥還沒想好,我得好好想一想,加上最近不是雙十一嘛得加加班,你看看開頭的我,多可憐,那還不點個贊?買個服務器?不肯定下一期多久出,想早點看到更新的小夥伴能夠去公衆號催更,公衆號提早一到兩天更新。
對了,順帶推薦下近期很超值的雲服務器,初學者或者大牛均可以買來學習,搭建項目啊,服務器的各類操做呀啥的,你總不能拿公司服務器練手吧,rm-rf一用全部人都會叫你大牛的,用個人連接買最低80多一年,200三年,買了找我我返10元更便宜了,真香啊,說實話真香,這個錢不就是白*嘛,我直接用用老媽的號懟了個三年的。還有四天!!!
(服務器搭建裝Mysql,Tomcat啥的在公衆號我轉載我基友Java3y的文章《手把手教你使用雲服務器》中有)!
連接購買 經過個人連接購買,新用戶專享價,若是不是新用戶的能夠用家裏人的帳號購買,還有最後三天了,如今買的人去公衆號加我微信返10元。
二維碼購買
好了各位,以上就是這篇文章的所有內容了,能看到這裏的人呀,都是人才,我後面會每週都更新幾篇《吊打面試官》系列和Java技術棧相關的文章。若是你有什麼想知道的,也能夠留言給我,我一有時間就會寫出來,咱們共同進步。
很是感謝靚仔/靚女您能看到這裏,若是這個文章寫得還不錯,以爲敖丙有點東西 求點贊 求關注 求分享 求留言 (對我很是有用)各位的支持和承認,就是我創做的最大動力,咱們下篇文章見!
敖丙 | 文 【原創】
每週都會持續更新《吊打面試官》系列能夠關注個人公衆號第一時間閱讀和催更,公衆號比博客提早一到兩天更新,也能夠在公衆號回覆【人才】加入人才交流羣,裏面都是人才長得好看說話還好聽,進去就像回家了同樣,就業和工做上有什麼問題也能夠直接滴滴我,我也是個新人,不過不影響咱們一塊兒進步。