nodejs redis 过期时间_别在为Redis面试而烦恼了?看完暴答【面试管】
Redis面試官喜歡問的,小伙伴們看完暴答面試官!!!
?Redis 是什么?都有哪些使用場景?Redis 是一個使用 C 語言開發的高性能鍵值對(key-value)的內存數據庫,性能優秀,數據在內存中,讀寫速度非常快,支持并發 10W QPS。單進程單線程,是線程安全的,采用 IO 多路復用機制。豐富的數據類型,支持字符串(strings)、散列(hashes)、列表(lists)、集合(sets)、有序集合(sorted sets)等。支持數據持久化。可以將內存中數據保存在磁盤中,重啟時加載。主從復制,哨兵,高可用。可以用作分布式鎖。可以作為消息中間件使用,支持發布訂閱。??? Redis 使用場景:
記錄帖子點贊數、點擊數、評論數;
緩存近期熱帖;
緩存文章詳情信息;
記錄用戶會話信息。
Redis 有哪些功能?
數據緩存功能
分布式鎖的功能
支持數據持久化
支持事務
支持消息隊列
存儲方式不同:memcache 把數據全部存在內存之中,斷電后會掛掉,數據不能超過內存大小;Redis 有部份存在硬盤上,這樣能保證數據的持久性。
數據支持類型:memcache 對數據類型支持相對簡單;Redis 有復雜的數據類型。
使用底層模型不同:它們之間底層實現方式,以及與客戶端之間通信的應用協議不一樣,Redis 自己構建了 vm 機制,因為一般的系統調用系統函數的話,會浪費一定的時間去移動和請求。
value 值大小不同:Redis 最大可以達到 512mb;memcache 只有 1mb。
Redis 為什么是單線程的?
因為 cpu 不是 Redis 的瓶頸,Redis 的瓶頸最有可能是機器內存或者網絡帶寬。既然單線程容易實現,而且 cpu 又不會成為瓶頸,那就順理成章地采用單線程的方案了。關于 Redis 的性能,官方網站也有,普通筆記本輕松處理每秒幾十萬的請求。而且單線程并不代表就慢 nginx 和 nodejs 也都是高性能單線程的代表。Redis 支持的數據類型有哪些以及應用場景總結?
Redis 支持的數據類型:string(字符串)、list(列表)、hash(字典)、set(集合)、zset(有序集合)。
數據類型應用場景:什么是緩存穿透,緩存擊穿,緩存雪崩,緩存失效,緩存并發及解決方案?一. 緩存擊穿
緩存擊穿是指緩存中沒有,但數據庫中有的數據(一般是緩存時間到期),這時由于并發用戶特別多,同時讀緩存沒有讀到的數據,又同時區數據庫讀取,引起數據庫壓力瞬間增大,造成的過的壓力。解決方案:
設置熱點數據永遠不過期。
加互斥鎖,互斥鎖參考代碼如下
二. 緩存穿透
緩存穿透是指緩存和數據庫中都沒有的數據,而用戶不斷發起請求,如發起為id為“-1”的數據或id為特別大不存在的數據。這時的用戶很可能是攻擊者,攻擊會導致數據庫壓力過大。解決方案:
接口層增加校驗,如用戶鑒權校驗,id做基礎校驗,id<=0的直接攔截;從緩存取
的數據,在數據庫中也沒有取到,這時也可以將key-value對寫為key-null,緩存有效時間可以設置短點,如30秒(設置太長會導致正常情況也沒法使用)。這樣可以防止攻擊用戶反復用同一個id暴力攻擊
三. 緩存雪崩
緩存雪崩是指緩存中數據大批量到過期時間,而查詢數據量巨大,引起數據庫壓力過大甚至down機。和緩存擊穿不同的是,緩存擊穿指并發查同一條數據,緩存雪崩是不同數據都過期了,很多數據都查不到從而查數據庫。解決方案:
緩存數據的過期時間設置隨機,防止同一時間大量數據過期現象發生。
如果緩存數據庫是分布式部署,將熱點數據均勻分布在不同搞得緩存數據庫中。
設置熱點數據永遠不過期。
四. 緩存失效
引起這個原因的主要因素是高并發下,我們一般設定一個緩存的過期時間時,可能有一些會設置5分鐘啊,10分鐘這些;并發很高時可能會出在某一個時間同時生成了很多的緩存,并且過期時間在同一時刻,這個時候就可能引發,當過期時間到后,這些緩存同時失效,請求全部轉發到DB,DB可能會壓力過重解決方案:
一個簡單方案就是將緩存失效時間分散開,不要所以緩存時間長度都設置成5分鐘或者10分鐘;比如我們可以在原有的失效時間基礎上增加一個隨機值,比如1-5分鐘隨機,這樣每一個緩存的過期時間的重復率就會降低,就很難引發集體失效的事件。
緩存失效時產生的雪崩效應,將所有請求全部放在數據庫上,這樣很容易就達到數據庫的瓶頸,導致服務無法正常提供。盡量避免這種場景的發生。
五. 緩存并發
當網站并發訪問高,一個緩存如果失效,可能出現多個進程同時查詢DB,同時設置緩存的情況,如果并發確實很大,這也可能造成DB壓力過大,還有緩存頻繁更新的問題。解決方案:
對緩存查詢加鎖,如果KEY不存在,就加鎖,然后查DB入緩存,然后解鎖;其他進程如果發現有鎖就等待,然后等解鎖后返回數據或者進入DB查詢。
Redis 支持的 Java 客戶端都有哪些?
支持的 Java 客戶端有 Redisson、jedis、lettuce 等。jedis 和 Redisson 有哪些區別?
jedis:提供了比較全面的 Redis 命令的支持。
Rdisson:實現了分布式和可擴展的 Java 數據結構,與 jedis 相比 Redisson 的功能相對簡單,不支持排序、事務、管道、分區等 Redis 特性。
怎么保證緩存和數據庫數據的一致性?
合理設置緩存的過期時間。
新增、更改、刪除數據庫操作時同步更新 Redis,可以使用事物機制來保證數據的一致性。
Redis 持久化有幾種方式?
? ? ?Redis 的持久化有兩種方式,或者說有兩種策略:
RDB(Redis Database):在指定的時間隔內生成數據集快照寫入到磁盤中(就是將redis內存中數據庫記錄定時寫入到磁盤中)
AOF(Append Only File):以日志的形式記錄每一個操作,并進行追加。
Redis RDB和AOF兩種持久化區別及優缺點?
RDB
在指定的時間隔內生成數據集快照寫入到磁盤中優點:一旦采用該方式,那么你的redis數據庫只包含一個文件,這對于文件備份而已非常完美,比如:你可能打算每個小時歸檔一次最近24小時數據,同時還要每天歸檔一次最近30天數據。通過這樣的備份,策略,一旦系統出現災難性故障,我們可以非常容易的進行恢復.
缺點:更新過程中出現宕機情況下,數據持久性會丟失
AOF
以日志的形式記錄每一個操作,并進行追加。優點:該方式可以對數據持久安全性更高,因為它提供了3種同步策略,每種策略效率都不是一樣的。
缺點:運行效率慢與RDB,雖然AOF有不同的策略,也沒有RDB效率快,并且RDB在恢復大數據集時速度也比AOF快
Redis 怎么實現分布式鎖?
Redis 分布式鎖其實就是在系統里面占一個“坑”,其他程序也要占“坑”的時候,占用成功了就可以繼續執行,失敗了就只能放棄或稍后重試。占坑一般使用 setnx(set if not exists)指令,只允許被一個程序占有,使用完調用 del 釋放鎖。Redis 分布式鎖有什么缺陷?
Redis 分布式鎖不能解決超時的問題,分布式鎖有一個超時時間,程序的執行如果超出了鎖的超時時間就會出現問題。Redis 淘汰策略有哪些?
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(驅逐):禁止驅逐數據。
Redis 常見的性能問題有哪些?該如何解決?
主服務器寫內存快照,會阻塞主線程的工作,當快照比較大時對性能影響是非常大的,會間斷性暫停服務,所以主服務器最好不要寫內存快照。Redis 主從復制的性能問題,為了主從復制的速度和連接的穩定性,主從庫最好在同一個局域網內。Redis 事務了解過嗎?
Redis 通過 MULTI、EXEC、WATCH 等命令來實現事務(transaction)功能。事務提供了一種將多個命令請求打包,然后一次性、按順序地執行多個命令的機制,并且在事務執行期間,服務器不會中斷事務而改去執行其他客戶端的命令請求,它會將事務中的所有命令都執行完畢,然后才去處理其他客戶端的命令請求。在傳統的關系式數據庫中,常常用 ACID 性質來檢驗事務功能的可靠性和安全性。在 Redis 中,事務總是具有原子性(Atomicity)、一致性(Consistency)和隔離性(Isolation),并且當 Redis 運行在某種特定的持久化模式下時,事務也具有持久性(Durability)。如何解決 Redis 的并發競爭 Key 問題
所謂 Redis 的并發競爭 Key 的問題也就是多個系統同時對一個 key 進行操作,但是最后執行的順序和我們期望的順序不同,這樣也就導致了結果的不同!推薦一種方案:分布式鎖(zookeeper 和 redis 都可以實現分布式鎖)。(如果不存在 Redis 的并發競爭 Key 問題,不要使用分布式鎖,這樣會影響性能)基于zookeeper臨時有序節點可以實現的分布式鎖。大致思想為:每個客戶端對某個方法加鎖時,在zookeeper上的與該方法對應的指定節點的目錄下,生成一個唯一的瞬時有序節點。判斷是否獲取鎖的方式很簡單,只需要判斷有序節點中序號最小的一個。當釋放鎖的時候,只需將這個瞬時節點刪除即可。同時,其可以避免服務宕機導致的鎖無法釋放,而產生的死鎖問題。完成業務流程后,刪除對應的子節點釋放鎖。如何保證緩存與數據庫雙寫時的數據一致性?
你只要用緩存,就可能會涉及到緩存與數據庫雙存儲雙寫,你只要是雙寫,就一定會有數據一致性的問題,那么你如何解決一致性問題?一般來說,就是如果你的系統不是嚴格要求緩存+數據庫必須一致性的話,緩存可以稍微的跟數據庫偶爾有不一致的情況,最好不要做這個方案,讀請求和寫請求串行化,串到一個內存隊列里去,這樣就可以保證一定不會出現不一致的情況串行化之后,就會導致系統的吞吐量會大幅度的降低,用比正常情況下多幾倍的機器去支撐線上的一個請求。還有一種方式就是可能會暫時產生不一致的情況,但是發生的幾率特別小,就是先更新數據庫,然后再刪除緩存。這種情況不存在并發問題么?
不是的。假設這會有兩個請求,一個請求A做查詢操作,一個請求B做更新操作,那么會有如下情形產生
(1)緩存剛好失效
(2)請求A查詢數據庫,得一個舊值
(3)請求B將新值寫入數據庫
(4)請求B刪除緩存
(5)請求A將查到的舊值寫入緩存
ok,如果發生上述情況,確實是會發生臟數據。
然而,發生這種情況的概率又有多少呢?
發生上述情況有一個先天性條件,就是步驟(3)的寫數據庫操作比步驟(2)的讀數據庫操作耗時更短,才有可能使得步驟(4)先于步驟(5)。可是,大家想想,數據庫的讀操作的速度遠快于寫操作的(不然做讀寫分離干嘛,做讀寫分離的意義就是因為讀操作比較快,耗資源少),因此步驟(3)耗時比步驟(2)更短,這一情形很難出現。總結
以上是生活随笔為你收集整理的nodejs redis 过期时间_别在为Redis面试而烦恼了?看完暴答【面试管】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 阿里云对象存储OSS与文件存储NAS的区
- 下一篇: mysql查看binlog日志内容