天下無難試之Redis面試刁難大全

Redis有哪些數據結構?html

字符串String、字典Hash、列表List、集合Set、有序集合SortedSet。node

若是你是Redis中高級用戶,還須要加上下面幾種數據結構HyperLogLog、Geo、Pub/Sub。面試

若是你說還玩過Redis Module,像BloomFilter,RedisSearch,Redis-ML,面試官得眼睛就開始發亮了。redis

 

假如Redis裏面有1億個key,其中有10w個key是以某個固定的已知的前綴開頭的,若是將它們所有找出來?數據庫

    使用keys指令能夠掃出指定模式的key列表。可是redis的單線程的,keys指令會致使線程阻塞一段時間,線上服務會停頓,直到指令執行完畢,服務才能恢復。緩存

    這個時候可使用scan指令,scan指令能夠無阻塞的提取出指定模式的key列表,可是會有必定的重複機率,在客戶端作一次去重就能夠了,可是總體所花費的時間會比直接用keys指令長。服務器

 

使用Redis作隊列:網絡

    異步隊列:數據結構

        通常使用list結構做爲隊列,rpush生產消息,lpop消費消息。當lpop沒有消息的時候,要適當sleep一會再重試。架構

        list還有個指令叫blpop,在沒有消息的時候,它會阻塞住直到消息到來。

    1:N的消息隊列:

        使用pub/sub主題訂閱者模式實現,但在消費者下線的狀況下,生產的消息會丟失,得使用專業的消息隊列如rabbitmq等。

    延時隊列:

        使用sortedset,拿時間戳做爲score,消息內容做爲key調用zadd來生產消息,消費者用zrangebyscore指令獲取N秒以前的數據輪詢進行處理。

 

持久化:

    bgsave作鏡像全量持久化,aof作增量持久化。

    由於bgsave會耗費較長時間,不夠實時,在停機的時候會致使大量丟失數據,因此須要aof來配合使用。在redis實例重啓時,會使用bgsave持久化文件從新構建內存,再使用aof重放近期的操做指令來實現完整恢復重啓以前的狀態。

若是忽然機器掉電會怎樣?

    取決於aof日誌sync屬性的配置,若是不要求性能,在每條寫指令時都sync一下磁盤,就不會丟失數據。可是在高性能的要求下每次都sync是不現實的,通常都使用定時sync,好比1s1次,這個時候最多就會丟失1s的數據。

bgsave的原理是什麼?

    fork和cow。fork是指redis經過建立子進程來進行bgsave操做,cow指的是copy on write,子進程建立後,父子進程共享數據段,父進程繼續提供讀寫服務,寫髒的頁面數據會逐漸和子進程分離開來。

1.redis調用fork,如今有了子進程和父進程。

2. 父進程繼續處理client請求,子進程負責將內存內容寫入到臨時文件。因爲os的寫時複製機制(copy on write)父子進程會共享相同的物理頁面,當父進程處理寫請求時os會爲父進程要修改的頁面建立副本,而不是寫共享的頁面。因此子進程的地址空間內的數 據是fork時刻整個數據庫的一個快照。

3.當子進程將快照寫入臨時文件完畢後,用臨時文件替換原來的快照文件,而後子進程退出。

 

aof 的方式也同時帶來了另外一個問題。持久化文件會變的愈來愈大。例如咱們調用incr test命令100次,文件中必須保存所有的100條命令,其實有99條都是多餘的。由於要恢復數據庫的狀態其實文件中保存一條set test 100就夠了。爲了壓縮aof的持久化文件。redis提供了bgrewriteaof命令。收到此命令redis將使用與快照相似的方式將內存中的數據 以命令的方式保存到臨時文件中,最後替換原來的文件。具體過程以下

1. redis調用fork ,如今有父子兩個進程
2. 子進程根據內存中的數據庫快照,往臨時文件中寫入重建數據庫狀態的命令
3.父進程繼續處理client請求,除了把寫命令寫入到原來的aof文件中。同時把收到的寫命令緩存起來。這樣就能保證若是子進程重寫失敗的話並不會出問題。
4.當子進程把快照內容寫入已命令方式寫到臨時文件中後,子進程發信號通知父進程。而後父進程把緩存的寫命令也寫入到臨時文件。
5.如今父進程可使用臨時文件替換老的aof文件,並重命名,後面收到的寫命令也開始往新的aof文件中追加。

