Redis 是徹底開源免費的,遵照 BSD 協議,是一個高性能的 key-value 數據庫。程序員
Redis 與其餘 key - value 緩存產品有如下三個特色:web
性能極高 – Redis 能讀的速度是 110000 次/s,寫的速度是 81000 次/s 。面試
豐富的數據類型 – Redis 支持二進制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 數據類型操做。redis
原子 – Redis 的全部操做都是原子性的,意思就是要麼成功執行要麼失敗徹底不 執行。單個操做是原子性的。多個操做也支持事務,即原子性,經過 MULTI 和 EXEC 指令包起來。算法
豐富的特性 – Redis 還支持 publish/subscribe, 通知, key 過時等等特性。數據庫
Redis 有着更爲複雜的數據結構而且提供對他們的原子性操做,這是一個不一樣於其 他數據庫的進化路徑。Redis 的數據類型都是基於基本數據結構的同時對程序員透 明,無需進行額外的抽象。後端
Redis 運行在內存中可是能夠持久化到磁盤,因此在對不一樣數據集進行高速讀寫時 須要權衡內存,由於數據量不能大於硬件內存。在內存數據庫方面的另外一個優勢 是,相比在磁盤上相同的複雜的數據結構,在內存中操做起來很是簡單,這樣 Redis 能夠作不少內部複雜性很強的事情。同時,在磁盤格式方面他們是緊湊的以追加 的方式產生的,由於他們並不須要進行隨機訪問。緩存
答:Redis 支持五種數據類型:string(字符串),hash(哈希),list(列表), set(集合)及 zsetsorted set:有序集合)。安全
咱們實際項目中比較經常使用的是 string,hash 若是你是 Redis 中高級用戶,還須要 加上下面幾種數據結構 HyperLogLog、Geo、Pub/Sub。服務器
若是你說還玩過 Redis Module,像 BloomFilter,RedisSearch,Redis-ML,面 試官得眼睛就開始發亮了。
一、速度快,由於數據存在內存中,相似於 HashMap,HashMap 的優點就是查 找和操做的時間複雜度都是 O1
二、支持豐富數據類型,支持 string,list,set,Zset,hash 等
三、支持事務,操做都是原子性,所謂的原子性就是對數據的更改要麼所有執行, 要麼所有不執行
四、豐富的特性:可用於緩存,消息,按 key 設置過時時間,過時後將會自動刪除
一、Memcached 全部的值均是簡單的字符串,redis 做爲其替代者,支持更爲豐 富的數據類
二、Redis 的速度比 Memcached 快很
三、Redis 能夠持久化其數據
一、存儲方式 Memecache 把數據所有存在內存之中,斷電後會掛掉,數據不能 超過內存大小。 Redis 有部份存在硬盤上,這樣能保證數據的持久性。
二、數據支持類型 Memcache 對數據類型支持相對簡單。 Redis 有複雜的數據類 型。
三、使用底層模型不一樣 它們之間底層實現方式 以及與客戶端之間通訊的應用協議 不同。 Redis 直接本身構建了 VM 機制 ,由於通常的系統調用系統函數的話, 會浪費必定的時間去移動和請求。
答:Redis 是單進程單線程的,redis 利用隊列技術將併發訪問變爲串行訪問,消 除了傳統數據庫串行控制的開銷。
答:512M
Redis 提供兩種持久化機制 RDB 和 AOF 機制:
一、RDBRedis DataBase)持久化方式: 是指用數據集快照的方式半持久化模式) 記錄 redis 數據庫的全部鍵值對,在某個時間點將數據寫入一個臨時文件,持久化 結束後,用這個臨時文件替換上次持久化的文件,達到數據恢復。
一、只有一個文件 dump.rdb,方便持久化。
二、容災性好,一個文件能夠保存到安全的磁盤。
三、性能最大化,fork 子進程來完成寫操做,讓主進程繼續處理命令,因此是 IO 最大化。使用單獨子進程來進行持久化,主進程不會進行任何 IO 操做,保證了 redi的高性能) 4.相對於數據集大時,比 AOF 的啓動效率更高。
一、數據安全性低。RDB 是間隔一段時間進行持久化,若是持久化之間 redis 發生 故障,會發生數據丟失。因此這種方式更適合數據要求不嚴謹的時候)
二、AOFAppend-only file)持久化方式: 是指全部的命令行記錄以 redis 命令請 求協議的格式徹底持久化存儲)保存爲 aof 文件。
一、數據安全,aof 持久化能夠配置 appendfsync 屬性,有 always,每進行一次 命令操做就記錄到 aof 文件中一次。
二、經過 append 模式寫文件,即便中途服務器宕機,能夠經過 redis-check-aof 工具解決數據一致性問題。
三、AOF 機制的 rewrite 模式。AOF 文件沒被 rewrite 以前(文件過大時會對命令 進行合併重寫),能夠刪除其中的某些命令(好比誤操做的 flushall))
一、AOF 文件比 RDB 文件大,且恢復速度慢。
二、數據集大的時候,比 rdb 啓動效率低。
一、Master 最好不要寫內存快照,若是 Master 寫內存快照,save 命令調度 rdbSave 函數,會阻塞主線程的工做,當快照比較大時對性能影響是很是大的,會間斷性 暫停服務
二、若是數據比較重要,某個 Slave 開啓 AOF 備份數據,策略設置爲每秒同步一
三、爲了主從複製的速度和鏈接的穩定性,Master 和 Slave 最好在同一個局域網
四、儘可能避免在壓力很大的主庫上增長從
五、主從複製不要用圖狀結構,用單向鏈表結構更爲穩定,即:Master <- Slave1 <- Slave2 <- Slave3…這樣的結構方便解決單點故障問題,實現 Slave 對 Master 的替換。若是 Master 掛了,能夠馬上啓用 Slave1 作 Master,其餘不變。
一、定時刪除:在設置鍵的過時時間的同時,建立一個定時器 timer). 讓定時器在鍵 的過時時間來臨時,當即執行對鍵的刪除操做。
二、惰性刪除:聽任鍵過時無論,可是每次從鍵空間中獲取鍵時,都檢查取得的鍵是 否過時,若是過時的話,就刪除該鍵;若是沒有過時,就返回該鍵。
三、按期刪除:每隔一段時間程序就對數據庫進行一次檢查,刪除裏面的過時鍵。至 於要刪除多少過時鍵,以及要檢查多少個數據庫,則由算法決定
volatile-lru:從已設置過時時間的數據集(server.db[i].expires)中挑選最近最 少使用的數據淘汰
volatile-ttl:從已設置過時時間的數據集(server.db[i].expires)中挑選將要過 期的數據淘汰
volatile-random:從已設置過時時間的數據集(server.db[i].expires)中任意 選擇數據淘汰
allkeys-lru:從數據集(server.db[i].dict)中挑選最近最少使用的數據淘汰
allkeys-random:從數據集(server.db[i].dict)中任意選擇數據淘汰
no-enviction(驅逐):禁止驅逐數據
注意這裏的 6 種機制,volatile 和 allkeys 規定了是對已設置過時時間的數據集淘 汰數據仍是從所有數據集淘汰數據,後面的 lru、ttl 以及 random 是三種不一樣的 淘汰策略,再加上一種 no-enviction 永不回收的策略。
使用策略規則:
一、若是數據呈現冪律分佈,也就是一部分數據訪問頻率高,一部分數據訪問頻率 低,則使用 allkeys-lru
二、若是數據呈現平等分佈,也就是全部的數據訪問頻率都相同,則使用 allkeys-random
答:Redis 爲了達到最快的讀寫速度將數據都讀到內存中,並經過異步的方式將數 據寫入磁盤。因此 redis 具備快速和數據持久化的特徵。若是不將數據放在內存中, 磁盤 I/O 速度爲嚴重影響 redis 的性能。在內存愈來愈便宜的今天,redis 將會越 來越受歡迎。若是設置了最大使用的內存,則數據已有記錄數達到內存限值後不 能繼續插入新值。
答:Redis 可使用主從同步,從從同步。第一次同步時,主節點作一次 bgsave, 並同時將後續修改操做記錄到內存 buffer,待完成後將 rdb 文件全量同步到複製 節點,複製節點接受完成後將 rdb 鏡像加載到內存。加載完成後,再通知主節點 將期間修改的操做記錄同步到複製節點進行重放就完成了同步過程
答:能夠將屢次 IO 往返的時間縮減爲一次,前提是 pipeline 執行的指令之間沒有 因果相關性。使用 redis-benchmark 進行壓測的時候能夠發現影響 redis 的 QPS 峯值的一個重要因素是 pipeline 批次指令的數目。
1)、Redis Sentinal 着眼於高可用,在 master 宕機時會自動將 slave 提高爲 master,繼續提供服務。
2)、Redis Cluster 着眼於擴展性,在單個 redis 內存不足時,使用 Cluster 進行 分片存儲。
答:有 A,B,C 三個節點的集羣,在沒有複製模型的狀況下,若是節點 B 失敗了, 那麼整個集羣就會覺得缺乏 5501-11000 這個範圍的槽而不可用。
答:Redisson、Jedis、lettuce 等等,官方推薦使用 Redisson。
答:Jedis 是 Redis 的 Java 實現的客戶端,其 API 提供了比較全面的 Redis 命令 的支持;Redisson 實現了分佈式和可擴展的 Java 數據結構,和 Jedis 相比,功能 較爲簡單,不支持字符串操做,不支持排序、事務、管道、分區等 Redis 特性。 Redisson 的宗旨是促進使用者對 Redis 的關注分離,從而讓使用者可以將精力更 集中地放在處理業務邏輯上。
設置密碼:config set requirepass 123456 受權密碼:auth 123456
答:Redis 集羣沒有使用一致性 hash,而是引入了哈希槽的概念,Redis 集羣有 16384 個哈希槽,每一個 key 經過 CRC16 校驗後對 16384 取模來決定放置哪一個槽, 集羣的每一個節點負責一部分 hash 槽。
答:爲了使在部分節點失敗或者大部分節點沒法通訊的狀況下集羣仍然可用,所 以集羣使用了主從複製模型,每一個節點都會有 N-1 個複製品.
答:Redis 並不能保證數據的強一致性,這意味這在實際中集羣在特定的條件下可 能會丟失寫操做。
答:異步複製
答:16384 個。
答:Redis 集羣目前沒法作數據庫選擇,默認在 0 數據庫。
答:使用 ping 命令。
答:
1)事務是一個單獨的隔離操做:事務中的全部命令都會序列化、按順序地執行。 事務在執行的過程當中,不會被其餘客戶端發送來的命令請求所打斷。
2)事務是一個原子操做:事務中的命令要麼所有被執行,要麼所有都不執行。
答:MULTI、EXEC、DISCARD、WATCH
答:EXPIRE 和 PERSIST 命令。
答:儘量使用散列表(hashes),散列表(是說散列表裏面存儲的數少)使用 的內存很是小,因此你應該儘量的將你的數據模型抽象到一個散列表裏面。比 如你的 web 系統中有一個用戶對象,不要爲這個用戶的名稱,姓氏,郵箱,密碼 設置單獨的 key,而是應該把這個用戶的全部信息存儲到一張散列表裏面.
答:一個客戶端運行了新的命令,添加了新的數據。Redi 檢查內存使用狀況,如 果大於 maxmemory 的限制, 則根據設定好的策略進行回收。一個新的命令被執 行,等等。因此咱們不斷地穿越內存限制的邊界,經過不斷達到邊界而後不斷地 回收回到邊界如下。若是一個命令的結果致使大量內存被使用(例如很大的集的交集保存到一個新的鍵),不用多久內存限制就會被這個內存使用量超越。
答:若是你使用的是 32 位的 Redis 實例,能夠好好利用 Hash,list,sorted set,set 等集合類型數據,由於一般狀況下不少小的 Key-Value 能夠用更緊湊的方式存放 到一塊兒。
答:若是達到設置的上限,Redis 的寫命令會返回錯誤信息(可是讀命令還能夠正 常返回。)或者你能夠將 Redis 當緩存來使用配置淘汰機制,當 Redis 達到內存 上限時會沖刷掉舊的內容。
答:理論上 Redis 能夠處理多達 232 的 keys,而且在實際中進行了測試,每一個實 例至少存放了 2 億 5 千萬的 keys。咱們正在測試一些較大的值。任何 list、set、 和 sorted set 均可以放 232 個元素。換句話說,Redis 的存儲極限是系統中的可 用內存值。
答:Redis 內存數據集大小上升到必定大小的時候,就會施行數據淘汰策略。
相關知識:Redis 提供 6 種數據淘汰策略:
volatile-lru:從已設置過時時間的數據集(server.db[i].expires)中挑選最近最 少使用的數據淘汰
volatile-ttl:從已設置過時時間的數據集(server.db[i].expires)中挑選將要過 期的數據淘汰
volatile-random:從已設置過時時間的數據集(server.db[i].expires)中任意 選擇數據淘汰
allkeys-lru:從數據集(server.db[i].dict)中挑選最近最少使用的數據淘汰
allkeys-random:從數據集(server.db[i].dict)中任意選擇數據淘汰
no-enviction(驅逐):禁止驅逐數據
一、會話緩存(Session Cache)
最經常使用的一種使用 Redis 的情景是會話緩存(session cache)。用 Redis 緩存話比其餘存儲(如 Memcached)的優點在於:Redis 提供持久化。當維護一個不 是嚴格要求一致性的緩存時,若是用戶的購物車信息所有丟失,大部分人都會不 高興的,如今,他們還會這樣嗎? 幸運的是,隨着 Redis 這些年的改進,很容 易找到怎麼恰當的使用 Redis 來緩存會話的文檔。甚至廣爲人知的商業平臺 Magento 也提供 Redis 的插件。
二、全頁緩存(FPC)
除基本的會話 token 以外,Redis 還提供很簡便的 FPC 平臺。回到一致性問題, 即便重啓了 Redis 實例,由於有磁盤的持久化,用戶也不會看到頁面加載速度的 降低,這是一個極大改進,相似 PHP 本地 FPC。 再次以 Magento 爲例,Magento 提供一個插件來使用 Redis 做爲全頁緩存後端。 此外,對 WordPress 的用戶來 說,Pantheon 有一個很是好的插件 wp-redis,這個插件能幫助你以最快速度加 載你曾瀏覽過的頁面。
三、隊列
Reids 在內存存儲引擎領域的一大優勢是提供 list 和 set 操做,這使得 Redis 能做爲一個很好的消息隊列平臺來使用。Redis 做爲隊列使用的操做,就相似於本 地程序語言(如 Python)對 list 的 push/pop 操做。 若是你快速的在 Google 中搜索「Redis queues」,你立刻就能找到大量的開源項目,這些項目的目的就 是利用 Redis 建立很是好的後端工具,以知足各類隊列需求。例如,Celery 有一 個後臺就是使用 Redis 做爲 broker,你能夠從這裏去查看。
4,排行榜/計數器
Redis 在內存中對數字進行遞增或遞減的操做實現的很是好。集合(Set)和有序 集合(Sorted Set)也使得咱們在執行這些操做的時候變的很是簡單,Redis 只是 正好提供了這兩種數據結構。因此,咱們要從排序集合中獲取到排名最靠前的 10 個用戶–咱們稱之爲「user_scores」,咱們只須要像下面同樣執行便可: 固然, 這是假定你是根據你用戶的分數作遞增的排序。若是你想返回用戶及用戶的分數, 你須要這樣執行: ZRANGE user_scores 0 10 WITHSCORES Agora Games 就 是一個很好的例子,用 Ruby 實現的,它的排行榜就是使用 Redis 來存儲數據的, 你能夠在這裏看到。
五、發佈/訂閱
最後(但確定不是最不重要的)是 Redis 的發佈/訂閱功能。發佈/訂閱的使用場景 確實很是多。我已看見人們在社交網絡鏈接中使用,還可做爲基於發佈/訂閱的腳 本觸發器,甚至用 Redis 的發佈/訂閱功能來創建聊天系統!
答:使用 keys 指令能夠掃出指定模式的 key 列表。
對方接着追問:若是這個 redis 正在給線上的業務提供服務,那使用 keys 指令會 有什麼問題?
這個時候你要回答 redis 關鍵的一個特性:redis 的單線程的。keys 指令會致使線 程阻塞一段時間,線上服務會停頓,直到指令執行完畢,服務才能恢復。這個時 候可使用 scan 指令,scan 指令能夠無阻塞的提取出指定模式的 key 列表,但 是會有必定的重複機率,在客戶端作一次去重就能夠了,可是總體所花費的時間 會比直接用 keys 指令長。
答:若是大量的 key 過時時間設置的過於集中,到過時的那個時間點,redis 可能 會出現短暫的卡頓現象。通常須要在時間上加一個隨機值,使得過時時間分散一 些。
答:通常使用 list 結構做爲隊列,rpush 生產消息,lpop 消費消息。當 lpop 沒有 消息的時候,要適當 sleep 一會再重試。
若是對方追問可不能夠不用 sleep 呢?
list 還有個指令叫 blpop,在沒有消息的時候,它會阻塞住直到消息到來。若是對 方追問能不能生產一次消費屢次呢?使用 pub/sub 主題訂閱者模式,能夠實現 1:N 的消息隊列。
若是對方追問 pub/sub 有什麼缺點?
在消費者下線的狀況下,生產的消息會丟失,得使用專業的消息隊列如 RabbitMQ 等。
若是對方追問 redis 如何實現延時隊列?
我估計如今你很想把面試官一棒打死若是你手上有一根棒球棍的話,怎麼問的這 麼詳細。可是你很剋制,而後神態自若的回答道:使用 sortedset,拿時間戳做爲 score,消息內容做爲 key 調用 zadd 來生產消息,消費者用 zrangebyscore 指令 獲取 N 秒以前的數據輪詢進行處理。到這裏,面試官暗地裏已經對你豎起了大拇 指。可是他不知道的是此刻你卻豎起了中指,在椅子背後。
先拿 setnx 來爭搶鎖,搶到以後,再用 expire 給鎖加一個過時時間防止鎖忘記了 釋放。
這時候對方會告訴你說你回答得不錯,而後接着問若是在 setnx 以後執行 expire 以前進程意外 crash 或者要重啓維護了,那會怎麼樣?
這時候你要給予驚訝的反饋:唉,是喔,這個鎖就永遠得不到釋放了。緊接着你 須要抓一抓本身得腦殼,故做思考片刻,好像接下來的結果是你主動思考出來的, 而後回答:我記得 set 指令有很是複雜的參數,這個應該是能夠同時把 setnx 和 expire 合成一條指令來用的!對方這時會顯露笑容,內心開始默唸:嗯,這小子還不錯。