Redis是一個很是火的非關係型數據庫,火到什麼程度呢?只要是一個互聯網公司都會使用到。Redis相關的問題能夠說是面試必問的,下面我從我的當面試官的經驗,總結幾個必需要掌握的知識點。(知識點較多,我整理了個思惟導圖,後臺回覆redis,發送給你) 介紹:Redis 是一個開源的使用 ANSI C 語言編寫、遵照 BSD 協議、支持網絡、可基於內存亦可持久化的日誌型、Key-Value 數據庫,並提供多種語言的 API的非關係型數據庫。傳統數據庫遵循 ACID 規則。而 Nosql(Not Only SQL 的縮寫,是對不一樣於傳統的關係型數據庫的數據庫管理系統的統稱) 通常爲分佈式而分佈式通常遵循 CAP 定理。html
Github 源碼:https://github.com/antirez/redisgit
Redis 官網:https://redis.io/ github
01面試
Redis支持的數據類型?redis
String字符串:算法
格式: set key valuesql
string類型是二進制安全的。意思是redis的string能夠包含任何數據。好比jpg圖片或者序列化的對象 。數據庫
string類型是Redis最基本的數據類型,一個鍵最大能存儲512MB。後端
Hash(哈希)數組
格式: hmset name key1 value1 key2 value2
Redis hash 是一個鍵值(key=>value)對集合。
Redis hash是一個string類型的field和value的映射表,hash特別適合用於存儲對象。
List(列表)
Redis 列表是簡單的字符串列表,按照插入順序排序。你能夠添加一個元素到列表的頭部(左邊)或者尾部(右邊)
格式: lpush name value
在 key 對應 list 的頭部添加字符串元素
格式: rpush name value
在 key 對應 list 的尾部添加字符串元素
格式: lrem name index
key 對應 list 中刪除 count 個和 value 相同的元素
格式: llen name
返回 key 對應 list 的長度
Set(集合)
格式: sadd name value
Redis的Set是string類型的無序集合。
集合是經過哈希表實現的,因此添加,刪除,查找的複雜度都是O(1)。
zset(sorted set:有序集合)
格式: zadd name score value
Redis zset 和 set 同樣也是string類型元素的集合,且不容許重複的成員。
不一樣的是每一個元素都會關聯一個double類型的分數。redis正是經過分數來爲集合中的成員進行從小到大的排序。
zset的成員是惟一的,但分數(score)卻能夠重複。
02
什麼是Redis持久化?Redis有哪幾種持久化方式?優缺點是什麼?
持久化就是把內存的數據寫到磁盤中去,防止服務宕機了內存數據丟失。
Redis 提供了兩種持久化方式:RDB(默認) 和AOF
RDB:
rdb是Redis DataBase縮寫
功能核心函數rdbSave(生成RDB文件)和rdbLoad(從文件加載內存)兩個函數
AOF:
Aof是Append-only file縮寫
每當執行服務器(定時)任務或者函數時flushAppendOnlyFile 函數都會被調用, 這個函數執行如下兩個工做
aof寫入保存:
WRITE:根據條件,將 aof_buf 中的緩存寫入到 AOF 文件
SAVE:根據條件,調用 fsync 或 fdatasync 函數,將 AOF 文件保存到磁盤中。
存儲結構:
內容是redis通信協議(RESP )格式的命令文本存儲。
比較:
一、aof文件比rdb更新頻率高,優先使用aof還原數據。
二、aof比rdb更安全也更大
三、rdb性能比aof好
四、若是兩個都配了優先加載AOF
03
剛剛上面你有提到redis通信協議(RESP ),能解釋下什麼是RESP?有什麼特色?(能夠看到不少面試其實都是連環炮,面試官其實在等着你回答到這個點,若是你答上了對你的評價就又加了一分)
RESP 是redis客戶端和服務端以前使用的一種通信協議;
RESP 的特色:實現簡單、快速解析、可讀性好
For Simple Strings the first byte of the reply is "+" 回覆
For Errors the first byte of the reply is "-" 錯誤
For Integers the first byte of the reply is ":" 整數
For Bulk Strings the first byte of the reply is "$" 字符串
For Arrays the first byte of the reply is "*" 數組
04
Redis 有哪些架構模式?講講各自的特色
單機版
特色:簡單
問題:
一、內存容量有限 二、處理能力有限 三、沒法高可用。
主從複製
Redis 的複製(replication)功能容許用戶根據一個 Redis 服務器來建立任意多個該服務器的複製品,其中被複制的服務器爲主服務器(master),而經過複製建立出來的服務器複製品則爲從服務器(slave)。 只要主從服務器之間的網絡鏈接正常,主從服務器二者會具備相同的數據,主服務器就會一直將發生在本身身上的數據更新同步 給從服務器,從而一直保證主從服務器的數據相同。
特色:
一、master/slave 角色
二、master/slave 數據相同
三、下降 master 讀壓力在轉交從庫
問題:
沒法保證高可用
沒有解決 master 寫的壓力
哨兵
Redis sentinel 是一個分佈式系統中監控 redis 主從服務器,並在主服務器下線時自動進行故障轉移。其中三個特性:
監控(Monitoring): Sentinel 會不斷地檢查你的主服務器和從服務器是否運做正常。
提醒(Notification): 當被監控的某個 Redis 服務器出現問題時, Sentinel 能夠經過 API 向管理員或者其餘應用程序發送通知。
自動故障遷移(Automatic failover): 當一個主服務器不能正常工做時, Sentinel 會開始一次自動故障遷移操做。
特色:
一、保證高可用
二、監控各個節點
三、自動故障遷移
缺點:主從模式,切換須要時間丟數據
沒有解決 master 寫的壓力
集羣(proxy 型):
Twemproxy 是一個 Twitter 開源的一個 redis 和 memcache 快速/輕量級代理服務器; Twemproxy 是一個快速的單線程代理程序,支持 Memcached ASCII 協議和 redis 協議。
特色:一、多種 hash 算法:MD五、CRC1六、CRC3二、CRC32a、hsieh、murmur、Jenkins
二、支持失敗節點自動刪除
三、後端 Sharding 分片邏輯對業務透明,業務方的讀寫方式和操做單個 Redis 一致
缺點:增長了新的 proxy,須要維護其高可用。
failover 邏輯須要本身實現,其自己不能支持故障的自動轉移可擴展性差,進行擴縮容都須要手動干預
集羣(直連型):
從redis 3.0以後版本支持redis-cluster集羣,Redis-Cluster採用無中心結構,每一個節點保存數據和整個集羣狀態,每一個節點都和其餘全部節點鏈接。
特色:
一、無中心架構(不存在哪一個節點影響性能瓶頸),少了 proxy 層。
二、數據按照 slot 存儲分佈在多個節點,節點間數據共享,可動態調整數據分佈。
三、可擴展性,可線性擴展到 1000 個節點,節點可動態添加或刪除。
四、高可用性,部分節點不可用時,集羣仍可用。經過增長 Slave 作備份數據副本
五、實現故障自動 failover,節點之間經過 gossip 協議交換狀態信息,用投票機制完成 Slave到 Master 的角色提高。
缺點:
一、資源隔離性較差,容易出現相互影響的狀況。
二、數據經過異步複製,不保證數據的強一致性
05
什麼是一致性哈希算法?什麼是哈希槽?
這兩個問題篇幅過長 網上找了兩個解鎖的不錯的文章
https://www.cnblogs.com/lpfuture/p/5796398.html
https://blog.csdn.net/z15732621582/article/details/79121213
06
Redis是基於CAP理論的,什麼是CAP理論?
能夠參考一篇文章。
07
Redis經常使用命令?
Keys pattern
*表示區配全部
以bit開頭的
查看Exists key是否存在
Set
設置 key 對應的值爲 string 類型的 value。
setnx
設置 key 對應的值爲 string 類型的 value。若是 key 已經存在,返回 0,nx 是 not exist 的意思。
刪除某個key
第一次返回1 刪除了 第二次返回0
Expire 設置過時時間(單位秒)
TTL查看剩下多少時間
返回負數則key失效,key不存在了
Setex
設置 key 對應的值爲 string 類型的 value,並指定此鍵值對應的有效期。
Mset
一次設置多個 key 的值,成功返回 ok 表示全部的值都設置了,失敗返回 0 表示沒有任何值被設置。
Getset
設置 key 的值,並返回 key 的舊值。
Mget
一次獲取多個 key 的值,若是對應 key 不存在,則對應返回 nil。
Incr
對 key 的值作加加操做,並返回新的值。注意 incr 一個不是 int 的 value 會返回錯誤,incr 一個不存在的 key,則設置 key 爲 1
incrby
同 incr 相似,加指定值 ,key 不存在時候會設置 key,並認爲原來的 value 是 0
Decr
對 key 的值作的是減減操做,decr 一個不存在 key,則設置 key 爲-1
Decrby
同 decr,減指定值。
Append
給指定 key 的字符串值追加 value,返回新字符串值的長度。
Strlen
取指定 key 的 value 值的長度。
persist xxx(取消過時時間)
選擇數據庫(0-15庫)
Select 0 //選擇數據庫
move age 1//把age 移動到1庫
Randomkey隨機返回一個key
Rename重命名
Type 返回數據類型
08
使用過Redis分佈式鎖麼,它是怎麼實現的?
先拿setnx來爭搶鎖,搶到以後,再用expire給鎖加一個過時時間防止鎖忘記了釋放。
若是在setnx以後執行expire以前進程意外crash或者要重啓維護了,那會怎麼樣?
set指令有很是複雜的參數,這個應該是能夠同時把setnx和expire合成一條指令來用的!
09
使用過Redis作異步隊列麼,你是怎麼用的?有什麼缺點?
通常使用list結構做爲隊列,rpush生產消息,lpop消費消息。當lpop沒有消息的時候,要適當sleep一會再重試。
缺點:
在消費者下線的狀況下,生產的消息會丟失,得使用專業的消息隊列如rabbitmq等。
能不能生產一次消費屢次呢?
使用pub/sub主題訂閱者模式,能夠實現1:N的消息隊列。
10
什麼是緩存穿透?如何避免?什麼是緩存雪崩?何如避免?
緩存穿透
通常的緩存系統,都是按照key去緩存查詢,若是不存在對應的value,就應該去後端系統查找(好比DB)。一些惡意的請求會故意查詢不存在的key,請求量很大,就會對後端系統形成很大的壓力。這就叫作緩存穿透。
如何避免?
1:對查詢結果爲空的狀況也進行緩存,緩存時間設置短一點,或者該key對應的數據insert了以後清理緩存。
2:對必定不存在的key進行過濾。能夠把全部的可能存在的key放到一個大的Bitmap中,查詢時經過該bitmap過濾。
緩存雪崩
當緩存服務器重啓或者大量緩存集中在某一個時間段失效,這樣在失效的時候,會給後端系統帶來很大壓力。致使系統崩潰。
如何避免?
1:在緩存失效後,經過加鎖或者隊列來控制讀數據庫寫緩存的線程數量。好比對某個key只容許一個線程查詢數據和寫緩存,其餘線程等待。
2:作二級緩存,A1爲原始緩存,A2爲拷貝緩存,A1失效時,能夠訪問A2,A1緩存失效時間設置爲短時間,A2設置爲長期
3:不一樣的key,設置不一樣的過時時間,讓緩存失效的時間點儘可能均勻。
歡迎工做一到五年的Java工程師朋友們加入Java架構開發:744677563
羣內提供免費的Java架構學習資料(裏面有高可用、高併發、高性能及分佈式、Jvm性能調優、Spring源碼,MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多個知識點的架構資料)合理利用本身每一分每一秒的時間來學習提高本身,不要再用"沒有時間「來掩飾本身思想上的懶惰!趁年輕,使勁拼,給將來的本身一個交代!