須要注意到是重寫aof文件的操做,並無讀取舊的aof文件,而是將整個內存中的數據庫內容用命令的方式重寫了一個新的aof文件,這點和快照有點相似。

 

Redis的同步機制?

    Redis可使用主從同步,從從同步。第一次同步時,主節點作一次bgsave,並同時將後續修改操做記錄到內存buffer,待完成後將rdb文件全量同步到複製節點,複製節點接受完成後將rdb鏡像加載到內存。加載完成後,再通知主節點將期間修改的操做記錄同步到複製節點進行重放就完成了同步過程。

https://mp.weixin.qq.com/s/507jyNbL4xCkxyW6Xk15Xg

 

redis主從複製:

當用戶往Master端寫入數據時,經過Redis Sync機制將數據文件發送至Slave,Slave也會執行相同的操做確保數據一致;

redis主從複製特色:

一、同一個Master能夠擁有多個Slaves。

二、Master下的Slave還能夠接受同一架構中其它slave的連接與同步請求,實現數據的級聯複製,即Master->Slave->Slave模式;

三、Master以非阻塞的方式同步數據至slave,這將意味着Master會繼續處理一個或多個slave的讀寫請求;

四、Slave端同步數據也能夠修改成非阻塞是的方式,當slave在執行新的同步時,它仍能夠用舊的數據信息來提供查詢;不然,當slave與master失去聯繫時,slave會返回一個錯誤給客戶端;

五、主從複製具備可擴展性,即多個slave專門提供只讀查詢與數據的冗餘,Master端專門提供寫操做;

六、經過配置禁用Master數據持久化機制,將其數據持久化操做交給Slaves完成,避免在Master中要有獨立的進程來完成此操做。

redis主從複製原理:

當啓動一個Slave進程後,它會向Master發送一個SYNC Command,請求同步鏈接。

不管是第一次鏈接仍是從新鏈接,Master都會啓動一個後臺進程,將數據快照保存到數據文件中,同時Master會記錄全部修改數據的命令並緩存在數據文件中。

後臺進程完成緩存操做後,Master就發送數據文件給Slave,Slave端將數據文件保存到硬盤上,而後將其在加載到內存中,接着Master就會全部修改數據的操做,將其發送給Slave端。

若Slave出現故障致使宕機,恢復正常後會自動從新鏈接,Master收到Slave的鏈接後,將其完整的數據文件發送給Slave,若是Mater同時收到多個Slave發來的同步請求,Master只會在後臺啓動一個進程保存數據文件,而後將其發送給全部的Slave,確保Slave正常。

http://blog.51cto.com/cfwlxf/1433637

 

redis事物的瞭解CAS

  在Redis中,MULTI/EXEC/DISCARD/WATCH這四個命令是咱們實現事務的基石。redis事務的實現特徵:
    1). 在事務中的全部命令都將會被串行化的順序執行,事務執行期間,Redis不會再爲其它客戶端的請求提供任何服務,從而保證了事物中的全部命令被原子的執行。
    2). 和關係型數據庫中的事務相比,在Redis事務中若是有某一條命令執行失敗,其後的命令仍然會被繼續執行。
    3). 咱們能夠經過MULTI命令開啓一個事務,有關係型數據庫開發經驗的人能夠將其理解爲"BEGIN TRANSACTION"語句。在該語句以後執行的命令都將被視爲事務以內的操做,最後咱們能夠經過執行EXEC/DISCARD命令來提交/回滾該事務內的全部操做。這兩

      個Redis命令可被視爲等同於關係型數據庫中的COMMIT/ROLLBACK語句。
    4). 在事務開啓以前,若是客戶端與服務器之間出現通信故障並致使網絡斷開,其後全部待執行的語句都將不會被服務器執行。然而若是網絡中斷事件是發生在客戶端執行EXEC命令以後,那麼該事務中的全部命令都會被服務器執行。
    5). 當使用Append-Only模式時,Redis會經過調用系統函數write將該事務內的全部寫操做在本次調用中所有寫入磁盤。然而若是在寫入的過程當中出現系統崩潰,如電源故障致使的宕機,那麼此時也許只有部分數據被寫入到磁盤,而另一部分數據卻已經丟失。

      Redis服務器會在從新啓動時執行一系列必要的一致性檢測,一旦發現相似問題,就會當即退出並給出相應的錯誤提示。此時,咱們就要充分利用Redis工具包中提供的redis-check-aof工具,該工具能夠幫助咱們定位到數據不一致的錯誤,並將已經寫入的部

      分數據進行回滾。修復以後咱們就能夠再次從新啓動Redis服務器了。

 

WATCH命令和基於CAS的樂觀鎖: 

   在Redis的事務中,WATCH命令可用於提供CAS(check-and-set)功能。假設咱們經過WATCH命令在事務執行以前監控了多個Keys,假若在WATCH以後有任何Key的值發生了變化,EXEC命令執行的事務都將被放棄,同時返回Null multi-bulk應答以通知調用者事務

 

redis持久化的幾種方式

一、快照(snapshots)
  缺省狀況狀況下,Redis把數據快照存放在磁盤上的二進制文件中,文件名爲dump.rdb。你能夠配置Redis的持久化策略,例如數據集中每N秒鐘有超過M次更新,就將數據寫入磁盤;或者你能夠手工調用命令SAVE或BGSAVE。
  工做原理
  . Redis forks.
  . 子進程開始將數據寫到臨時RDB文件中。
  . 當子進程完成寫RDB文件,用新文件替換老文件。
  . 這種方式可使Redis使用copy-on-write技術。
二、AOF
  快照模式並不十分jian壯,當系統中止,或者無心中Redis被kill掉,最後寫入Redis的數據就會丟失。這對某些應用也許不是大問題,但對於要求高可靠性的應用來講,
  Redis就不是一個合適的選擇。
  Append-only文件模式是另外一種選擇。
  你能夠在配置文件中打開AOF模式
三、虛擬內存方式
  當你的key很小而value很大時,使用VM的效果會比較好.由於這樣節約的內存比較大.
  當你的key不小時,能夠考慮使用一些很是方法將很大的key變成很大的value,好比你能夠考慮將key,value組合成一個新的value.
  vm-max-threads這個參數,能夠設置訪問swap文件的線程數,設置最好不要超過機器的核數,若是設置爲0,那麼全部對swap文件的操做都是串行的.可能會形成比較長時間的延遲,可是對數據完整性有很好的保證.

  本身測試的時候發現用虛擬內存性能也不錯。若是數據量很大,能夠考慮分佈式或者其餘數據庫

https://www.cnblogs.com/Survivalist/p/8119891.html

 

redis 4.0

 Redis 4.0 之前存在的問題:1,節點重啓後須要全力拉取數據; 2,發生主從切換後,新的從節點都須要從新與主節點進去全量的數據同步  3,aof數據加載很慢;

           Redis 4.0 引入了兩項新的技術來解決了上述問題,Psync2,混合rdb、aof 文件。

           1, Psync 2 : 解決了從庫重啓以及發生主從切換以後的全量同步問題。

                以前的版本中,從庫重啓須要全量同步的緣由是從庫沒有將主節點的runId持久化(runId 是和 節點的nodeId 不一樣?),因此從節點重啓後由於沒有了這個runId 因此須要全量同步。新的版本中在RDB文件保存了這個runid,解決了重啓節點須要全量同步的問題。

                Redis 4.0 容許多級slave 的存在,便可以有這樣的形式   A(主) → B (從) → C(從) → D (從)  (Replication version 2); 當發生主從切換後,新的主節點能夠判斷從節點是否知足部分同步的條件: 以前就是重新主節點同步的或者以前和新主節點同步的是同一個master, 其餘的條件好比backlog 和offset 的位置和以前的版本同樣。                         

          2, Mixed-rdb & aof:  解決aof文件加載慢問題。

                aof相比rdb文件來講恢復數據的速度要慢不少。4.0 之後的aof重寫再也不是像以前同樣將數據以aof 的格式寫入到文件中, 而是先寫成rdb 的格式 (應該是先作一份全量的rdb,而後存儲進文件中去,這樣就必定快不少?這個和重寫aof 的數據量應該差很少纔是)。

 

 

redis怎樣找到key在內存中的位置

http://blog.csdn.net/agangdi/article/details/21567199

相關文章
相關標籤/搜索