如下內容爲轉載,原文出自微信公衆號:JavaFamilynode
答:英俊瀟灑的面試官,您好。咱們能夠先看一下 關係型數據庫 和 Redis 本質上的區別。面試
Redis採用的是基於內存的,採用的是單進程單線程模型的 KV 數據庫,有C語言編寫,官方提供的數據是能夠達到 10w+ 的QPS(每秒內查詢次數)。redis
我打個比方吧:之前有人這麼問過我,上下文切換是啥,爲何會縣城不安全?我是這麼說的,就比如你看一本英文書,看到第十頁發現有個單詞不會讀,你加了個書籤,而後去查字典,過了一下子你又回來繼續從書籤那裏讀,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更完整。
優勢:
它會生成多個數據文件,每一個數據文件分別表明了某一時刻 Redis 裏面的數據,這種方式,有沒有以爲很適合作冷備,完整的數據運維設置定時任務,定時同步到雲端的服務器,好比阿里雲服務,這樣一旦線上掛了,你想恢復多少分鐘以前的數據,就去雲端拷貝一份以前的數據就行了。
RDB對 Redis 的性能影響很是小,是由於在同步數據的時候他只是 fork 了一個子進程去作持久化,並且他在數據恢復的時候速度比AOF來的快。
缺點:
RDB都是快照文件,都是默認五分鐘甚至更久的時間纔會生成一次,這意味着你此次同步到下次同步這中間五分鐘的數據頗有可能所有丟失。AOF則最多丟失一秒的數據,數據完整性上高低立判。
還有就是RDB在生成數據快照的時候,若是文件很大,客戶端可能會暫停幾毫秒甚至幾秒,你公司在作秒殺或者搶單的時候,它恰好在這個時候 fork 了一個子進程去生成一個大快照,這確定要出大問題的。
優勢:
上面提到了,RDB五分鐘一次生成快照,可是AOF是一秒一次去經過一個後臺的縣城 fsync 操做,那最多丟失這一秒的數據。
AOF在對日誌文件進行操做的時候,是以 append-only 的方式去寫的,他只是追加的方式寫數據,天然就少了不少磁盤尋址的開銷,寫入性能驚人,文件也不容易破損。
AOF的日誌是經過一個叫很是可讀的方式記錄的,這樣的特性就適合作災難性數據誤刪除的緊急恢復了,好比某公司的實習生經過 flushall 清空了全部的數據,只要這個時候後臺重寫還沒發生,你立刻拷貝一份AOF日誌文件,把最後一條 flushall 命令刪除了就完事了。
Tip:這命令別去線上系統操做啊!!!想試去本身買的服務器上裝個Redis試!!!
缺點:
同樣的數據,AOF文件比RDB還要大。
AOF開啓後,Redis 支撐寫的QPS會比RDB支持寫的要低,他不是每秒都要去異步刷新一第二天志 fsync 嘛,固然即便這樣性能仍是很高,我記得 ElasticSearch 也是這樣的,異步刷新緩存區的數據去持久化,爲何這麼作,而不是來一條懟一條呢?那我會告訴你這樣性能可能低到沒辦法用的。至於爲什麼這麼作,後面記得再補了。
答:小朋友纔會作選擇題,我全都要!你單獨使用RDB,你會丟失不少數據;你單獨使用AOF,你數據恢復沒RDB來得快,真出了什麼問題,第一時間用RDB恢復,而後AOF作數據補全,簡直不要太完美!冷備、熱備一塊兒上,纔是互聯網時代一個健壯系統的王道。
完了,給本身挖坑了。。。(其實早有準備,就等你來問!也提醒一下,不會的知識點,回答中別說,不然真就是本身挖坑還本身往裏跳)
答:能夠僞裝思考(略做思考,省得覺得你真的不會),哦,想起來了,還有哨兵集羣 sentinel 。
哨兵必須用三個實例去保證本身的健壯性,哨兵 + 主從 並不能保證數據不丟失,可是能夠保證集羣的高可用。
爲何必需要三個實例呢?咱們先看看兩個哨兵會咋樣。
master宕機了,S1 和 S2 兩個哨兵只要有一個認爲你宕機了就切換了,而且會選舉一個哨兵去執行故障,可是這個時候也須要大多數哨兵都是運行的。
那這樣有啥問題呢?M1宕機了,S1沒有掛,這是OK的,可是整個機器都掛了呢?哨兵就剩下S2個光桿司令了,沒有哨兵去容許故障轉移了,雖然另一個機器上還有R1,可是故障轉移就是不執行。
經典的哨兵集羣是這樣的:
M1所在的機器掛了,哨兵還有兩個,兩我的一看M1掛了,那咱們就選舉一個出來執行故障轉移不就好了嘛。
簡單總結下哨兵組件的主要功能:
答:提到這個,就跟我前面提到的數據持久化的 RDB 和 AOF 有着密切的關係了。
我先說說爲何要用主從這樣的架構模式,前面提到了單機 QPS 是有上限的,並且Redis的特性就是必須支撐讀高併發的,那你一臺機器又讀又寫,就算是機器也扛不住啊。可是你讓這個 master 機器去寫,數據同步給別的 slave 機器,他們都拿去讀,分發掉大量的請求那就會好不少,並且擴容的時候還能夠輕鬆實現水平擴容。
迴歸正題,他們的數據是怎麼同步的呢?
你啓動了一臺 slave 的時候,他會發送一個 psync 命令給 master,若是是這個 slave 第一次鏈接到 master,他會觸發一個全量複製。master 就會啓動一個線程,生成 RDB快照,還會把新的寫請求都緩存在內存中,RDB文件生成後,master 會將這個 RDB 發送給 slave 的,slave 拿到以後作的第一件事情就是寫進本地的磁盤,而後加載進內存,而後 master 會把內存裏面的緩存的那些新命名都發給 slave。
答:傳輸過程當中有什麼網絡問題的,會自動重連的,而且鏈接以後會把缺乏的數據不上。
Tip:你們須要記住的是,RDB快照的數據生成的時候,緩存區也必須同時開始接受新請求,否則你舊的數據過去了,你在同步期間的增量數據咋辦?對吧?
答:Redis 的過時策略,是有按期刪除和惰性刪除兩種。
按期刪除好理解,就是默認100s就隨機抽取一些設置了過時時間的key,去檢查是否過時,過時了就刪除。
答:假如Redis裏面全部的key都有過時時間,再全掃描一遍?這太恐怖了,並且咱們線上基本上都會設置必定的過時時間。全掃描就跟你去查數據庫不帶where條件、不走索引全表掃描同樣,100s一次,會給 CPU 帶來很大的負載!
答:這就回到剛纔說的惰性刪除了。見名知意,惰性嘛,就是我不主動刪,我懶,我等你來查詢了,再看看你過時了沒,過時就刪除還不給你返回,沒過時該怎樣就怎樣。
答:若是過時就刪除,假設Redis裏放了10萬個key,都設置了過時時間,你每隔幾把毫秒,就檢查10萬個key,那Redis基本上就死了,CPU負載會很高的,基本都消耗在你的檢查過時key上。
可是問題是,按期刪除可能回致使不少過時key到了時間並無被刪除掉,那應該怎麼處理呢?因此就有了惰性刪除了。這就是說,在你獲取某個key的時候,redis會檢查一下,這個key若是設置了過時時間,那麼是否過時了?若是過時了此時就會刪除,不會給你返回任何東西。
並非key到了時間就被刪除,而是你查詢這個key的時候,redis再懶惰地檢查一下。
經過上述兩種手段結合起來,保證過時的key必定會被刪除。
因此說,用了上述2種策略後,這種現象就不難解釋了:數據明明都過時了,可是還佔着內存。
答:會出現大量的key堆積在內存裏,致使redis內存很快耗盡。使用redis內存淘汰機制解決這個問題。
可能有的小夥伴遇到過這種狀況,放在redis中的數據怎麼沒了?
由於Redis將數據放到內存中,內存時有限的,好比redis就只能用10個G,你要是忘裏面寫了20G的數據,會出現什麼狀況?固然是會幹掉10個G的數據,而後保留10個G的數據了。那幹掉哪些數據?保留哪些數據?固然時幹掉不經常使用的數據,保留經常使用的數據了。
Redis提供了6中數據淘汰策略: