女朋友面試回來抱怨說會redis,面試官問了一堆redis

图片

Redis 優缺點及特點

什麼是Redis?簡述它的優缺點? 

 

Redis本質上是一個Key-Value類型的記憶體資料庫,類似MemoryCache,整個資料庫統統載入在記憶體當中進行操作,定期通過非同步操作把資料庫數據flush到硬碟上進行保存。因為是純記憶體操作,Redis的性能非常出色,每秒可以處理超過 10萬次讀寫操作,是已知性能快的 Key-Value DB。

 

Redis的出色之處不僅僅是性能,Redis大的魅力是支援保存多種數據結構,單個value的大限 制是1GB,不像MemoryCache只能保存1MB的數據,因此Redis可以用來實現很多有用的功能。

 

比方說用他的List來做FIFO雙向鏈表,實現一個輕量級的高性能消息隊列服務,用他的Set可以做高性能的tag系統等等。

 

另外Redis也可以對存入的Key-Value設置expire時間,因此也可以被當作一個功能加強版的MemoryCache來用。

 

Redis的主要缺點是資料庫容量受到物理記憶體的限制,不能用作海量數據的高性能讀寫,因此Redis適合的場景主要局限在較小數據量的高性能操作和運算上。

 

Redis相比MemoryCache有哪些優勢? 

 

MemoryCache所有的值均是簡單的字元串,Redis作為其替代者,支援更為豐富的數據類型

Redis的速度比MemoryCache快很多

Redis可以持久化其數據。

 

Redis支援哪幾種數據類型? 

 

  String:字元
  List:列表
  Set:集合
  Sorted Set:有序集合
  Hash:哈希列表

 

Redis主要消耗什麼物理資源? 

 

記憶體。因為Redis的數據都是存儲在記憶體當中。記憶體資料庫相比一般的關係型資料庫,讀取速度要更快,但是消耗的記憶體資源會更多。

 

Redis的全稱是什麼? 

 

Remote Dictionary Server

 

Redis有哪幾種數據淘汰策略?

 

noeviction:默認策略,不淘汰,如果記憶體已滿,添加數據則返回錯誤。

allkeys-lru: 嘗試回收最近最少使用的鍵,使得新添加的數據有空間存放。

volatile-lru: 嘗試回收最少使用的鍵,但僅限於在過期集合的鍵,使得新添加的數據有空間存放。

allkeys-random: 回收隨機的鍵使得新添加的數據有空間存放。

volatile-random: 回收隨機的鍵使得新添加的數據有空間存放,但僅限於在過期集合的鍵。

volatile-ttl: 回收在過期集合的鍵,並且優先回收存活時間(TTL)較短的鍵,使得新添加的數據有空間存 放。

 

 

一個字元串類型的值能存儲最大容量是多少?

 

 512M 

 

為什麼Redis需要把所有數據放到記憶體中? 

 

Redis為了達到最快的讀寫速度將數據都讀到記憶體中,並通過非同步的方式將數據寫入磁碟。所以Redis具有快速和數據持久化的特徵。如果不將數據放在記憶體中,磁碟I/O速度嚴重影響Redis的性能。

 

MySQL有2000w數據,redis中只存20w的數據,如何保證 redis中的數據都是熱點數據?

 

redis記憶體數據集大小上升到一定大小的時候,就會施行數據淘汰策略。

 

Redis有哪些適合的場景? 

 

會話快取(Session Cache): 常用的一種使用Redis的情景是會話快取(session cache)。

 

用Redis快取會話比其他存儲(如MemoryCache)的優勢在於:Redis提供持久化。

 

當維護一個不是嚴格要求一致性的快取時,如果用戶的購物車資訊全部丟失,造成用戶體驗上的不佳。

 

隨著 Redis 這些年的改進,很容易找到怎麼恰當的使用Redis來快取會話的文檔。甚至廣為 人知的商業平台Magento也提供Redis的插件。

 

全頁快取(FPC):除基本的會話token之外,Redis還提供很簡便的FPC平台。

 

回到一致性問題,即使重啟了Redis實例, 因為有磁碟的持久化,用戶也不會看到頁面載入速度的下降,這是一個極大改進,類似PHP本地FPC。

 

再次以Magento為例,Magento提供一個插件來使用Redis作為全頁快取後端。

 

此外,對WordPress的用戶來說,Pantheon有一個非常好的插件wp-Redis,這個插件能幫助你以快 速度載入你曾瀏覽過的頁面。

 

隊列:  Reids在記憶體存儲引擎領域的一大優點是提供 list 和 set 操作,這使得Redis能作為一個很好的消息隊列平台來使用。

 

Redis作為隊列使用的操作,就類似於本地程式語言(如C#)對queue的 put/pop 操作。

 

如果你快速的在Google中搜索「Redis queues」,你馬上就能找到大量的開源項目,這些項目的目的就是利用Redis創建非常好的後端工具,以滿足各種隊列需求。

 

例如,Celery有一個後台就是使用Redis作為 broker,你可以從這裡去查看。

 

排行榜/計數器:Redis在記憶體中對數字進行遞增或遞減的操作實現的非常好。

 

集合(Set)和有序集合(Sorted Set)也 使得我們在執行這些操作的時候變的非常簡單,Redis只是正好提供了這兩種數據結構。

 

所以,我們要從排序集合中獲取到排名靠前的10個用戶–我們稱之為「user_scores」。

 

當然,這是假定你是根據你用戶的分數做遞增的排序。

 

 

發布/訂閱:  發布/訂閱的使用場景確實非常多。

 

我已看見人們在社交網路連接中使用,還可作為基於發布/訂閱的腳本觸發器,甚至用Redis的發布/訂閱功能來建立聊天系統。

 

Redis支援的Java客戶端都有哪些?官方推薦用哪個? 

 

Redisson、Jedis、lettuce等等,官方推薦使用Redisson。

 

Redis和Redisson有什麼關係? 

 

Redisson是一個高級的分散式協調Redis客服端,能幫助用戶在分散式環境中輕鬆實現一些Java的對象。

例如:


Bloomfilter,BitSet,Set,SetMultimap,ScoredSortedSet,SortedSet,Map,ConcurrentMap,List,ListMultimap,Queue,BlockingQueue,Deque,BlockingDeque等。

 

Redis如何設置密碼及驗證密碼? 

 

設置密碼:config set requirepass 123456 授權密碼:auth pwd

 

說說Redis哈希槽的概念? 

 

Redis集群沒有使用一致性hash,而是引入了哈希槽的概念,Redis集群有16384個哈希槽,每個key通過 CRC16校驗後對16384取模來決定放置哪個槽,集群的每個節點負責一部分hash槽。

 

Redis 管道模型及事務

怎麼測試Redis的連通性? 

 

跟測試ip一樣,使用ping的方式。

 

Redis中的管道有什麼用? 

 

一次請求/響應伺服器能實現處理新的請求即使舊的請求還未被響應。

 

這樣就可以將多個命令發送到伺服器,而不用等待回復,後在一個步驟中讀取該答覆(這個跟程式語言的 async/await 非同步編程一樣)。

 

這就是管道(pipelining),是一種幾十年來廣泛使用的技術。例如許多POP3協議已經實現支援這個功 能,大大加快了從伺服器下載新郵件的過程。

 

怎麼理解Redis事務? 

 

事務是一個單獨的隔離操作:事務中的所有命令都會序列化、按順序地執行。事務在執行的過程中,不會被其他客戶端發送來的命令請求所打斷。

 

事務是一個原子操作:事務中的命令要麼全部被執行,要麼全部都不執行。

 

Redis事務相關的命令有哪幾個? 

 

MULTI、EXEC、DISCARD、WATCH

 

Redis key的過期時間和永久有效分別怎麼設置? 

 

EXPIRE:設置過期
PERSIST:設置永久有效

 

Redis 記憶體優化及性能

 

Redis如何做記憶體優化? 

 

Redis的散列(hash)表會將一個鍵和一個散列表在資料庫中關聯起來,用戶可以在散列表中為任意多個字設置值。

 

與字元串鍵值對一樣,散列表裡面的欄位和值既可以是文本數據,可以是二進位數據。

 

儘可能使用散列表(hash),散列表(是說散列表裡面存儲的數量少)使用的記憶體非常小,所以應該儘可能的將你的數據模型抽象到一個散列表裡面。

 

比如你的web系統中有一個用戶對象,不要為這個用戶的名稱,姓氏,郵箱,密碼設置單獨的key,而是 應該把這個用戶的所有資訊存儲到一張散列表裡面。

 

Redis回收進程如何工作的? 

 

一個客戶端運行了新的命令,添加了新的數據。Redis檢查記憶體使用情況,如果大於maxmemory的限制, 則根據設定好的策略進行回收。

 

所以我們不斷地穿越記憶體限制的邊界,通過不斷達到邊界然後不斷地回收回到邊界以下。

 

如果一個命令的結果導致大量記憶體被使用(例如很大的集合的交集保存到一個新的鍵),不用多久記憶體限制就會被這個記憶體使用量超越。

 

為什麼Redis需要把所有數據放到記憶體中? 

 

Redis為了達到快的讀寫速度將數據都讀到記憶體中,並通過非同步的方式將數據寫入磁碟。

 

所以Redis具有快速和數據持久化的特徵。

 

如果不將數據放在記憶體中,磁碟I/O速度會嚴重影響redis的性能。

 

如果設置了大量使用的記憶體,則數據已有記錄數達到記憶體 限值後不能繼續插入新值。

 

Redis常見的性能問題都有哪些?如何解決? 

 

Master寫記憶體快照,save命令調度rdbSave函數,會阻塞主執行緒的工作,當快照比較大時對性能影響是非常大的,會間斷性暫停服務,所以Master好不要寫記憶體快照。

 

Master AOF持久化,如果不重寫AOF文件,這個持久化方式對性能的影響是小的,但是AOF文件會不斷增大,AOF文件過大會影響Master重啟的恢復速度。

 

Master好不要做任何持久化工作,包括記憶體快照和AOF日誌文件,特別是不要啟用記憶體快照做持久化,如果數據比較關鍵,某個Slave開啟AOF備 份數據,策略為每秒同步一次。

 

Master調用BGREWRITEAOF重寫AOF文件,AOF在重寫的時候會佔大量的CPU和記憶體資源,導致服務載入過高,出現短暫服務暫停現象。

 

Redis主從複製的性能問題,為了主從複製的速度和連接的穩定性,Slave和Master好在同一個區域網內。

 

Redis最適合的場景有哪些? 

 

會話快取(Session Cache)
全頁快取(FPC) 
隊列 
排行榜/計數器
發布/訂閱 

 

MemoryCache與Redis的區別都有哪些? 

 

存儲方式不同,MemoryCache是把數據全部存在記憶體中,數據不能超過記憶體的大小,斷電後資料庫會掛掉。Redis有部分存在硬碟上,這樣能保證數據的持久性。

 

數據支援的類型不同MemoryCache對數據類型支援相對簡單,redis有複雜的數據類型。

 

使用底層模型不同它們之間底層實現方式以及與客戶端之間通訊的應用協議不一樣。

Redis直接自己 構建了VM機制,因為一般的系統調用系統函數的話,會浪費一定的時間去移動和請求。

 

支援的value大小不一樣Redis大可以達到1GB,而MemoryCache只有1MB。

 

Redis有哪幾種數據結構? 

 

String字元串: String數據結構是簡單的key-value類型,value不僅可以是String,也可以是數字(當數字類型用Long 可以表示的時候Encoding就是整型,其他都存儲在sdshdr當做字元串)。

Hash字典: 在MemoryCache中,我們經常將一些結構化的資訊打包成HashMap,在客戶端序列化後存儲為一個字元 串的值(一般是JSON格式),比如用戶的昵稱、年齡、性別、積分等。

List列表: List說白了就是鏈表(redis使用雙端鏈表實現的List)

Set集合: Set就是一個集合,集合的概念就是一堆不重複值的組合。利用Redis提供的Set數據結構,可以存儲一 些集合性的數據。

Sorted Set有序集合: 和Set相比,Sorted Set是將Set中的元素增加了一個權重參數score,使得集合中的元素能夠按score進 行有序排列,

帶有權重的元素,比如一個遊戲的用戶得分排行榜

比較複雜的數據結構,一般用到的場景不算太多 

 

 

寫到這裡,

女朋友就忍不住問了:可是,Redis如何做集群?

高並發下快取擊穿是怎麼導致?

快取雪崩又是怎麼造成的又咋解決呢?

並發下競爭Key又是咋解決呢?

 

我:......

 

我:傻瓜,時候不早了,早些休息......