Redis常見面試題

73、發表於2021-01-05

5.2.1 Redis 是什麼?常⻅的應用場景?

redis是一個快取資料庫,是一個非關係型資料庫的鍵值儲存資料庫
應用場景:內容快取,主要用於處理大量資料的高訪問負載;日誌系統

5.2.2 Redis 常⻅資料型別有哪些?各自有什麼應用場景?

String:儲存的資料是普通的鍵值對可用String來進行儲存
Hash:儲存的資料是一組關聯性較強的資料,如一個人的生日、年齡、姓名等一系列資訊
List:儲存的資料是列表、訊息佇列等
Set:儲存的資料型別是不重複的列表可用
Sorted Set:儲存的資料型別是有序的不重複的列表

5.2.3 非關係型資料庫 Redis 和 MongoDB 資料庫的結構有什麼區別?

記憶體管理機制上,redis把所有的資料都放入到記憶體中,定期寫入磁碟。當記憶體不足時,呼叫LRU演算法刪除資料;mongodb和mysql類似,只將索引檔案放入記憶體中。當記憶體不足時,只將熱點資料放入記憶體,其它的資料寫入磁碟。
資料結構上,redis支援豐富的資料結構,如String、Hash、List等;mongoDB支援的資料結構單一,但支援豐富的資料表達、 索引
效能上,redis適合較小的資料運算;mongodb在海量的資料下效能更優

5.2.4 Redis 和 MongoDB 資料庫的鍵(key)和值(value)的區別?

5.2.5 Redis 持久化機制是什麼?有哪幾種方式?

週期性的將記憶體中的資料寫入到檔案中,當redis當機,重啟後,可以從持久化檔案中讀取資料,恢復當機前的狀態
有RDB和AOF兩種方式,RDB是週期性的持久化資料,AOF是把每條寫入命令當作日誌,寫入到一個日誌檔案中,當redis當機,重啟後,從AOF檔案中讀取寫入命令重新構建整個資料集。

5.2.6 Redis 的事務是什麼?

可以一次性執行多個命令,本質上就是一組命令的集合

5.2.7 為什麼要使用 Redis 作為快取?

redis相對於其它的鍵值資料儲存,能夠儲存豐富的資料型別、執行速度快、操作是原子性的,可以把資料複製到任意數量的從機

5.2.8 Redis 和 Memcached 的區別?

redis支援持久化,mencached不支援
redis支援豐富的資料型別,mencached只支援一種string

5.2.9 Redis 如何設定過期時間和刪除過期資料?

設定過期時間的方法有四種:
1. EXPIRE <KEY> <time>:設定鍵的生存時間為time秒
2. PEXPIRE <KEY> <time>:設定鍵的生存時間為time毫秒
3. EXPIREAT <KEY> <time>:將鍵的過期時間設定為time所指定的秒數時間戳
4. PEXPIREAT <KEY> <time>:將鍵的過期時間設定為time所指定的毫秒數時間戳
刪除資料一共有三種策略:
1. 立即刪除:設定過期時間時,指定一個回撥函式,當到達過期時間,由時間處理器自動執行鍵的刪除操作
2. 惰性刪除:過期了就過期了,不管。每次從dict中按照key取值時,先檢查key是否過期,如果過期,刪除key,並返回nil,沒有過期返回鍵值
3. 定時刪除:每隔一段時間,檢查expires字典,刪除過期的鍵。

5.2.10 Redis 有哪幾種資料淘汰策略?

volatile-lru:從設定了過期時間的資料集中,選擇最近最久沒使用的資料釋放
volatile-random:從設定了過期時間的資料集中,隨機選擇一個資料進行釋放
volatile-ttl:從設定了過期時間的資料集中,選擇馬上就要過期的資料進行釋放
allkeys-lru:從資料集中(過期時間有沒有設定都算),選擇最近最久沒使用的資料釋放
allkeys-random:從資料集中(過期時間有沒有設定都算),隨機選擇一個資料進行釋放
Noeviction:不刪除任何資料,如果記憶體不足,直接返回錯誤

