介紹:Redis 是一個開源的使用ANSI C 語言編寫、遵守BSD 協定、支援網路、可基於記憶體亦可持久化的日誌型、Key-Value 資料庫,並提供多種語言的API的非關係型資料庫。
專題推薦:2020年redis面試題大全(最新)
傳統資料庫遵循 ACID 規則。而 Nosql(Not Only SQL 的縮寫,是對不同於傳統的關係型資料庫的資料庫管理系統的統稱) 一般為分散式而分散式一般遵循 CAP 定理。
Github 原始碼:https://github.com/antirez/redis
Redis 官網:https://redis.io/
推薦:《redis教程》
Redis支援的資料類型?
String字串:
格式: set key value
#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)卻可以重複。
什麼是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 )格式的指令文字儲存。
比較:
1、aof檔案比rdb更新頻率高,優先使用aof還原資料。
2、aof比rdb更安全也更大
3、rdb效能比aof好
4、如果兩個都配了優先載入AOF
剛剛上面你有提到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 "*" 陣列
#Redis 有哪些架構模式?講講各自的特色
單機版
特點:簡單
問題:
1、記憶體容量有限 2、處理能力有限 3、無法高可用。
主從複製
#Redis 的複製(replication)功能允許使用者根據一個Redis 伺服器來建立任意多個該伺服器的複製品,其中複製的伺服器為主伺服器(master),而透過複製建立出來的伺服器複製品則為從伺服器(slave)。只要主從伺服器之間的網路連接正常,主從伺服器兩者會具有相同的數據,主伺服器就會一直將發生在自己身上的數據更新同步 給從伺服器,從而一直保證主從伺服器的資料相同。
特點:
1、master/slave 角色
2、master/slave 資料相同
3、降低master 讀取壓力在轉交給從函式庫
問題:
無法保證高可用
沒有解決master 寫的壓力
##哨兵
Redis sentinel 是分散式系統中監控redis 主從伺服器,並在主伺服器下線時自動進行故障轉移。其中三個功能:監控(Monitoring): Sentinel 會不斷檢查你的主伺服器和從伺服器是否運作正常。 提醒(Notification): 當被監控的某個 Redis 伺服器出現問題時, Sentinel 可以透過 API 向管理員或其他應用程式發送通知。 自動故障遷移(Automatic failover): 當一個主伺服器無法正常運作時, Sentinel 會開始一次自動故障遷移作業。 特點:1、保證高可用2、監控各個節點3、自動故障遷移
##缺點:主從模式,切換需要時間丟資料
沒有解決master 寫的壓力
叢集(proxy 類型):
Twemproxy 是一個Twitter 開源的一個redis 和memcache 快速/輕量級代理伺服器; Twemproxy 是一個快速的單線程代理程序,支援Memcached ASCII 協定和redis 協定。
特點:1、多種hash 演算法:MD5、CRC16、CRC32、CRC32a、hsieh、murmur、Jenkins
2、支援失敗節點自動刪除
3、後端Sharding 分片邏輯對業務透明,業務方的讀寫方式和操作單一Redis 一致性
缺點:增加了新的proxy,需要維護其高可用。
failover 邏輯需要自己實現,本身不能支援故障的自動轉移可擴展性差,進行擴縮容都需要手動幹預
群集(直連型):
從redis 3.0之後版本支援redis-cluster集群,Redis-Cluster採用無中心結構,每個節點保存資料和整個叢集狀態,每個節點都和其他所有節點連接。
特點:
1、無中心架構(不存在哪個節點影響效能瓶頸),少了 proxy 層。
2、資料依 slot 儲存分佈在多個節點,節點間資料共享,可動態調整資料分佈。
3、可擴充性,可線性擴展到 1000 個節點,節點可動態新增或移除。
4、高可用性,部分節點不可用時,叢集仍可用。透過增加 Slave 做備份資料副本
5、實作故障自動 failover,節點之間透過 gossip 協定交換狀態訊息,用投票機製完成 Slave到 Master 的角色提升。
缺點:
1、資源隔離性較差,容易出現相互影響的情況。
2、資料透過非同步複製,不保證資料的強一致性
什麼是一致性雜湊演算法?什麼是哈希槽?
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,設定不同的過期時間,讓快取失效的時間點盡量均勻。
以上是分享Redis常見面試題的詳細內容。更多資訊請關注PHP中文網其他相關文章!