5.2.11 Redis 為什麼是單執行緒的?

redis是用一個cpu對一塊記憶體區域進行資料的讀寫操作,如果用多執行緒,會存在上下文切換,上下文切換會浪費時間和資源。所以對於redis這樣的記憶體系統來說,沒有上下文的切換效率是最高的。
一次cpu上下文切換的時間大概是1500ns,從記憶體中讀取1MB連續資料的時間大概是250us,假如1mb的資料都是由多執行緒讀取了1000次,那麼就有1000次上下文切換的時間1500ns*1000=1500us。我單執行緒讀取的時間只有250us,多執行緒光上下文切換的時間就有1500us了
同時,使用單執行緒也避免了資料安全性的問題,多執行緒操作為了處理資料安全問題,需要加鎖,一旦加鎖就會影響程式的執行效率

5.2.12 單執行緒的 Redis 為什麼這麼快?

單執行緒,沒有上下文切換的開銷、沒有加鎖解鎖的開銷
純記憶體作業系統,資料全部儲存在記憶體中
高效的資料結構
合理的資料編碼

5.2.13 快取雪崩和快取穿透是什麼?如何預防解決?

快取穿透:指查詢一個一定不存在的資料,快取中不命中時會去查詢資料庫,如果查詢不到則不寫入快取,以後這個不存在資料的請求都會去查詢資料庫,造成資料穿透
預防辦法:
1. 布隆過濾
2. 快取空物件,null變為一個值,設定過期時間5min-10min

快取雪崩:指快取系統重啟或快取集中失效,導致造成大量的快取穿透,所有的查詢都落到資料庫,造成快取雪崩
預防辦法:
1. 快取集中失效後,通過加鎖或佇列控制資料庫寫快取的執行緒數量,如對一個key的操作只允許一個執行緒,其它執行緒等待
2. 做二級快取,A1為原始快取,A2為拷貝快取,A1失效,可以查詢A2,A1過期時間設定短期,A2過期時間設定長期
3. 不同key,設定不同的過期時間,保證快取不會同一時間失效

5.2.14 布隆過濾器是什麼?
5.2.15 簡單描述一下什麼是快取預熱、快取更新和快取降級?

快取預熱:指系統上線後,將資料載入到快取中,手動或定時重新整理
快取更新:指自動或觸發清理過期或不需要的資料
快取降級:指為保證核心業務可以使用,將部分關鍵資料降級處理,同時也可以避免快取雪崩

5.2.16 如何解決 Redis 的併發競爭 Key 的問題?

1. 分散式鎖+時間戳
	i. 對key操作不要求順序
	準備一個分散式鎖,大家去搶鎖,搶到的先做set操作
	ii. 對key操作要求順序
	預期按照順序給key賦值,比如先作業系統a,再b,再c,此時如果b先控制鎖賦值了,之後a搶到鎖,會先檢視自己的時間戳是否早於快取中的,如果是,則不做set操作
2. 訊息佇列

5.2.17 寫一個 Python 連線操作 Redis 資料庫例項?

import redis
r=redis.Redis(host='localhost',port='6379')
r.set('foo','haha')
print(r.get('foo'))

5.2.18 什麼是分散式鎖?

在分散式系統中,防止多個程式之間相互干擾,避免同一時間對共享資料進行修改操作。

5.2.19 Python 如何實現一個 Redis 分散式鎖?
5.2.20 如何保證快取與資料庫雙寫時的資料一致性?

先修改快取為指定值,再去更新資料庫,再去更新快取。如果讀請求過來了,先讀快取,如果快取是指定值,進入迴圈,等待寫請求完成,更新快取。如果迴圈超時,則去讀資料庫,更新快取。

5.2.21 叢集是什麼?Redis 有哪些叢集方案?
5.2.22 Redis 常⻅效能問題和解決方案?
5.2.23 瞭解 Redis 的同步機制麼?
5.2.24 如果有大量的 key 需要設定同一時間過期,一般需要注意什麼?

5.2.25 如何使用 Redis 實現非同步佇列?
5.2.26 列舉一些常用的資料庫視覺化工具?

相關文章